1cd4edf94SFlorian Hahn //===--- ConstraintSystemTests.cpp ----------------------------------------===//
2cd4edf94SFlorian Hahn //
3cd4edf94SFlorian Hahn // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cd4edf94SFlorian Hahn // See https://llvm.org/LICENSE.txt for license information.
5cd4edf94SFlorian Hahn // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cd4edf94SFlorian Hahn //
7cd4edf94SFlorian Hahn //===----------------------------------------------------------------------===//
8cd4edf94SFlorian Hahn
9cd4edf94SFlorian Hahn #include "llvm/Analysis/ConstraintSystem.h"
10cd4edf94SFlorian Hahn #include "gtest/gtest.h"
11cd4edf94SFlorian Hahn
12cd4edf94SFlorian Hahn using namespace llvm;
13cd4edf94SFlorian Hahn
14cd4edf94SFlorian Hahn namespace {
15cd4edf94SFlorian Hahn
TEST(ConstraintSolverTest,TestSolutionChecks)16*db22e70dSFlorian Hahn TEST(ConstraintSolverTest, TestSolutionChecks) {
17cd4edf94SFlorian Hahn {
18cd4edf94SFlorian Hahn ConstraintSystem CS;
19cd4edf94SFlorian Hahn // x + y <= 10, x >= 5, y >= 6, x <= 10, y <= 10
20cd4edf94SFlorian Hahn CS.addVariableRow({10, 1, 1});
21cd4edf94SFlorian Hahn CS.addVariableRow({-5, -1, 0});
22cd4edf94SFlorian Hahn CS.addVariableRow({-6, 0, -1});
23cd4edf94SFlorian Hahn CS.addVariableRow({10, 1, 0});
24cd4edf94SFlorian Hahn CS.addVariableRow({10, 0, 1});
25cd4edf94SFlorian Hahn
26cd4edf94SFlorian Hahn EXPECT_FALSE(CS.mayHaveSolution());
27cd4edf94SFlorian Hahn }
28cd4edf94SFlorian Hahn
29cd4edf94SFlorian Hahn {
30cd4edf94SFlorian Hahn ConstraintSystem CS;
31cd4edf94SFlorian Hahn // x + y <= 10, x >= 2, y >= 3, x <= 10, y <= 10
32cd4edf94SFlorian Hahn CS.addVariableRow({10, 1, 1});
33cd4edf94SFlorian Hahn CS.addVariableRow({-2, -1, 0});
34cd4edf94SFlorian Hahn CS.addVariableRow({-3, 0, -1});
35cd4edf94SFlorian Hahn CS.addVariableRow({10, 1, 0});
36cd4edf94SFlorian Hahn CS.addVariableRow({10, 0, 1});
37cd4edf94SFlorian Hahn
38cd4edf94SFlorian Hahn EXPECT_TRUE(CS.mayHaveSolution());
39cd4edf94SFlorian Hahn }
40cd4edf94SFlorian Hahn
41cd4edf94SFlorian Hahn {
42cd4edf94SFlorian Hahn ConstraintSystem CS;
43cd4edf94SFlorian Hahn // x + y <= 10, 10 >= x, 10 >= y; does not have a solution.
44cd4edf94SFlorian Hahn CS.addVariableRow({10, 1, 1});
45cd4edf94SFlorian Hahn CS.addVariableRow({-10, -1, 0});
46cd4edf94SFlorian Hahn CS.addVariableRow({-10, 0, -1});
47cd4edf94SFlorian Hahn
48cd4edf94SFlorian Hahn EXPECT_FALSE(CS.mayHaveSolution());
49cd4edf94SFlorian Hahn }
50cd4edf94SFlorian Hahn
51cd4edf94SFlorian Hahn {
52cd4edf94SFlorian Hahn ConstraintSystem CS;
53cd4edf94SFlorian Hahn // x + y >= 20, 10 >= x, 10 >= y; does HAVE a solution.
54cd4edf94SFlorian Hahn CS.addVariableRow({-20, -1, -1});
55cd4edf94SFlorian Hahn CS.addVariableRow({-10, -1, 0});
56cd4edf94SFlorian Hahn CS.addVariableRow({-10, 0, -1});
57cd4edf94SFlorian Hahn
58cd4edf94SFlorian Hahn EXPECT_TRUE(CS.mayHaveSolution());
59cd4edf94SFlorian Hahn }
60cd4edf94SFlorian Hahn
61cd4edf94SFlorian Hahn {
62cd4edf94SFlorian Hahn ConstraintSystem CS;
63cd4edf94SFlorian Hahn
64cd4edf94SFlorian Hahn // 2x + y + 3z <= 10, 2x + y >= 10, y >= 1
65cd4edf94SFlorian Hahn CS.addVariableRow({10, 2, 1, 3});
66cd4edf94SFlorian Hahn CS.addVariableRow({-10, -2, -1, 0});
67cd4edf94SFlorian Hahn CS.addVariableRow({-1, 0, 0, -1});
68cd4edf94SFlorian Hahn
69cd4edf94SFlorian Hahn EXPECT_FALSE(CS.mayHaveSolution());
70cd4edf94SFlorian Hahn }
71cd4edf94SFlorian Hahn
72cd4edf94SFlorian Hahn {
73cd4edf94SFlorian Hahn ConstraintSystem CS;
74cd4edf94SFlorian Hahn
75cd4edf94SFlorian Hahn // 2x + y + 3z <= 10, 2x + y >= 10
76cd4edf94SFlorian Hahn CS.addVariableRow({10, 2, 1, 3});
77cd4edf94SFlorian Hahn CS.addVariableRow({-10, -2, -1, 0});
78cd4edf94SFlorian Hahn
79cd4edf94SFlorian Hahn EXPECT_TRUE(CS.mayHaveSolution());
80cd4edf94SFlorian Hahn }
81cd4edf94SFlorian Hahn }
82*db22e70dSFlorian Hahn
TEST(ConstraintSolverTest,IsConditionImplied)83*db22e70dSFlorian Hahn TEST(ConstraintSolverTest, IsConditionImplied) {
84*db22e70dSFlorian Hahn {
85*db22e70dSFlorian Hahn // For the test below, we assume we know
86*db22e70dSFlorian Hahn // x <= 5 && y <= 3
87*db22e70dSFlorian Hahn ConstraintSystem CS;
88*db22e70dSFlorian Hahn CS.addVariableRow({5, 1, 0});
89*db22e70dSFlorian Hahn CS.addVariableRow({3, 0, 1});
90*db22e70dSFlorian Hahn
91*db22e70dSFlorian Hahn // x + y <= 6 does not hold.
92*db22e70dSFlorian Hahn EXPECT_FALSE(CS.isConditionImplied({6, 1, 1}));
93*db22e70dSFlorian Hahn // x + y <= 7 does not hold.
94*db22e70dSFlorian Hahn EXPECT_FALSE(CS.isConditionImplied({7, 1, 1}));
95*db22e70dSFlorian Hahn // x + y <= 8 does hold.
96*db22e70dSFlorian Hahn EXPECT_TRUE(CS.isConditionImplied({8, 1, 1}));
97*db22e70dSFlorian Hahn
98*db22e70dSFlorian Hahn // 2 * x + y <= 12 does hold.
99*db22e70dSFlorian Hahn EXPECT_FALSE(CS.isConditionImplied({12, 2, 1}));
100*db22e70dSFlorian Hahn // 2 * x + y <= 13 does hold.
101*db22e70dSFlorian Hahn EXPECT_TRUE(CS.isConditionImplied({13, 2, 1}));
102*db22e70dSFlorian Hahn
103*db22e70dSFlorian Hahn // x + y <= 12 does hold.
104*db22e70dSFlorian Hahn EXPECT_FALSE(CS.isConditionImplied({12, 2, 1}));
105*db22e70dSFlorian Hahn // 2 * x + y <= 13 does hold.
106*db22e70dSFlorian Hahn EXPECT_TRUE(CS.isConditionImplied({13, 2, 1}));
107*db22e70dSFlorian Hahn
108*db22e70dSFlorian Hahn // x <= y == x - y <= 0 does not hold.
109*db22e70dSFlorian Hahn EXPECT_FALSE(CS.isConditionImplied({0, 1, -1}));
110*db22e70dSFlorian Hahn // y <= x == -x + y <= 0 does not hold.
111*db22e70dSFlorian Hahn EXPECT_FALSE(CS.isConditionImplied({0, -1, 1}));
112*db22e70dSFlorian Hahn }
113*db22e70dSFlorian Hahn
114*db22e70dSFlorian Hahn {
115*db22e70dSFlorian Hahn // For the test below, we assume we know
116*db22e70dSFlorian Hahn // x + 1 <= y + 1 == x - y <= 0
117*db22e70dSFlorian Hahn ConstraintSystem CS;
118*db22e70dSFlorian Hahn CS.addVariableRow({0, 1, -1});
119*db22e70dSFlorian Hahn
120*db22e70dSFlorian Hahn // x <= y == x - y <= 0 does hold.
121*db22e70dSFlorian Hahn EXPECT_TRUE(CS.isConditionImplied({0, 1, -1}));
122*db22e70dSFlorian Hahn // y <= x == -x + y <= 0 does not hold.
123*db22e70dSFlorian Hahn EXPECT_FALSE(CS.isConditionImplied({0, -1, 1}));
124*db22e70dSFlorian Hahn
125*db22e70dSFlorian Hahn // x <= y + 10 == x - y <= 10 does hold.
126*db22e70dSFlorian Hahn EXPECT_TRUE(CS.isConditionImplied({10, 1, -1}));
127*db22e70dSFlorian Hahn // x + 10 <= y == x - y <= -10 does NOT hold.
128*db22e70dSFlorian Hahn EXPECT_FALSE(CS.isConditionImplied({-10, 1, -1}));
129*db22e70dSFlorian Hahn }
130*db22e70dSFlorian Hahn
131*db22e70dSFlorian Hahn {
132*db22e70dSFlorian Hahn // For the test below, we assume we know
133*db22e70dSFlorian Hahn // x <= y == x - y <= 0
134*db22e70dSFlorian Hahn // y <= z == y - x <= 0
135*db22e70dSFlorian Hahn ConstraintSystem CS;
136*db22e70dSFlorian Hahn CS.addVariableRow({0, 1, -1, 0});
137*db22e70dSFlorian Hahn CS.addVariableRow({0, 0, 1, -1});
138*db22e70dSFlorian Hahn
139*db22e70dSFlorian Hahn // z <= y == -y + z <= 0 does not hold.
140*db22e70dSFlorian Hahn EXPECT_FALSE(CS.isConditionImplied({0, 0, -1, 1}));
141*db22e70dSFlorian Hahn // x <= z == x - z <= 0 does hold.
142*db22e70dSFlorian Hahn EXPECT_TRUE(CS.isConditionImplied({0, 1, 0, -1}));
143*db22e70dSFlorian Hahn }
144*db22e70dSFlorian Hahn }
145*db22e70dSFlorian Hahn
TEST(ConstraintSolverTest,IsConditionImpliedOverflow)146*db22e70dSFlorian Hahn TEST(ConstraintSolverTest, IsConditionImpliedOverflow) {
147*db22e70dSFlorian Hahn ConstraintSystem CS;
148*db22e70dSFlorian Hahn // Make sure isConditionImplied returns false when there is an overflow.
149*db22e70dSFlorian Hahn int64_t Limit = std::numeric_limits<int64_t>::max();
150*db22e70dSFlorian Hahn CS.addVariableRow({Limit - 1, Limit - 2, Limit - 3});
151*db22e70dSFlorian Hahn EXPECT_FALSE(CS.isConditionImplied({Limit - 1, Limit - 2, Limit - 3}));
152*db22e70dSFlorian Hahn }
153cd4edf94SFlorian Hahn } // namespace
154