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