blob: db298bc0d4e15624a72d4c3845d419f70eb06929 [file] [log] [blame]
Chandler Carruth8cd041e2014-03-04 12:24:34 +00001//===- ConstantRangeTest.cpp - ConstantRange tests ------------------------===//
Dan Gohman5035fbf2009-07-09 22:07:27 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Dan Gohman5035fbf2009-07-09 22:07:27 +00006//
7//===----------------------------------------------------------------------===//
8
Chandler Carruth8cd041e2014-03-04 12:24:34 +00009#include "llvm/IR/ConstantRange.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000010#include "llvm/IR/Instructions.h"
Sanjoy Das6ed05302015-10-22 03:12:57 +000011#include "llvm/IR/Operator.h"
Nikita Popovef2d9792019-03-17 20:24:02 +000012#include "llvm/Support/KnownBits.h"
Dan Gohman5035fbf2009-07-09 22:07:27 +000013#include "gtest/gtest.h"
14
15using namespace llvm;
16
17namespace {
18
Nick Lewycky17a4fa82009-07-11 18:43:20 +000019class ConstantRangeTest : public ::testing::Test {
20protected:
21 static ConstantRange Full;
22 static ConstantRange Empty;
23 static ConstantRange One;
24 static ConstantRange Some;
25 static ConstantRange Wrap;
26};
Dan Gohman5035fbf2009-07-09 22:07:27 +000027
Nikita Popovee9f2ae2019-03-27 20:18:51 +000028template<typename Fn>
29static void EnumerateTwoConstantRanges(unsigned Bits, Fn TestFn) {
30 unsigned Max = 1 << Bits;
31 for (unsigned Lo1 = 0; Lo1 < Max; Lo1++) {
32 for (unsigned Hi1 = 0; Hi1 < Max; Hi1++) {
33 // Enforce ConstantRange invariant.
34 if (Lo1 == Hi1 && Lo1 != 0 && Lo1 != Max - 1)
35 continue;
36
37 ConstantRange CR1(APInt(Bits, Lo1), APInt(Bits, Hi1));
38 for (unsigned Lo2 = 0; Lo2 < Max; Lo2++) {
39 for (unsigned Hi2 = 0; Hi2 < Max; Hi2++) {
40 // Enforce ConstantRange invariant.
41 if (Lo2 == Hi2 && Lo2 != 0 && Lo2 != Max - 1)
42 continue;
43
44 ConstantRange CR2(APInt(Bits, Lo2), APInt(Bits, Hi2));
45 TestFn(CR1, CR2);
46 }
47 }
48 }
49 }
50}
51
Nikita Popov977934f2019-03-24 09:34:40 +000052ConstantRange ConstantRangeTest::Full(16, true);
Nick Lewycky17a4fa82009-07-11 18:43:20 +000053ConstantRange ConstantRangeTest::Empty(16, false);
54ConstantRange ConstantRangeTest::One(APInt(16, 0xa));
55ConstantRange ConstantRangeTest::Some(APInt(16, 0xa), APInt(16, 0xaaa));
56ConstantRange ConstantRangeTest::Wrap(APInt(16, 0xaaa), APInt(16, 0xa));
57
58TEST_F(ConstantRangeTest, Basics) {
Dan Gohman5035fbf2009-07-09 22:07:27 +000059 EXPECT_TRUE(Full.isFullSet());
60 EXPECT_FALSE(Full.isEmptySet());
Owen Anderson1a9078b2010-08-07 05:47:46 +000061 EXPECT_TRUE(Full.inverse().isEmptySet());
Nikita Popov7b4e9a12019-03-27 19:12:09 +000062 EXPECT_FALSE(Full.isWrappedSet());
Dan Gohman5035fbf2009-07-09 22:07:27 +000063 EXPECT_TRUE(Full.contains(APInt(16, 0x0)));
64 EXPECT_TRUE(Full.contains(APInt(16, 0x9)));
65 EXPECT_TRUE(Full.contains(APInt(16, 0xa)));
66 EXPECT_TRUE(Full.contains(APInt(16, 0xaa9)));
67 EXPECT_TRUE(Full.contains(APInt(16, 0xaaa)));
68
69 EXPECT_FALSE(Empty.isFullSet());
70 EXPECT_TRUE(Empty.isEmptySet());
Owen Anderson1a9078b2010-08-07 05:47:46 +000071 EXPECT_TRUE(Empty.inverse().isFullSet());
Nikita Popov7b4e9a12019-03-27 19:12:09 +000072 EXPECT_FALSE(Empty.isWrappedSet());
Dan Gohman5035fbf2009-07-09 22:07:27 +000073 EXPECT_FALSE(Empty.contains(APInt(16, 0x0)));
74 EXPECT_FALSE(Empty.contains(APInt(16, 0x9)));
75 EXPECT_FALSE(Empty.contains(APInt(16, 0xa)));
76 EXPECT_FALSE(Empty.contains(APInt(16, 0xaa9)));
77 EXPECT_FALSE(Empty.contains(APInt(16, 0xaaa)));
78
79 EXPECT_FALSE(One.isFullSet());
80 EXPECT_FALSE(One.isEmptySet());
Nikita Popov7b4e9a12019-03-27 19:12:09 +000081 EXPECT_FALSE(One.isWrappedSet());
Dan Gohman5035fbf2009-07-09 22:07:27 +000082 EXPECT_FALSE(One.contains(APInt(16, 0x0)));
83 EXPECT_FALSE(One.contains(APInt(16, 0x9)));
84 EXPECT_TRUE(One.contains(APInt(16, 0xa)));
85 EXPECT_FALSE(One.contains(APInt(16, 0xaa9)));
86 EXPECT_FALSE(One.contains(APInt(16, 0xaaa)));
Owen Anderson1a9078b2010-08-07 05:47:46 +000087 EXPECT_FALSE(One.inverse().contains(APInt(16, 0xa)));
Dan Gohman5035fbf2009-07-09 22:07:27 +000088
89 EXPECT_FALSE(Some.isFullSet());
90 EXPECT_FALSE(Some.isEmptySet());
Nikita Popov7b4e9a12019-03-27 19:12:09 +000091 EXPECT_FALSE(Some.isWrappedSet());
Dan Gohman5035fbf2009-07-09 22:07:27 +000092 EXPECT_FALSE(Some.contains(APInt(16, 0x0)));
93 EXPECT_FALSE(Some.contains(APInt(16, 0x9)));
94 EXPECT_TRUE(Some.contains(APInt(16, 0xa)));
95 EXPECT_TRUE(Some.contains(APInt(16, 0xaa9)));
96 EXPECT_FALSE(Some.contains(APInt(16, 0xaaa)));
97
98 EXPECT_FALSE(Wrap.isFullSet());
99 EXPECT_FALSE(Wrap.isEmptySet());
Nikita Popov7b4e9a12019-03-27 19:12:09 +0000100 EXPECT_TRUE(Wrap.isWrappedSet());
Dan Gohman5035fbf2009-07-09 22:07:27 +0000101 EXPECT_TRUE(Wrap.contains(APInt(16, 0x0)));
102 EXPECT_TRUE(Wrap.contains(APInt(16, 0x9)));
103 EXPECT_FALSE(Wrap.contains(APInt(16, 0xa)));
104 EXPECT_FALSE(Wrap.contains(APInt(16, 0xaa9)));
105 EXPECT_TRUE(Wrap.contains(APInt(16, 0xaaa)));
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000106}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000107
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000108TEST_F(ConstantRangeTest, Equality) {
Nick Lewyckyd5923992009-09-05 18:27:40 +0000109 EXPECT_EQ(Full, Full);
110 EXPECT_EQ(Empty, Empty);
111 EXPECT_EQ(One, One);
112 EXPECT_EQ(Some, Some);
113 EXPECT_EQ(Wrap, Wrap);
114 EXPECT_NE(Full, Empty);
115 EXPECT_NE(Full, One);
116 EXPECT_NE(Full, Some);
117 EXPECT_NE(Full, Wrap);
118 EXPECT_NE(Empty, One);
119 EXPECT_NE(Empty, Some);
120 EXPECT_NE(Empty, Wrap);
121 EXPECT_NE(One, Some);
122 EXPECT_NE(One, Wrap);
123 EXPECT_NE(Some, Wrap);
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000124}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000125
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000126TEST_F(ConstantRangeTest, SingleElement) {
Craig Topper66f09ad2014-06-08 22:29:17 +0000127 EXPECT_EQ(Full.getSingleElement(), static_cast<APInt *>(nullptr));
128 EXPECT_EQ(Empty.getSingleElement(), static_cast<APInt *>(nullptr));
Sanjoy Dasc7d32912016-10-02 20:59:05 +0000129 EXPECT_EQ(Full.getSingleMissingElement(), static_cast<APInt *>(nullptr));
130 EXPECT_EQ(Empty.getSingleMissingElement(), static_cast<APInt *>(nullptr));
131
Dan Gohman5035fbf2009-07-09 22:07:27 +0000132 EXPECT_EQ(*One.getSingleElement(), APInt(16, 0xa));
Craig Topper66f09ad2014-06-08 22:29:17 +0000133 EXPECT_EQ(Some.getSingleElement(), static_cast<APInt *>(nullptr));
134 EXPECT_EQ(Wrap.getSingleElement(), static_cast<APInt *>(nullptr));
Dan Gohman5035fbf2009-07-09 22:07:27 +0000135
Sanjoy Dasc7d32912016-10-02 20:59:05 +0000136 EXPECT_EQ(One.getSingleMissingElement(), static_cast<APInt *>(nullptr));
137 EXPECT_EQ(Some.getSingleMissingElement(), static_cast<APInt *>(nullptr));
138
139 ConstantRange OneInverse = One.inverse();
140 EXPECT_EQ(*OneInverse.getSingleMissingElement(), *One.getSingleElement());
141
Dan Gohman5035fbf2009-07-09 22:07:27 +0000142 EXPECT_FALSE(Full.isSingleElement());
143 EXPECT_FALSE(Empty.isSingleElement());
144 EXPECT_TRUE(One.isSingleElement());
145 EXPECT_FALSE(Some.isSingleElement());
146 EXPECT_FALSE(Wrap.isSingleElement());
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000147}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000148
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000149TEST_F(ConstantRangeTest, GetSetSize) {
Nuno Lopes99504c52012-07-16 18:08:12 +0000150 EXPECT_EQ(Full.getSetSize(), APInt(17, 65536));
151 EXPECT_EQ(Empty.getSetSize(), APInt(17, 0));
152 EXPECT_EQ(One.getSetSize(), APInt(17, 1));
153 EXPECT_EQ(Some.getSetSize(), APInt(17, 0xaa0));
154
155 ConstantRange Wrap(APInt(4, 7), APInt(4, 3));
156 ConstantRange Wrap2(APInt(4, 8), APInt(4, 7));
157 EXPECT_EQ(Wrap.getSetSize(), APInt(5, 12));
158 EXPECT_EQ(Wrap2.getSetSize(), APInt(5, 15));
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000159}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000160
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000161TEST_F(ConstantRangeTest, GetMinsAndMaxes) {
Dan Gohman5035fbf2009-07-09 22:07:27 +0000162 EXPECT_EQ(Full.getUnsignedMax(), APInt(16, UINT16_MAX));
163 EXPECT_EQ(One.getUnsignedMax(), APInt(16, 0xa));
164 EXPECT_EQ(Some.getUnsignedMax(), APInt(16, 0xaa9));
165 EXPECT_EQ(Wrap.getUnsignedMax(), APInt(16, UINT16_MAX));
166
167 EXPECT_EQ(Full.getUnsignedMin(), APInt(16, 0));
168 EXPECT_EQ(One.getUnsignedMin(), APInt(16, 0xa));
169 EXPECT_EQ(Some.getUnsignedMin(), APInt(16, 0xa));
170 EXPECT_EQ(Wrap.getUnsignedMin(), APInt(16, 0));
171
172 EXPECT_EQ(Full.getSignedMax(), APInt(16, INT16_MAX));
173 EXPECT_EQ(One.getSignedMax(), APInt(16, 0xa));
174 EXPECT_EQ(Some.getSignedMax(), APInt(16, 0xaa9));
175 EXPECT_EQ(Wrap.getSignedMax(), APInt(16, INT16_MAX));
176
Ryan Flynna845ef02009-07-22 16:17:36 +0000177 EXPECT_EQ(Full.getSignedMin(), APInt(16, (uint64_t)INT16_MIN));
Dan Gohman5035fbf2009-07-09 22:07:27 +0000178 EXPECT_EQ(One.getSignedMin(), APInt(16, 0xa));
179 EXPECT_EQ(Some.getSignedMin(), APInt(16, 0xa));
Ryan Flynna845ef02009-07-22 16:17:36 +0000180 EXPECT_EQ(Wrap.getSignedMin(), APInt(16, (uint64_t)INT16_MIN));
Nick Lewycky571bf542009-07-13 04:50:21 +0000181
182 // Found by Klee
183 EXPECT_EQ(ConstantRange(APInt(4, 7), APInt(4, 0)).getSignedMax(),
184 APInt(4, 7));
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000185}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000186
Nick Lewyckya35462d2010-09-06 23:52:49 +0000187TEST_F(ConstantRangeTest, SignWrapped) {
Nikita Popove6eef492019-03-26 22:37:26 +0000188 EXPECT_FALSE(Full.isSignWrappedSet());
Nick Lewyckya35462d2010-09-06 23:52:49 +0000189 EXPECT_FALSE(Empty.isSignWrappedSet());
190 EXPECT_FALSE(One.isSignWrappedSet());
191 EXPECT_FALSE(Some.isSignWrappedSet());
192 EXPECT_TRUE(Wrap.isSignWrappedSet());
193
194 EXPECT_FALSE(ConstantRange(APInt(8, 127), APInt(8, 128)).isSignWrappedSet());
195 EXPECT_TRUE(ConstantRange(APInt(8, 127), APInt(8, 129)).isSignWrappedSet());
196 EXPECT_FALSE(ConstantRange(APInt(8, 128), APInt(8, 129)).isSignWrappedSet());
197 EXPECT_TRUE(ConstantRange(APInt(8, 10), APInt(8, 9)).isSignWrappedSet());
198 EXPECT_TRUE(ConstantRange(APInt(8, 10), APInt(8, 250)).isSignWrappedSet());
199 EXPECT_FALSE(ConstantRange(APInt(8, 250), APInt(8, 10)).isSignWrappedSet());
200 EXPECT_FALSE(ConstantRange(APInt(8, 250), APInt(8, 251)).isSignWrappedSet());
201}
202
Nikita Popov7b4e9a12019-03-27 19:12:09 +0000203TEST_F(ConstantRangeTest, UpperWrapped) {
204 // The behavior here is the same as for isWrappedSet() / isSignWrappedSet().
205 EXPECT_FALSE(Full.isUpperWrapped());
206 EXPECT_FALSE(Empty.isUpperWrapped());
207 EXPECT_FALSE(One.isUpperWrapped());
208 EXPECT_FALSE(Some.isUpperWrapped());
209 EXPECT_TRUE(Wrap.isUpperWrapped());
210 EXPECT_FALSE(Full.isUpperSignWrapped());
211 EXPECT_FALSE(Empty.isUpperSignWrapped());
212 EXPECT_FALSE(One.isUpperSignWrapped());
213 EXPECT_FALSE(Some.isUpperSignWrapped());
214 EXPECT_TRUE(Wrap.isUpperSignWrapped());
215
216 // The behavior differs if Upper is the Min/SignedMin value.
217 ConstantRange CR1(APInt(8, 42), APInt::getMinValue(8));
218 EXPECT_FALSE(CR1.isWrappedSet());
219 EXPECT_TRUE(CR1.isUpperWrapped());
220
221 ConstantRange CR2(APInt(8, 42), APInt::getSignedMinValue(8));
222 EXPECT_FALSE(CR2.isSignWrappedSet());
223 EXPECT_TRUE(CR2.isUpperSignWrapped());
224}
225
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000226TEST_F(ConstantRangeTest, Trunc) {
Dan Gohman5035fbf2009-07-09 22:07:27 +0000227 ConstantRange TFull = Full.truncate(10);
228 ConstantRange TEmpty = Empty.truncate(10);
229 ConstantRange TOne = One.truncate(10);
230 ConstantRange TSome = Some.truncate(10);
231 ConstantRange TWrap = Wrap.truncate(10);
232 EXPECT_TRUE(TFull.isFullSet());
233 EXPECT_TRUE(TEmpty.isEmptySet());
Jay Foad583abbc2010-12-07 08:25:19 +0000234 EXPECT_EQ(TOne, ConstantRange(One.getLower().trunc(10),
235 One.getUpper().trunc(10)));
Dan Gohman5035fbf2009-07-09 22:07:27 +0000236 EXPECT_TRUE(TSome.isFullSet());
Craig Topper2df639e2017-06-04 23:03:52 +0000237 EXPECT_TRUE(TWrap.isFullSet());
Craig Topper0be7a1b2017-06-04 23:03:54 +0000238
239 // trunc([2, 5), 3->2) = [2, 1)
240 ConstantRange TwoFive(APInt(3, 2), APInt(3, 5));
241 EXPECT_EQ(TwoFive.truncate(2), ConstantRange(APInt(2, 2), APInt(2, 1)));
242
243 // trunc([2, 6), 3->2) = full
244 ConstantRange TwoSix(APInt(3, 2), APInt(3, 6));
245 EXPECT_TRUE(TwoSix.truncate(2).isFullSet());
246
247 // trunc([5, 7), 3->2) = [1, 3)
248 ConstantRange FiveSeven(APInt(3, 5), APInt(3, 7));
249 EXPECT_EQ(FiveSeven.truncate(2), ConstantRange(APInt(2, 1), APInt(2, 3)));
Craig Topper4b31ffd2017-06-04 23:07:53 +0000250
251 // trunc([7, 1), 3->2) = [3, 1)
252 ConstantRange SevenOne(APInt(3, 7), APInt(3, 1));
253 EXPECT_EQ(SevenOne.truncate(2), ConstantRange(APInt(2, 3), APInt(2, 1)));
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000254}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000255
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000256TEST_F(ConstantRangeTest, ZExt) {
Dan Gohman5035fbf2009-07-09 22:07:27 +0000257 ConstantRange ZFull = Full.zeroExtend(20);
258 ConstantRange ZEmpty = Empty.zeroExtend(20);
259 ConstantRange ZOne = One.zeroExtend(20);
260 ConstantRange ZSome = Some.zeroExtend(20);
261 ConstantRange ZWrap = Wrap.zeroExtend(20);
Nick Lewyckyd5923992009-09-05 18:27:40 +0000262 EXPECT_EQ(ZFull, ConstantRange(APInt(20, 0), APInt(20, 0x10000)));
Dan Gohman5035fbf2009-07-09 22:07:27 +0000263 EXPECT_TRUE(ZEmpty.isEmptySet());
Jay Foad583abbc2010-12-07 08:25:19 +0000264 EXPECT_EQ(ZOne, ConstantRange(One.getLower().zext(20),
265 One.getUpper().zext(20)));
266 EXPECT_EQ(ZSome, ConstantRange(Some.getLower().zext(20),
267 Some.getUpper().zext(20)));
Nick Lewyckya35462d2010-09-06 23:52:49 +0000268 EXPECT_EQ(ZWrap, ConstantRange(APInt(20, 0), APInt(20, 0x10000)));
Nuno Lopeseb9d2752012-07-23 20:33:29 +0000269
270 // zext([5, 0), 3->7) = [5, 8)
271 ConstantRange FiveZero(APInt(3, 5), APInt(3, 0));
272 EXPECT_EQ(FiveZero.zeroExtend(7), ConstantRange(APInt(7, 5), APInt(7, 8)));
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000273}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000274
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000275TEST_F(ConstantRangeTest, SExt) {
Dan Gohman5035fbf2009-07-09 22:07:27 +0000276 ConstantRange SFull = Full.signExtend(20);
277 ConstantRange SEmpty = Empty.signExtend(20);
278 ConstantRange SOne = One.signExtend(20);
279 ConstantRange SSome = Some.signExtend(20);
280 ConstantRange SWrap = Wrap.signExtend(20);
Nick Lewyckyd5923992009-09-05 18:27:40 +0000281 EXPECT_EQ(SFull, ConstantRange(APInt(20, (uint64_t)INT16_MIN, true),
282 APInt(20, INT16_MAX + 1, true)));
Dan Gohman5035fbf2009-07-09 22:07:27 +0000283 EXPECT_TRUE(SEmpty.isEmptySet());
Jay Foad583abbc2010-12-07 08:25:19 +0000284 EXPECT_EQ(SOne, ConstantRange(One.getLower().sext(20),
285 One.getUpper().sext(20)));
286 EXPECT_EQ(SSome, ConstantRange(Some.getLower().sext(20),
287 Some.getUpper().sext(20)));
Nick Lewyckya35462d2010-09-06 23:52:49 +0000288 EXPECT_EQ(SWrap, ConstantRange(APInt(20, (uint64_t)INT16_MIN, true),
289 APInt(20, INT16_MAX + 1, true)));
290
291 EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, 140)).signExtend(16),
292 ConstantRange(APInt(16, -128), APInt(16, 128)));
Nuno Lopes1112eca2013-10-30 15:36:50 +0000293
294 EXPECT_EQ(ConstantRange(APInt(16, 0x0200), APInt(16, 0x8000)).signExtend(19),
295 ConstantRange(APInt(19, 0x0200), APInt(19, 0x8000)));
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000296}
297
298TEST_F(ConstantRangeTest, IntersectWith) {
Nick Lewyckyd5923992009-09-05 18:27:40 +0000299 EXPECT_EQ(Empty.intersectWith(Full), Empty);
300 EXPECT_EQ(Empty.intersectWith(Empty), Empty);
301 EXPECT_EQ(Empty.intersectWith(One), Empty);
302 EXPECT_EQ(Empty.intersectWith(Some), Empty);
303 EXPECT_EQ(Empty.intersectWith(Wrap), Empty);
304 EXPECT_EQ(Full.intersectWith(Full), Full);
305 EXPECT_EQ(Some.intersectWith(Some), Some);
306 EXPECT_EQ(Some.intersectWith(One), One);
307 EXPECT_EQ(Full.intersectWith(One), One);
308 EXPECT_EQ(Full.intersectWith(Some), Some);
309 EXPECT_EQ(Some.intersectWith(Wrap), Empty);
310 EXPECT_EQ(One.intersectWith(Wrap), Empty);
311 EXPECT_EQ(One.intersectWith(Wrap), Wrap.intersectWith(One));
Dan Gohman5035fbf2009-07-09 22:07:27 +0000312
Nick Lewycky0d139032009-07-18 06:34:42 +0000313 // Klee generated testcase from PR4545.
314 // The intersection of i16 [4, 2) and [6, 5) is disjoint, looking like
315 // 01..4.6789ABCDEF where the dots represent values not in the intersection.
316 ConstantRange LHS(APInt(16, 4), APInt(16, 2));
317 ConstantRange RHS(APInt(16, 6), APInt(16, 5));
Chris Lattnerdbbdc792009-08-23 06:32:25 +0000318 EXPECT_TRUE(LHS.intersectWith(RHS) == LHS);
Nuno Lopes63afc082012-05-18 00:14:36 +0000319
320 // previous bug: intersection of [min, 3) and [2, max) should be 2
Nuno Lopesebb0c942012-06-28 00:59:33 +0000321 LHS = ConstantRange(APInt(32, -2147483646), APInt(32, 3));
322 RHS = ConstantRange(APInt(32, 2), APInt(32, 2147483646));
Nuno Lopes63afc082012-05-18 00:14:36 +0000323 EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 2)));
Nuno Lopesebb0c942012-06-28 00:59:33 +0000324
325 // [2, 0) /\ [4, 3) = [2, 0)
326 LHS = ConstantRange(APInt(32, 2), APInt(32, 0));
327 RHS = ConstantRange(APInt(32, 4), APInt(32, 3));
328 EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 2), APInt(32, 0)));
329
330 // [2, 0) /\ [4, 2) = [4, 0)
331 LHS = ConstantRange(APInt(32, 2), APInt(32, 0));
332 RHS = ConstantRange(APInt(32, 4), APInt(32, 2));
333 EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 4), APInt(32, 0)));
334
335 // [4, 2) /\ [5, 1) = [5, 1)
336 LHS = ConstantRange(APInt(32, 4), APInt(32, 2));
337 RHS = ConstantRange(APInt(32, 5), APInt(32, 1));
338 EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 5), APInt(32, 1)));
339
340 // [2, 0) /\ [7, 4) = [7, 4)
341 LHS = ConstantRange(APInt(32, 2), APInt(32, 0));
342 RHS = ConstantRange(APInt(32, 7), APInt(32, 4));
343 EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 7), APInt(32, 4)));
344
345 // [4, 2) /\ [1, 0) = [1, 0)
346 LHS = ConstantRange(APInt(32, 4), APInt(32, 2));
347 RHS = ConstantRange(APInt(32, 1), APInt(32, 0));
348 EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 4), APInt(32, 2)));
349
350 // [15, 0) /\ [7, 6) = [15, 0)
351 LHS = ConstantRange(APInt(32, 15), APInt(32, 0));
352 RHS = ConstantRange(APInt(32, 7), APInt(32, 6));
353 EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 15), APInt(32, 0)));
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000354}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000355
Nikita Popovee9f2ae2019-03-27 20:18:51 +0000356TEST_F(ConstantRangeTest, IntersectWithExhaustive) {
357 unsigned Bits = 4;
358 EnumerateTwoConstantRanges(Bits,
359 [=](const ConstantRange &CR1, const ConstantRange &CR2) {
360 // Collect up to three contiguous unsigned ranges. The HaveInterrupt
361 // variables are used determine when we have to switch to the next
362 // range because the previous one ended.
363 APInt Lower1(Bits, 0), Upper1(Bits, 0);
364 APInt Lower2(Bits, 0), Upper2(Bits, 0);
365 APInt Lower3(Bits, 0), Upper3(Bits, 0);
366 bool HaveRange1 = false, HaveInterrupt1 = false;
367 bool HaveRange2 = false, HaveInterrupt2 = false;
368 bool HaveRange3 = false, HaveInterrupt3 = false;
369
370 APInt Num(Bits, 0);
371 for (unsigned I = 0, Limit = 1 << Bits; I < Limit; ++I, ++Num) {
372 if (!CR1.contains(Num) || !CR2.contains(Num)) {
373 if (HaveRange3)
374 HaveInterrupt3 = true;
375 else if (HaveRange2)
376 HaveInterrupt2 = true;
377 else if (HaveRange1)
378 HaveInterrupt1 = true;
379 continue;
380 }
381
382 if (HaveRange3) {
383 Upper3 = Num;
384 } else if (HaveInterrupt2) {
385 HaveRange3 = true;
386 Lower3 = Upper3 = Num;
387 } else if (HaveRange2) {
388 Upper2 = Num;
389 } else if (HaveInterrupt1) {
390 HaveRange2 = true;
391 Lower2 = Upper2 = Num;
392 } else if (HaveRange1) {
393 Upper1 = Num;
394 } else {
395 HaveRange1 = true;
396 Lower1 = Upper1 = Num;
397 }
398 }
399
400 assert(!HaveInterrupt3 && "Should have at most three ranges");
401
402 ConstantRange CR = CR1.intersectWith(CR2);
403
404 if (!HaveRange1) {
405 EXPECT_TRUE(CR.isEmptySet());
406 return;
407 }
408
409 if (!HaveRange2) {
410 if (Lower1 == Upper1 + 1) {
411 EXPECT_TRUE(CR.isFullSet());
412 } else {
413 ConstantRange Expected(Lower1, Upper1 + 1);
414 EXPECT_EQ(Expected, CR);
415 }
416 return;
417 }
418
419 ConstantRange Variant1(Bits, /*full*/ true);
420 ConstantRange Variant2(Bits, /*full*/ true);
421 if (!HaveRange3) {
422 // Compute the two possible ways to cover two disjoint ranges.
423 if (Lower1 != Upper2 + 1)
424 Variant1 = ConstantRange(Lower1, Upper2 + 1);
425 if (Lower2 != Upper1 + 1)
426 Variant2 = ConstantRange(Lower2, Upper1 + 1);
427 } else {
428 // If we have three ranges, the first and last one have to be adjacent
429 // to the unsigned domain. It's better to think of this as having two
430 // holes, and we can construct one range using each hole.
431 assert(Lower1.isNullValue() && Upper3.isMaxValue());
432 Variant1 = ConstantRange(Lower2, Upper1 + 1);
433 Variant2 = ConstantRange(Lower3, Upper2 + 1);
434 }
435
436 // The intersection should return the smaller of the two variants.
437 if (Variant1.isSizeStrictlySmallerThan(Variant2))
438 EXPECT_EQ(Variant1, CR);
439 else if (Variant2.isSizeStrictlySmallerThan(Variant1))
440 EXPECT_EQ(Variant2, CR);
441 else
442 EXPECT_TRUE(Variant1 == CR || Variant2 == CR);
443 });
444}
445
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000446TEST_F(ConstantRangeTest, UnionWith) {
Nick Lewyckyd5923992009-09-05 18:27:40 +0000447 EXPECT_EQ(Wrap.unionWith(One),
448 ConstantRange(APInt(16, 0xaaa), APInt(16, 0xb)));
449 EXPECT_EQ(One.unionWith(Wrap), Wrap.unionWith(One));
450 EXPECT_EQ(Empty.unionWith(Empty), Empty);
451 EXPECT_EQ(Full.unionWith(Full), Full);
452 EXPECT_EQ(Some.unionWith(Wrap), Full);
Nick Lewycky567daf32009-07-19 03:44:35 +0000453
454 // PR4545
Nick Lewyckyd5923992009-09-05 18:27:40 +0000455 EXPECT_EQ(ConstantRange(APInt(16, 14), APInt(16, 1)).unionWith(
456 ConstantRange(APInt(16, 0), APInt(16, 8))),
457 ConstantRange(APInt(16, 14), APInt(16, 8)));
458 EXPECT_EQ(ConstantRange(APInt(16, 6), APInt(16, 4)).unionWith(
459 ConstantRange(APInt(16, 4), APInt(16, 0))),
Nikita Popov977934f2019-03-24 09:34:40 +0000460 ConstantRange::getFull(16));
Nick Lewyckyd5923992009-09-05 18:27:40 +0000461 EXPECT_EQ(ConstantRange(APInt(16, 1), APInt(16, 0)).unionWith(
462 ConstantRange(APInt(16, 2), APInt(16, 1))),
Nikita Popov977934f2019-03-24 09:34:40 +0000463 ConstantRange::getFull(16));
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000464}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000465
Nuno Lopes5020db22012-06-28 16:10:13 +0000466TEST_F(ConstantRangeTest, SetDifference) {
467 EXPECT_EQ(Full.difference(Empty), Full);
468 EXPECT_EQ(Full.difference(Full), Empty);
469 EXPECT_EQ(Empty.difference(Empty), Empty);
470 EXPECT_EQ(Empty.difference(Full), Empty);
471
472 ConstantRange A(APInt(16, 3), APInt(16, 7));
473 ConstantRange B(APInt(16, 5), APInt(16, 9));
474 ConstantRange C(APInt(16, 3), APInt(16, 5));
475 ConstantRange D(APInt(16, 7), APInt(16, 9));
476 ConstantRange E(APInt(16, 5), APInt(16, 4));
477 ConstantRange F(APInt(16, 7), APInt(16, 3));
478 EXPECT_EQ(A.difference(B), C);
479 EXPECT_EQ(B.difference(A), D);
480 EXPECT_EQ(E.difference(A), F);
481}
482
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000483TEST_F(ConstantRangeTest, SubtractAPInt) {
Nick Lewyckyd5923992009-09-05 18:27:40 +0000484 EXPECT_EQ(Full.subtract(APInt(16, 4)), Full);
485 EXPECT_EQ(Empty.subtract(APInt(16, 4)), Empty);
486 EXPECT_EQ(Some.subtract(APInt(16, 4)),
487 ConstantRange(APInt(16, 0x6), APInt(16, 0xaa6)));
488 EXPECT_EQ(Wrap.subtract(APInt(16, 4)),
489 ConstantRange(APInt(16, 0xaa6), APInt(16, 0x6)));
490 EXPECT_EQ(One.subtract(APInt(16, 4)),
491 ConstantRange(APInt(16, 0x6)));
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000492}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000493
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000494TEST_F(ConstantRangeTest, Add) {
Nick Lewyckyd5923992009-09-05 18:27:40 +0000495 EXPECT_EQ(Full.add(APInt(16, 4)), Full);
496 EXPECT_EQ(Full.add(Full), Full);
497 EXPECT_EQ(Full.add(Empty), Empty);
498 EXPECT_EQ(Full.add(One), Full);
499 EXPECT_EQ(Full.add(Some), Full);
500 EXPECT_EQ(Full.add(Wrap), Full);
501 EXPECT_EQ(Empty.add(Empty), Empty);
502 EXPECT_EQ(Empty.add(One), Empty);
503 EXPECT_EQ(Empty.add(Some), Empty);
504 EXPECT_EQ(Empty.add(Wrap), Empty);
505 EXPECT_EQ(Empty.add(APInt(16, 4)), Empty);
506 EXPECT_EQ(Some.add(APInt(16, 4)),
Nick Lewyckyd385c222010-08-11 22:04:36 +0000507 ConstantRange(APInt(16, 0xe), APInt(16, 0xaae)));
Nick Lewyckyd5923992009-09-05 18:27:40 +0000508 EXPECT_EQ(Wrap.add(APInt(16, 4)),
Nick Lewyckyd385c222010-08-11 22:04:36 +0000509 ConstantRange(APInt(16, 0xaae), APInt(16, 0xe)));
Nick Lewyckyd5923992009-09-05 18:27:40 +0000510 EXPECT_EQ(One.add(APInt(16, 4)),
Nick Lewyckyd385c222010-08-11 22:04:36 +0000511 ConstantRange(APInt(16, 0xe)));
512}
513
Artur Pilipenkoed841032016-10-19 14:44:23 +0000514TEST_F(ConstantRangeTest, AddWithNoSignedWrap) {
515 EXPECT_EQ(Empty.addWithNoSignedWrap(APInt(16, 1)), Empty);
516 EXPECT_EQ(Full.addWithNoSignedWrap(APInt(16, 1)),
517 ConstantRange(APInt(16, INT16_MIN+1), APInt(16, INT16_MIN)));
518 EXPECT_EQ(ConstantRange(APInt(8, -50), APInt(8, 50)).addWithNoSignedWrap(APInt(8, 10)),
519 ConstantRange(APInt(8, -40), APInt(8, 60)));
520 EXPECT_EQ(ConstantRange(APInt(8, -50), APInt(8, 120)).addWithNoSignedWrap(APInt(8, 10)),
521 ConstantRange(APInt(8, -40), APInt(8, INT8_MIN)));
522 EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, -10)).addWithNoSignedWrap(APInt(8, 5)),
523 ConstantRange(APInt(8, 125), APInt(8, -5)));
524 EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, -120)).addWithNoSignedWrap(APInt(8, 10)),
525 ConstantRange(APInt(8, INT8_MIN+10), APInt(8, -110)));
526
527 EXPECT_EQ(Empty.addWithNoSignedWrap(APInt(16, -1)), Empty);
528 EXPECT_EQ(Full.addWithNoSignedWrap(APInt(16, -1)),
529 ConstantRange(APInt(16, INT16_MIN), APInt(16, INT16_MAX)));
530 EXPECT_EQ(ConstantRange(APInt(8, -50), APInt(8, 50)).addWithNoSignedWrap(APInt(8, -10)),
531 ConstantRange(APInt(8, -60), APInt(8, 40)));
532 EXPECT_EQ(ConstantRange(APInt(8, -120), APInt(8, 50)).addWithNoSignedWrap(APInt(8, -10)),
533 ConstantRange(APInt(8, INT8_MIN), APInt(8, 40)));
534 EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, -120)).addWithNoSignedWrap(APInt(8, -5)),
535 ConstantRange(APInt(8, 115), APInt(8, -125)));
536 EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, -120)).addWithNoSignedWrap(APInt(8, -10)),
537 ConstantRange(APInt(8, 110), APInt(8, INT8_MIN-10)));
538}
539
Nick Lewyckyd385c222010-08-11 22:04:36 +0000540TEST_F(ConstantRangeTest, Sub) {
541 EXPECT_EQ(Full.sub(APInt(16, 4)), Full);
542 EXPECT_EQ(Full.sub(Full), Full);
543 EXPECT_EQ(Full.sub(Empty), Empty);
544 EXPECT_EQ(Full.sub(One), Full);
545 EXPECT_EQ(Full.sub(Some), Full);
546 EXPECT_EQ(Full.sub(Wrap), Full);
547 EXPECT_EQ(Empty.sub(Empty), Empty);
548 EXPECT_EQ(Empty.sub(One), Empty);
549 EXPECT_EQ(Empty.sub(Some), Empty);
550 EXPECT_EQ(Empty.sub(Wrap), Empty);
551 EXPECT_EQ(Empty.sub(APInt(16, 4)), Empty);
552 EXPECT_EQ(Some.sub(APInt(16, 4)),
553 ConstantRange(APInt(16, 0x6), APInt(16, 0xaa6)));
Nick Lewycky5dc6b792011-06-22 21:13:46 +0000554 EXPECT_EQ(Some.sub(Some),
555 ConstantRange(APInt(16, 0xf561), APInt(16, 0xaa0)));
Nick Lewyckyd385c222010-08-11 22:04:36 +0000556 EXPECT_EQ(Wrap.sub(APInt(16, 4)),
557 ConstantRange(APInt(16, 0xaa6), APInt(16, 0x6)));
558 EXPECT_EQ(One.sub(APInt(16, 4)),
559 ConstantRange(APInt(16, 0x6)));
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000560}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000561
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000562TEST_F(ConstantRangeTest, Multiply) {
Nick Lewyckyd5923992009-09-05 18:27:40 +0000563 EXPECT_EQ(Full.multiply(Full), Full);
564 EXPECT_EQ(Full.multiply(Empty), Empty);
565 EXPECT_EQ(Full.multiply(One), Full);
566 EXPECT_EQ(Full.multiply(Some), Full);
567 EXPECT_EQ(Full.multiply(Wrap), Full);
568 EXPECT_EQ(Empty.multiply(Empty), Empty);
569 EXPECT_EQ(Empty.multiply(One), Empty);
570 EXPECT_EQ(Empty.multiply(Some), Empty);
571 EXPECT_EQ(Empty.multiply(Wrap), Empty);
572 EXPECT_EQ(One.multiply(One), ConstantRange(APInt(16, 0xa*0xa),
573 APInt(16, 0xa*0xa + 1)));
574 EXPECT_EQ(One.multiply(Some), ConstantRange(APInt(16, 0xa*0xa),
575 APInt(16, 0xa*0xaa9 + 1)));
576 EXPECT_EQ(One.multiply(Wrap), Full);
577 EXPECT_EQ(Some.multiply(Some), Full);
578 EXPECT_EQ(Some.multiply(Wrap), Full);
579 EXPECT_EQ(Wrap.multiply(Wrap), Full);
Nick Lewycky53023892009-07-13 03:27:41 +0000580
Nuno Lopes986cc182012-07-16 20:47:16 +0000581 ConstantRange Zero(APInt(16, 0));
582 EXPECT_EQ(Zero.multiply(Full), Zero);
583 EXPECT_EQ(Zero.multiply(Some), Zero);
584 EXPECT_EQ(Zero.multiply(Wrap), Zero);
585 EXPECT_EQ(Full.multiply(Zero), Zero);
586 EXPECT_EQ(Some.multiply(Zero), Zero);
587 EXPECT_EQ(Wrap.multiply(Zero), Zero);
588
Nick Lewycky53023892009-07-13 03:27:41 +0000589 // http://llvm.org/PR4545
Nick Lewyckyd5923992009-09-05 18:27:40 +0000590 EXPECT_EQ(ConstantRange(APInt(4, 1), APInt(4, 6)).multiply(
591 ConstantRange(APInt(4, 6), APInt(4, 2))),
592 ConstantRange(4, /*isFullSet=*/true));
James Molloydcc78ec2015-03-06 15:50:47 +0000593
594 EXPECT_EQ(ConstantRange(APInt(8, 254), APInt(8, 0)).multiply(
595 ConstantRange(APInt(8, 252), APInt(8, 4))),
596 ConstantRange(APInt(8, 250), APInt(8, 9)));
597 EXPECT_EQ(ConstantRange(APInt(8, 254), APInt(8, 255)).multiply(
598 ConstantRange(APInt(8, 2), APInt(8, 4))),
599 ConstantRange(APInt(8, 250), APInt(8, 253)));
Craig Topper9bbae502017-05-10 18:15:06 +0000600
601 // TODO: This should be return [-2, 0]
602 EXPECT_EQ(ConstantRange(APInt(8, -2)).multiply(
603 ConstantRange(APInt(8, 0), APInt(8, 2))),
Craig Topperc51d0532017-05-10 20:01:48 +0000604 ConstantRange(APInt(8, -2), APInt(8, 1)));
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000605}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000606
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000607TEST_F(ConstantRangeTest, UMax) {
Nick Lewyckyd5923992009-09-05 18:27:40 +0000608 EXPECT_EQ(Full.umax(Full), Full);
609 EXPECT_EQ(Full.umax(Empty), Empty);
610 EXPECT_EQ(Full.umax(Some), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
611 EXPECT_EQ(Full.umax(Wrap), Full);
612 EXPECT_EQ(Full.umax(Some), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
613 EXPECT_EQ(Empty.umax(Empty), Empty);
614 EXPECT_EQ(Empty.umax(Some), Empty);
615 EXPECT_EQ(Empty.umax(Wrap), Empty);
616 EXPECT_EQ(Empty.umax(One), Empty);
617 EXPECT_EQ(Some.umax(Some), Some);
618 EXPECT_EQ(Some.umax(Wrap), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
619 EXPECT_EQ(Some.umax(One), Some);
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000620 // TODO: ConstantRange is currently over-conservative here.
Nick Lewyckyd5923992009-09-05 18:27:40 +0000621 EXPECT_EQ(Wrap.umax(Wrap), Full);
622 EXPECT_EQ(Wrap.umax(One), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
623 EXPECT_EQ(One.umax(One), One);
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000624}
625
626TEST_F(ConstantRangeTest, SMax) {
Nick Lewyckyd5923992009-09-05 18:27:40 +0000627 EXPECT_EQ(Full.smax(Full), Full);
628 EXPECT_EQ(Full.smax(Empty), Empty);
629 EXPECT_EQ(Full.smax(Some), ConstantRange(APInt(16, 0xa),
630 APInt::getSignedMinValue(16)));
631 EXPECT_EQ(Full.smax(Wrap), Full);
632 EXPECT_EQ(Full.smax(One), ConstantRange(APInt(16, 0xa),
633 APInt::getSignedMinValue(16)));
634 EXPECT_EQ(Empty.smax(Empty), Empty);
635 EXPECT_EQ(Empty.smax(Some), Empty);
636 EXPECT_EQ(Empty.smax(Wrap), Empty);
637 EXPECT_EQ(Empty.smax(One), Empty);
638 EXPECT_EQ(Some.smax(Some), Some);
639 EXPECT_EQ(Some.smax(Wrap), ConstantRange(APInt(16, 0xa),
640 APInt(16, (uint64_t)INT16_MIN)));
641 EXPECT_EQ(Some.smax(One), Some);
642 EXPECT_EQ(Wrap.smax(One), ConstantRange(APInt(16, 0xa),
643 APInt(16, (uint64_t)INT16_MIN)));
644 EXPECT_EQ(One.smax(One), One);
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000645}
Dan Gohman5035fbf2009-07-09 22:07:27 +0000646
Philip Reamesba313122016-02-26 22:08:18 +0000647TEST_F(ConstantRangeTest, UMin) {
648 EXPECT_EQ(Full.umin(Full), Full);
649 EXPECT_EQ(Full.umin(Empty), Empty);
650 EXPECT_EQ(Full.umin(Some), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
651 EXPECT_EQ(Full.umin(Wrap), Full);
652 EXPECT_EQ(Empty.umin(Empty), Empty);
653 EXPECT_EQ(Empty.umin(Some), Empty);
654 EXPECT_EQ(Empty.umin(Wrap), Empty);
655 EXPECT_EQ(Empty.umin(One), Empty);
656 EXPECT_EQ(Some.umin(Some), Some);
657 EXPECT_EQ(Some.umin(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
658 EXPECT_EQ(Some.umin(One), One);
659 // TODO: ConstantRange is currently over-conservative here.
660 EXPECT_EQ(Wrap.umin(Wrap), Full);
661 EXPECT_EQ(Wrap.umin(One), ConstantRange(APInt(16, 0), APInt(16, 0xb)));
662 EXPECT_EQ(One.umin(One), One);
663}
664
665TEST_F(ConstantRangeTest, SMin) {
666 EXPECT_EQ(Full.smin(Full), Full);
667 EXPECT_EQ(Full.smin(Empty), Empty);
668 EXPECT_EQ(Full.smin(Some), ConstantRange(APInt(16, (uint64_t)INT16_MIN),
669 APInt(16, 0xaaa)));
670 EXPECT_EQ(Full.smin(Wrap), Full);
671 EXPECT_EQ(Empty.smin(Empty), Empty);
672 EXPECT_EQ(Empty.smin(Some), Empty);
673 EXPECT_EQ(Empty.smin(Wrap), Empty);
674 EXPECT_EQ(Empty.smin(One), Empty);
675 EXPECT_EQ(Some.smin(Some), Some);
676 EXPECT_EQ(Some.smin(Wrap), ConstantRange(APInt(16, (uint64_t)INT16_MIN),
677 APInt(16, 0xaaa)));
678 EXPECT_EQ(Some.smin(One), One);
679 // TODO: ConstantRange is currently over-conservative here.
680 EXPECT_EQ(Wrap.smin(Wrap), Full);
681 EXPECT_EQ(Wrap.smin(One), ConstantRange(APInt(16, (uint64_t)INT16_MIN),
682 APInt(16, 0xb)));
683 EXPECT_EQ(One.smin(One), One);
684}
685
Nick Lewycky17a4fa82009-07-11 18:43:20 +0000686TEST_F(ConstantRangeTest, UDiv) {
Nick Lewyckyd5923992009-09-05 18:27:40 +0000687 EXPECT_EQ(Full.udiv(Full), Full);
688 EXPECT_EQ(Full.udiv(Empty), Empty);
689 EXPECT_EQ(Full.udiv(One), ConstantRange(APInt(16, 0),
690 APInt(16, 0xffff / 0xa + 1)));
691 EXPECT_EQ(Full.udiv(Some), ConstantRange(APInt(16, 0),
692 APInt(16, 0xffff / 0xa + 1)));
693 EXPECT_EQ(Full.udiv(Wrap), Full);
694 EXPECT_EQ(Empty.udiv(Empty), Empty);
695 EXPECT_EQ(Empty.udiv(One), Empty);
696 EXPECT_EQ(Empty.udiv(Some), Empty);
697 EXPECT_EQ(Empty.udiv(Wrap), Empty);
698 EXPECT_EQ(One.udiv(One), ConstantRange(APInt(16, 1)));
699 EXPECT_EQ(One.udiv(Some), ConstantRange(APInt(16, 0), APInt(16, 2)));
700 EXPECT_EQ(One.udiv(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xb)));
701 EXPECT_EQ(Some.udiv(Some), ConstantRange(APInt(16, 0), APInt(16, 0x111)));
702 EXPECT_EQ(Some.udiv(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
703 EXPECT_EQ(Wrap.udiv(Wrap), Full);
Dan Gohman5035fbf2009-07-09 22:07:27 +0000704}
705
Nick Lewyckyd385c222010-08-11 22:04:36 +0000706TEST_F(ConstantRangeTest, Shl) {
Marcello Maggioni30eb5752019-04-07 06:12:44 +0000707 ConstantRange Some2(APInt(16, 0xfff), APInt(16, 0x8000));
708 ConstantRange WrapNullMax(APInt(16, 0x1), APInt(16, 0x0));
Nick Lewyckyd385c222010-08-11 22:04:36 +0000709 EXPECT_EQ(Full.shl(Full), Full);
710 EXPECT_EQ(Full.shl(Empty), Empty);
711 EXPECT_EQ(Full.shl(One), Full); // TODO: [0, (-1 << 0xa) + 1)
712 EXPECT_EQ(Full.shl(Some), Full); // TODO: [0, (-1 << 0xa) + 1)
713 EXPECT_EQ(Full.shl(Wrap), Full);
714 EXPECT_EQ(Empty.shl(Empty), Empty);
715 EXPECT_EQ(Empty.shl(One), Empty);
716 EXPECT_EQ(Empty.shl(Some), Empty);
717 EXPECT_EQ(Empty.shl(Wrap), Empty);
718 EXPECT_EQ(One.shl(One), ConstantRange(APInt(16, 0xa << 0xa),
719 APInt(16, (0xa << 0xa) + 1)));
720 EXPECT_EQ(One.shl(Some), Full); // TODO: [0xa << 0xa, 0)
721 EXPECT_EQ(One.shl(Wrap), Full); // TODO: [0xa, 0xa << 14 + 1)
722 EXPECT_EQ(Some.shl(Some), Full); // TODO: [0xa << 0xa, 0xfc01)
723 EXPECT_EQ(Some.shl(Wrap), Full); // TODO: [0xa, 0x7ff << 0x5 + 1)
724 EXPECT_EQ(Wrap.shl(Wrap), Full);
Marcello Maggioni30eb5752019-04-07 06:12:44 +0000725 EXPECT_EQ(
726 Some2.shl(ConstantRange(APInt(16, 0x1))),
727 ConstantRange(APInt(16, 0xfff << 0x1), APInt(16, 0x7fff << 0x1) + 1));
728 EXPECT_EQ(One.shl(WrapNullMax), Full);
Nick Lewyckyd385c222010-08-11 22:04:36 +0000729}
730
731TEST_F(ConstantRangeTest, Lshr) {
732 EXPECT_EQ(Full.lshr(Full), Full);
733 EXPECT_EQ(Full.lshr(Empty), Empty);
734 EXPECT_EQ(Full.lshr(One), ConstantRange(APInt(16, 0),
735 APInt(16, (0xffff >> 0xa) + 1)));
736 EXPECT_EQ(Full.lshr(Some), ConstantRange(APInt(16, 0),
737 APInt(16, (0xffff >> 0xa) + 1)));
738 EXPECT_EQ(Full.lshr(Wrap), Full);
739 EXPECT_EQ(Empty.lshr(Empty), Empty);
740 EXPECT_EQ(Empty.lshr(One), Empty);
741 EXPECT_EQ(Empty.lshr(Some), Empty);
742 EXPECT_EQ(Empty.lshr(Wrap), Empty);
743 EXPECT_EQ(One.lshr(One), ConstantRange(APInt(16, 0)));
744 EXPECT_EQ(One.lshr(Some), ConstantRange(APInt(16, 0)));
745 EXPECT_EQ(One.lshr(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xb)));
746 EXPECT_EQ(Some.lshr(Some), ConstantRange(APInt(16, 0),
747 APInt(16, (0xaaa >> 0xa) + 1)));
748 EXPECT_EQ(Some.lshr(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
749 EXPECT_EQ(Wrap.lshr(Wrap), Full);
750}
751
Max Kazantsevd7921712017-12-18 13:01:32 +0000752TEST_F(ConstantRangeTest, Ashr) {
753 EXPECT_EQ(Full.ashr(Full), Full);
754 EXPECT_EQ(Full.ashr(Empty), Empty);
755 EXPECT_EQ(Full.ashr(One), ConstantRange(APInt(16, 0xffe0),
756 APInt(16, (0x7fff >> 0xa) + 1 )));
757 ConstantRange Small(APInt(16, 0xa), APInt(16, 0xb));
758 EXPECT_EQ(Full.ashr(Small), ConstantRange(APInt(16, 0xffe0),
759 APInt(16, (0x7fff >> 0xa) + 1 )));
760 EXPECT_EQ(Full.ashr(Some), ConstantRange(APInt(16, 0xffe0),
761 APInt(16, (0x7fff >> 0xa) + 1 )));
762 EXPECT_EQ(Full.ashr(Wrap), Full);
763 EXPECT_EQ(Empty.ashr(Empty), Empty);
764 EXPECT_EQ(Empty.ashr(One), Empty);
765 EXPECT_EQ(Empty.ashr(Some), Empty);
766 EXPECT_EQ(Empty.ashr(Wrap), Empty);
767 EXPECT_EQ(One.ashr(One), ConstantRange(APInt(16, 0)));
768 EXPECT_EQ(One.ashr(Some), ConstantRange(APInt(16, 0)));
769 EXPECT_EQ(One.ashr(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xb)));
770 EXPECT_EQ(Some.ashr(Some), ConstantRange(APInt(16, 0),
771 APInt(16, (0xaaa >> 0xa) + 1)));
772 EXPECT_EQ(Some.ashr(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
773 EXPECT_EQ(Wrap.ashr(Wrap), Full);
774 ConstantRange Neg(APInt(16, 0xf3f0, true), APInt(16, 0xf7f8, true));
775 EXPECT_EQ(Neg.ashr(Small), ConstantRange(APInt(16, 0xfffc, true),
776 APInt(16, 0xfffe, true)));
777}
778
Sanjoy Das7182d362015-03-18 00:41:24 +0000779TEST(ConstantRange, MakeAllowedICmpRegion) {
Nick Lewycky5154ee02010-09-28 18:18:36 +0000780 // PR8250
781 ConstantRange SMax = ConstantRange(APInt::getSignedMaxValue(32));
Sanjoy Das7182d362015-03-18 00:41:24 +0000782 EXPECT_TRUE(ConstantRange::makeAllowedICmpRegion(ICmpInst::ICMP_SGT, SMax)
783 .isEmptySet());
784}
785
786TEST(ConstantRange, MakeSatisfyingICmpRegion) {
787 ConstantRange LowHalf(APInt(8, 0), APInt(8, 128));
788 ConstantRange HighHalf(APInt(8, 128), APInt(8, 0));
789 ConstantRange EmptySet(8, /* isFullSet = */ false);
790
791 EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_NE, LowHalf),
792 HighHalf);
793
794 EXPECT_EQ(
795 ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_NE, HighHalf),
796 LowHalf);
797
798 EXPECT_TRUE(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_EQ,
799 HighHalf).isEmptySet());
800
801 ConstantRange UnsignedSample(APInt(8, 5), APInt(8, 200));
802
803 EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_ULT,
804 UnsignedSample),
805 ConstantRange(APInt(8, 0), APInt(8, 5)));
806
807 EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_ULE,
808 UnsignedSample),
809 ConstantRange(APInt(8, 0), APInt(8, 6)));
810
811 EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_UGT,
812 UnsignedSample),
813 ConstantRange(APInt(8, 200), APInt(8, 0)));
814
815 EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_UGE,
816 UnsignedSample),
817 ConstantRange(APInt(8, 199), APInt(8, 0)));
818
819 ConstantRange SignedSample(APInt(8, -5), APInt(8, 5));
820
821 EXPECT_EQ(
822 ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SLT, SignedSample),
823 ConstantRange(APInt(8, -128), APInt(8, -5)));
824
825 EXPECT_EQ(
826 ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SLE, SignedSample),
827 ConstantRange(APInt(8, -128), APInt(8, -4)));
828
829 EXPECT_EQ(
830 ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SGT, SignedSample),
831 ConstantRange(APInt(8, 5), APInt(8, -128)));
832
833 EXPECT_EQ(
834 ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SGE, SignedSample),
835 ConstantRange(APInt(8, 4), APInt(8, -128)));
Nick Lewycky5154ee02010-09-28 18:18:36 +0000836}
837
Sanjoy Das39289102016-03-03 18:31:33 +0000838TEST(ConstantRange, MakeGuaranteedNoWrapRegion) {
Sanjoy Das6ed05302015-10-22 03:12:57 +0000839 const int IntMin4Bits = 8;
840 const int IntMax4Bits = 7;
841 typedef OverflowingBinaryOperator OBO;
842
843 for (int Const : {0, -1, -2, 1, 2, IntMin4Bits, IntMax4Bits}) {
844 APInt C(4, Const, true /* = isSigned */);
845
Sanjoy Das5079f622016-02-22 16:13:02 +0000846 auto NUWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
847 Instruction::Add, C, OBO::NoUnsignedWrap);
Sanjoy Das6ed05302015-10-22 03:12:57 +0000848
849 EXPECT_FALSE(NUWRegion.isEmptySet());
850
Sanjoy Das5079f622016-02-22 16:13:02 +0000851 auto NSWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
852 Instruction::Add, C, OBO::NoSignedWrap);
Sanjoy Das6ed05302015-10-22 03:12:57 +0000853
854 EXPECT_FALSE(NSWRegion.isEmptySet());
855
Sanjoy Das5079f622016-02-22 16:13:02 +0000856 auto NoWrapRegion = ConstantRange::makeGuaranteedNoWrapRegion(
Sanjoy Das6ed05302015-10-22 03:12:57 +0000857 Instruction::Add, C, OBO::NoSignedWrap | OBO::NoUnsignedWrap);
858
859 EXPECT_FALSE(NoWrapRegion.isEmptySet());
860 EXPECT_TRUE(NUWRegion.intersectWith(NSWRegion).contains(NoWrapRegion));
861
862 for (APInt I = NUWRegion.getLower(), E = NUWRegion.getUpper(); I != E;
863 ++I) {
864 bool Overflow = false;
Craig Topper3cc8da32017-04-19 22:11:05 +0000865 (void)I.uadd_ov(C, Overflow);
Sanjoy Das6ed05302015-10-22 03:12:57 +0000866 EXPECT_FALSE(Overflow);
867 }
868
869 for (APInt I = NSWRegion.getLower(), E = NSWRegion.getUpper(); I != E;
870 ++I) {
871 bool Overflow = false;
Craig Topper3cc8da32017-04-19 22:11:05 +0000872 (void)I.sadd_ov(C, Overflow);
Sanjoy Das6ed05302015-10-22 03:12:57 +0000873 EXPECT_FALSE(Overflow);
874 }
875
876 for (APInt I = NoWrapRegion.getLower(), E = NoWrapRegion.getUpper(); I != E;
877 ++I) {
878 bool Overflow = false;
879
Craig Topper3cc8da32017-04-19 22:11:05 +0000880 (void)I.sadd_ov(C, Overflow);
Sanjoy Das6ed05302015-10-22 03:12:57 +0000881 EXPECT_FALSE(Overflow);
882
Craig Topper3cc8da32017-04-19 22:11:05 +0000883 (void)I.uadd_ov(C, Overflow);
Sanjoy Das6ed05302015-10-22 03:12:57 +0000884 EXPECT_FALSE(Overflow);
885 }
886 }
Sanjoy Dasf3867e62016-03-03 18:31:16 +0000887
Joel Galensonc32b0fc2017-12-05 18:14:23 +0000888 for (int Const : {0, -1, -2, 1, 2, IntMin4Bits, IntMax4Bits}) {
889 APInt C(4, Const, true /* = isSigned */);
890
891 auto NUWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
892 Instruction::Sub, C, OBO::NoUnsignedWrap);
893
894 EXPECT_FALSE(NUWRegion.isEmptySet());
895
896 auto NSWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
897 Instruction::Sub, C, OBO::NoSignedWrap);
898
899 EXPECT_FALSE(NSWRegion.isEmptySet());
900
901 auto NoWrapRegion = ConstantRange::makeGuaranteedNoWrapRegion(
902 Instruction::Sub, C, OBO::NoSignedWrap | OBO::NoUnsignedWrap);
903
904 EXPECT_FALSE(NoWrapRegion.isEmptySet());
905 EXPECT_TRUE(NUWRegion.intersectWith(NSWRegion).contains(NoWrapRegion));
906
907 for (APInt I = NUWRegion.getLower(), E = NUWRegion.getUpper(); I != E;
908 ++I) {
909 bool Overflow = false;
910 (void)I.usub_ov(C, Overflow);
911 EXPECT_FALSE(Overflow);
912 }
913
914 for (APInt I = NSWRegion.getLower(), E = NSWRegion.getUpper(); I != E;
915 ++I) {
916 bool Overflow = false;
917 (void)I.ssub_ov(C, Overflow);
918 EXPECT_FALSE(Overflow);
919 }
920
921 for (APInt I = NoWrapRegion.getLower(), E = NoWrapRegion.getUpper(); I != E;
922 ++I) {
923 bool Overflow = false;
924
925 (void)I.ssub_ov(C, Overflow);
926 EXPECT_FALSE(Overflow);
927
928 (void)I.usub_ov(C, Overflow);
929 EXPECT_FALSE(Overflow);
930 }
931 }
932
Sanjoy Dasf3867e62016-03-03 18:31:16 +0000933 auto NSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
934 Instruction::Add, ConstantRange(32, /* isFullSet = */ true),
935 OBO::NoSignedWrap);
936 EXPECT_TRUE(NSWForAllValues.isSingleElement() &&
937 NSWForAllValues.getSingleElement()->isMinValue());
938
Joel Galensonc32b0fc2017-12-05 18:14:23 +0000939 NSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
940 Instruction::Sub, ConstantRange(32, /* isFullSet = */ true),
941 OBO::NoSignedWrap);
942 EXPECT_TRUE(NSWForAllValues.isSingleElement() &&
943 NSWForAllValues.getSingleElement()->isMaxValue());
944
Sanjoy Dasf3867e62016-03-03 18:31:16 +0000945 auto NUWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
946 Instruction::Add, ConstantRange(32, /* isFullSet = */ true),
947 OBO::NoUnsignedWrap);
948 EXPECT_TRUE(NUWForAllValues.isSingleElement() &&
Craig Topper5c0a5472017-05-15 04:40:19 +0000949 NUWForAllValues.getSingleElement()->isMinValue());
Sanjoy Dasf3867e62016-03-03 18:31:16 +0000950
Joel Galensonc32b0fc2017-12-05 18:14:23 +0000951 NUWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
952 Instruction::Sub, ConstantRange(32, /* isFullSet = */ true),
953 OBO::NoUnsignedWrap);
954 EXPECT_TRUE(NUWForAllValues.isSingleElement() &&
955 NUWForAllValues.getSingleElement()->isMaxValue());
956
Sanjoy Dasf3867e62016-03-03 18:31:16 +0000957 auto NUWAndNSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
958 Instruction::Add, ConstantRange(32, /* isFullSet = */ true),
959 OBO::NoUnsignedWrap | OBO::NoSignedWrap);
960 EXPECT_TRUE(NUWAndNSWForAllValues.isSingleElement() &&
Craig Topper5c0a5472017-05-15 04:40:19 +0000961 NUWAndNSWForAllValues.getSingleElement()->isMinValue());
Sanjoy Dasf3867e62016-03-03 18:31:16 +0000962
Joel Galensonc32b0fc2017-12-05 18:14:23 +0000963 NUWAndNSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
964 Instruction::Sub, ConstantRange(32, /* isFullSet = */ true),
965 OBO::NoUnsignedWrap | OBO::NoSignedWrap);
966 EXPECT_TRUE(NUWAndNSWForAllValues.isSingleElement() &&
967 NUWAndNSWForAllValues.getSingleElement()->isMaxValue());
968
969 EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
970 Instruction::Add, APInt(32, 0), OBO::NoUnsignedWrap).isFullSet());
971 EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
972 Instruction::Add, APInt(32, 0), OBO::NoSignedWrap).isFullSet());
973 EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
974 Instruction::Add, APInt(32, 0),
975 OBO::NoUnsignedWrap | OBO::NoSignedWrap).isFullSet());
976 EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
977 Instruction::Sub, APInt(32, 0), OBO::NoUnsignedWrap).isFullSet());
978 EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
979 Instruction::Sub, APInt(32, 0), OBO::NoSignedWrap).isFullSet());
980 EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
981 Instruction::Sub, APInt(32, 0),
982 OBO::NoUnsignedWrap | OBO::NoSignedWrap).isFullSet());
983
Sanjoy Dasf3867e62016-03-03 18:31:16 +0000984 ConstantRange OneToFive(APInt(32, 1), APInt(32, 6));
985 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
986 Instruction::Add, OneToFive, OBO::NoSignedWrap),
987 ConstantRange(APInt::getSignedMinValue(32),
988 APInt::getSignedMaxValue(32) - 4));
989 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
990 Instruction::Add, OneToFive, OBO::NoUnsignedWrap),
991 ConstantRange(APInt::getMinValue(32), APInt::getMinValue(32) - 5));
992 EXPECT_EQ(
993 ConstantRange::makeGuaranteedNoWrapRegion(
994 Instruction::Add, OneToFive, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
995 ConstantRange(APInt::getMinValue(32), APInt::getSignedMaxValue(32) - 4));
Joel Galensonc32b0fc2017-12-05 18:14:23 +0000996 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
997 Instruction::Sub, OneToFive, OBO::NoSignedWrap),
998 ConstantRange(APInt::getSignedMinValue(32) + 5,
999 APInt::getSignedMinValue(32)));
1000 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1001 Instruction::Sub, OneToFive, OBO::NoUnsignedWrap),
1002 ConstantRange(APInt::getMinValue(32) + 5, APInt::getMinValue(32)));
1003 EXPECT_EQ(
1004 ConstantRange::makeGuaranteedNoWrapRegion(
1005 Instruction::Sub, OneToFive, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
1006 ConstantRange(APInt::getMinValue(32) + 5, APInt::getSignedMinValue(32)));
Sanjoy Dasf3867e62016-03-03 18:31:16 +00001007
1008 ConstantRange MinusFiveToMinusTwo(APInt(32, -5), APInt(32, -1));
1009 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1010 Instruction::Add, MinusFiveToMinusTwo, OBO::NoSignedWrap),
1011 ConstantRange(APInt::getSignedMinValue(32) + 5,
1012 APInt::getSignedMinValue(32)));
1013 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1014 Instruction::Add, MinusFiveToMinusTwo, OBO::NoUnsignedWrap),
1015 ConstantRange(APInt(32, 0), APInt(32, 2)));
1016 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1017 Instruction::Add, MinusFiveToMinusTwo,
1018 OBO::NoUnsignedWrap | OBO::NoSignedWrap),
1019 ConstantRange(APInt(32, 0), APInt(32, 2)));
Joel Galensonc32b0fc2017-12-05 18:14:23 +00001020 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1021 Instruction::Sub, MinusFiveToMinusTwo, OBO::NoSignedWrap),
1022 ConstantRange(APInt::getSignedMinValue(32),
1023 APInt::getSignedMaxValue(32) - 4));
1024 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1025 Instruction::Sub, MinusFiveToMinusTwo, OBO::NoUnsignedWrap),
1026 ConstantRange(APInt::getMaxValue(32) - 1,
1027 APInt::getMinValue(32)));
1028 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1029 Instruction::Sub, MinusFiveToMinusTwo,
1030 OBO::NoUnsignedWrap | OBO::NoSignedWrap),
1031 ConstantRange(APInt::getMaxValue(32) - 1,
1032 APInt::getMinValue(32)));
Sanjoy Dasf3867e62016-03-03 18:31:16 +00001033
1034 ConstantRange MinusOneToOne(APInt(32, -1), APInt(32, 2));
1035 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1036 Instruction::Add, MinusOneToOne, OBO::NoSignedWrap),
1037 ConstantRange(APInt::getSignedMinValue(32) + 1,
1038 APInt::getSignedMinValue(32) - 1));
1039 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1040 Instruction::Add, MinusOneToOne, OBO::NoUnsignedWrap),
1041 ConstantRange(APInt(32, 0), APInt(32, 1)));
1042 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1043 Instruction::Add, MinusOneToOne,
1044 OBO::NoUnsignedWrap | OBO::NoSignedWrap),
1045 ConstantRange(APInt(32, 0), APInt(32, 1)));
Joel Galensonc32b0fc2017-12-05 18:14:23 +00001046 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1047 Instruction::Sub, MinusOneToOne, OBO::NoSignedWrap),
1048 ConstantRange(APInt::getSignedMinValue(32) + 1,
1049 APInt::getSignedMinValue(32) - 1));
1050 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1051 Instruction::Sub, MinusOneToOne, OBO::NoUnsignedWrap),
1052 ConstantRange(APInt::getMaxValue(32),
1053 APInt::getMinValue(32)));
1054 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1055 Instruction::Sub, MinusOneToOne,
1056 OBO::NoUnsignedWrap | OBO::NoSignedWrap),
1057 ConstantRange(APInt::getMaxValue(32),
1058 APInt::getMinValue(32)));
1059
1060 ConstantRange One(APInt(32, 1), APInt(32, 2));
1061 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1062 Instruction::Add, One, OBO::NoSignedWrap),
1063 ConstantRange(APInt::getSignedMinValue(32),
1064 APInt::getSignedMaxValue(32)));
1065 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1066 Instruction::Add, One, OBO::NoUnsignedWrap),
1067 ConstantRange(APInt::getMinValue(32), APInt::getMaxValue(32)));
1068 EXPECT_EQ(
1069 ConstantRange::makeGuaranteedNoWrapRegion(
1070 Instruction::Add, One, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
1071 ConstantRange(APInt(32, 0), APInt::getSignedMaxValue(32)));
1072 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1073 Instruction::Sub, One, OBO::NoSignedWrap),
1074 ConstantRange(APInt::getSignedMinValue(32) + 1,
1075 APInt::getSignedMinValue(32)));
1076 EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
1077 Instruction::Sub, One, OBO::NoUnsignedWrap),
1078 ConstantRange(APInt::getMinValue(32) + 1, APInt::getMinValue(32)));
1079 EXPECT_EQ(
1080 ConstantRange::makeGuaranteedNoWrapRegion(
1081 Instruction::Sub, One, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
1082 ConstantRange(APInt::getMinValue(32) + 1, APInt::getSignedMinValue(32)));
Sanjoy Das6ed05302015-10-22 03:12:57 +00001083}
1084
Sanjoy Das590614c2016-05-19 03:53:06 +00001085TEST(ConstantRange, GetEquivalentICmp) {
1086 APInt RHS;
1087 CmpInst::Predicate Pred;
1088
1089 EXPECT_TRUE(ConstantRange(APInt::getMinValue(32), APInt(32, 100))
1090 .getEquivalentICmp(Pred, RHS));
1091 EXPECT_EQ(Pred, CmpInst::ICMP_ULT);
1092 EXPECT_EQ(RHS, APInt(32, 100));
1093
1094 EXPECT_TRUE(ConstantRange(APInt::getSignedMinValue(32), APInt(32, 100))
1095 .getEquivalentICmp(Pred, RHS));
1096 EXPECT_EQ(Pred, CmpInst::ICMP_SLT);
1097 EXPECT_EQ(RHS, APInt(32, 100));
1098
1099 EXPECT_TRUE(ConstantRange(APInt(32, 100), APInt::getMinValue(32))
1100 .getEquivalentICmp(Pred, RHS));
1101 EXPECT_EQ(Pred, CmpInst::ICMP_UGE);
1102 EXPECT_EQ(RHS, APInt(32, 100));
1103
1104 EXPECT_TRUE(ConstantRange(APInt(32, 100), APInt::getSignedMinValue(32))
1105 .getEquivalentICmp(Pred, RHS));
1106 EXPECT_EQ(Pred, CmpInst::ICMP_SGE);
1107 EXPECT_EQ(RHS, APInt(32, 100));
1108
1109 EXPECT_TRUE(
1110 ConstantRange(32, /*isFullSet=*/true).getEquivalentICmp(Pred, RHS));
1111 EXPECT_EQ(Pred, CmpInst::ICMP_UGE);
1112 EXPECT_EQ(RHS, APInt(32, 0));
1113
1114 EXPECT_TRUE(
1115 ConstantRange(32, /*isFullSet=*/false).getEquivalentICmp(Pred, RHS));
1116 EXPECT_EQ(Pred, CmpInst::ICMP_ULT);
1117 EXPECT_EQ(RHS, APInt(32, 0));
1118
1119 EXPECT_FALSE(ConstantRange(APInt(32, 100), APInt(32, 200))
1120 .getEquivalentICmp(Pred, RHS));
1121
1122 EXPECT_FALSE(ConstantRange(APInt::getSignedMinValue(32) - APInt(32, 100),
1123 APInt::getSignedMinValue(32) + APInt(32, 100))
1124 .getEquivalentICmp(Pred, RHS));
1125
1126 EXPECT_FALSE(ConstantRange(APInt::getMinValue(32) - APInt(32, 100),
1127 APInt::getMinValue(32) + APInt(32, 100))
1128 .getEquivalentICmp(Pred, RHS));
Sanjoy Dasc7d32912016-10-02 20:59:05 +00001129
1130 EXPECT_TRUE(ConstantRange(APInt(32, 100)).getEquivalentICmp(Pred, RHS));
1131 EXPECT_EQ(Pred, CmpInst::ICMP_EQ);
1132 EXPECT_EQ(RHS, APInt(32, 100));
1133
1134 EXPECT_TRUE(
1135 ConstantRange(APInt(32, 100)).inverse().getEquivalentICmp(Pred, RHS));
1136 EXPECT_EQ(Pred, CmpInst::ICMP_NE);
1137 EXPECT_EQ(RHS, APInt(32, 100));
1138
1139 EXPECT_TRUE(
1140 ConstantRange(APInt(512, 100)).inverse().getEquivalentICmp(Pred, RHS));
1141 EXPECT_EQ(Pred, CmpInst::ICMP_NE);
1142 EXPECT_EQ(RHS, APInt(512, 100));
1143
1144 // NB! It would be correct for the following four calls to getEquivalentICmp
1145 // to return ordered predicates like CmpInst::ICMP_ULT or CmpInst::ICMP_UGT.
1146 // However, that's not the case today.
1147
1148 EXPECT_TRUE(ConstantRange(APInt(32, 0)).getEquivalentICmp(Pred, RHS));
1149 EXPECT_EQ(Pred, CmpInst::ICMP_EQ);
1150 EXPECT_EQ(RHS, APInt(32, 0));
1151
1152 EXPECT_TRUE(
1153 ConstantRange(APInt(32, 0)).inverse().getEquivalentICmp(Pred, RHS));
1154 EXPECT_EQ(Pred, CmpInst::ICMP_NE);
1155 EXPECT_EQ(RHS, APInt(32, 0));
1156
1157 EXPECT_TRUE(ConstantRange(APInt(32, -1)).getEquivalentICmp(Pred, RHS));
1158 EXPECT_EQ(Pred, CmpInst::ICMP_EQ);
1159 EXPECT_EQ(RHS, APInt(32, -1));
1160
1161 EXPECT_TRUE(
1162 ConstantRange(APInt(32, -1)).inverse().getEquivalentICmp(Pred, RHS));
1163 EXPECT_EQ(Pred, CmpInst::ICMP_NE);
1164 EXPECT_EQ(RHS, APInt(32, -1));
Sanjoy Das590614c2016-05-19 03:53:06 +00001165}
1166
Tim Shenb32823c2018-06-26 18:54:10 +00001167TEST(ConstantRange, MakeGuaranteedNoWrapRegionMulUnsignedSingleValue) {
1168 typedef OverflowingBinaryOperator OBO;
1169
1170 for (uint64_t I = std::numeric_limits<uint8_t>::min();
1171 I <= std::numeric_limits<uint8_t>::max(); I++) {
1172 auto Range = ConstantRange::makeGuaranteedNoWrapRegion(
1173 Instruction::Mul, ConstantRange(APInt(8, I), APInt(8, I + 1)),
1174 OBO::NoUnsignedWrap);
1175
1176 for (uint64_t V = std::numeric_limits<uint8_t>::min();
1177 V <= std::numeric_limits<uint8_t>::max(); V++) {
1178 bool Overflow;
1179 (void)APInt(8, I).umul_ov(APInt(8, V), Overflow);
1180 EXPECT_EQ(!Overflow, Range.contains(APInt(8, V)));
1181 }
1182 }
1183}
1184
1185TEST(ConstantRange, MakeGuaranteedNoWrapRegionMulSignedSingleValue) {
1186 typedef OverflowingBinaryOperator OBO;
1187
1188 for (int64_t I = std::numeric_limits<int8_t>::min();
1189 I <= std::numeric_limits<int8_t>::max(); I++) {
1190 auto Range = ConstantRange::makeGuaranteedNoWrapRegion(
1191 Instruction::Mul,
1192 ConstantRange(APInt(8, I, /*isSigned=*/true),
1193 APInt(8, I + 1, /*isSigned=*/true)),
1194 OBO::NoSignedWrap);
1195
1196 for (int64_t V = std::numeric_limits<int8_t>::min();
1197 V <= std::numeric_limits<int8_t>::max(); V++) {
1198 bool Overflow;
1199 (void)APInt(8, I, /*isSigned=*/true)
1200 .smul_ov(APInt(8, V, /*isSigned=*/true), Overflow);
1201 EXPECT_EQ(!Overflow, Range.contains(APInt(8, V, /*isSigned=*/true)));
1202 }
1203 }
1204}
1205
1206TEST(ConstantRange, MakeGuaranteedNoWrapRegionMulUnsignedAndSignedSingleValue) {
1207 typedef OverflowingBinaryOperator OBO;
1208
1209 for (uint64_t I = std::numeric_limits<uint8_t>::min();
1210 I <= std::numeric_limits<uint8_t>::max(); I++) {
1211 auto Range = ConstantRange::makeGuaranteedNoWrapRegion(
1212 Instruction::Mul, ConstantRange(APInt(8, I), APInt(8, I + 1)),
1213 OBO::NoUnsignedWrap | OBO::NoSignedWrap);
1214
1215 for (uint64_t V = std::numeric_limits<uint8_t>::min();
1216 V <= std::numeric_limits<uint8_t>::max(); V++) {
1217 bool UOverflow;
1218 (void)APInt(8, I).umul_ov(APInt(8, V), UOverflow);
1219 bool SOverflow;
1220 (void)APInt(8, I).smul_ov(APInt(8, V), SOverflow);
1221 EXPECT_EQ(!(UOverflow || SOverflow), Range.contains(APInt(8, V)));
1222 }
1223 }
1224}
1225
1226TEST(ConstantRange, MakeGuaranteedNoWrapRegionMulUnsignedRange) {
1227 typedef OverflowingBinaryOperator OBO;
1228
1229 for (uint64_t Lo = std::numeric_limits<uint8_t>::min();
1230 Lo <= std::numeric_limits<uint8_t>::max(); Lo++) {
1231 for (uint64_t Hi = Lo; Hi <= std::numeric_limits<uint8_t>::max(); Hi++) {
1232 EXPECT_EQ(
1233 ConstantRange::makeGuaranteedNoWrapRegion(
1234 Instruction::Mul, ConstantRange(APInt(8, Lo), APInt(8, Hi + 1)),
1235 OBO::NoUnsignedWrap),
1236 ConstantRange::makeGuaranteedNoWrapRegion(
1237 Instruction::Mul, ConstantRange(APInt(8, Hi), APInt(8, Hi + 1)),
1238 OBO::NoUnsignedWrap));
1239 }
1240 }
1241}
1242
1243TEST(ConstantRange, MakeGuaranteedNoWrapRegionMulSignedRange) {
1244 typedef OverflowingBinaryOperator OBO;
1245
1246 int Lo = -12, Hi = 16;
1247 auto Range = ConstantRange::makeGuaranteedNoWrapRegion(
1248 Instruction::Mul,
1249 ConstantRange(APInt(8, Lo, /*isSigned=*/true),
1250 APInt(8, Hi + 1, /*isSigned=*/true)),
1251 OBO::NoSignedWrap);
1252
1253 for (int64_t V = std::numeric_limits<int8_t>::min();
1254 V <= std::numeric_limits<int8_t>::max(); V++) {
1255 bool AnyOverflow = false;
1256 for (int64_t I = Lo; I <= Hi; I++) {
1257 bool Overflow;
1258 (void)APInt(8, I, /*isSigned=*/true)
1259 .smul_ov(APInt(8, V, /*isSigned=*/true), Overflow);
1260 AnyOverflow |= Overflow;
1261 }
1262 EXPECT_EQ(!AnyOverflow, Range.contains(APInt(8, V, /*isSigned=*/true)));
1263 }
1264}
1265
Nikita Popove3d3e862019-03-15 17:29:05 +00001266#define EXPECT_MAY_OVERFLOW(op) \
1267 EXPECT_EQ(ConstantRange::OverflowResult::MayOverflow, (op))
1268#define EXPECT_ALWAYS_OVERFLOWS(op) \
1269 EXPECT_EQ(ConstantRange::OverflowResult::AlwaysOverflows, (op))
1270#define EXPECT_NEVER_OVERFLOWS(op) \
1271 EXPECT_EQ(ConstantRange::OverflowResult::NeverOverflows, (op))
1272
1273TEST_F(ConstantRangeTest, UnsignedAddOverflow) {
1274 // Ill-defined - may overflow is a conservative result.
1275 EXPECT_MAY_OVERFLOW(Some.unsignedAddMayOverflow(Empty));
1276 EXPECT_MAY_OVERFLOW(Empty.unsignedAddMayOverflow(Some));
1277
1278 // Never overflow despite one full/wrap set.
1279 ConstantRange Zero(APInt::getNullValue(16));
1280 EXPECT_NEVER_OVERFLOWS(Full.unsignedAddMayOverflow(Zero));
1281 EXPECT_NEVER_OVERFLOWS(Wrap.unsignedAddMayOverflow(Zero));
1282 EXPECT_NEVER_OVERFLOWS(Zero.unsignedAddMayOverflow(Full));
1283 EXPECT_NEVER_OVERFLOWS(Zero.unsignedAddMayOverflow(Wrap));
1284
1285 // But usually full/wrap always may overflow.
1286 EXPECT_MAY_OVERFLOW(Full.unsignedAddMayOverflow(One));
1287 EXPECT_MAY_OVERFLOW(Wrap.unsignedAddMayOverflow(One));
1288 EXPECT_MAY_OVERFLOW(One.unsignedAddMayOverflow(Full));
1289 EXPECT_MAY_OVERFLOW(One.unsignedAddMayOverflow(Wrap));
1290
1291 ConstantRange A(APInt(16, 0xfd00), APInt(16, 0xfe00));
1292 ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));
1293 ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));
1294 EXPECT_NEVER_OVERFLOWS(A.unsignedAddMayOverflow(B1));
1295 EXPECT_MAY_OVERFLOW(A.unsignedAddMayOverflow(B2));
1296 EXPECT_NEVER_OVERFLOWS(B1.unsignedAddMayOverflow(A));
1297 EXPECT_MAY_OVERFLOW(B2.unsignedAddMayOverflow(A));
1298
1299 ConstantRange C1(APInt(16, 0x0299), APInt(16, 0x0400));
1300 ConstantRange C2(APInt(16, 0x0300), APInt(16, 0x0400));
1301 EXPECT_MAY_OVERFLOW(A.unsignedAddMayOverflow(C1));
1302 EXPECT_ALWAYS_OVERFLOWS(A.unsignedAddMayOverflow(C2));
1303 EXPECT_MAY_OVERFLOW(C1.unsignedAddMayOverflow(A));
1304 EXPECT_ALWAYS_OVERFLOWS(C2.unsignedAddMayOverflow(A));
1305}
1306
1307TEST_F(ConstantRangeTest, UnsignedSubOverflow) {
1308 // Ill-defined - may overflow is a conservative result.
1309 EXPECT_MAY_OVERFLOW(Some.unsignedSubMayOverflow(Empty));
1310 EXPECT_MAY_OVERFLOW(Empty.unsignedSubMayOverflow(Some));
1311
1312 // Never overflow despite one full/wrap set.
1313 ConstantRange Zero(APInt::getNullValue(16));
1314 ConstantRange Max(APInt::getAllOnesValue(16));
1315 EXPECT_NEVER_OVERFLOWS(Full.unsignedSubMayOverflow(Zero));
1316 EXPECT_NEVER_OVERFLOWS(Wrap.unsignedSubMayOverflow(Zero));
1317 EXPECT_NEVER_OVERFLOWS(Max.unsignedSubMayOverflow(Full));
1318 EXPECT_NEVER_OVERFLOWS(Max.unsignedSubMayOverflow(Wrap));
1319
1320 // But usually full/wrap always may overflow.
1321 EXPECT_MAY_OVERFLOW(Full.unsignedSubMayOverflow(One));
1322 EXPECT_MAY_OVERFLOW(Wrap.unsignedSubMayOverflow(One));
1323 EXPECT_MAY_OVERFLOW(One.unsignedSubMayOverflow(Full));
1324 EXPECT_MAY_OVERFLOW(One.unsignedSubMayOverflow(Wrap));
1325
1326 ConstantRange A(APInt(16, 0x0000), APInt(16, 0x0100));
1327 ConstantRange B(APInt(16, 0x0100), APInt(16, 0x0200));
1328 EXPECT_NEVER_OVERFLOWS(B.unsignedSubMayOverflow(A));
1329 EXPECT_ALWAYS_OVERFLOWS(A.unsignedSubMayOverflow(B));
1330
1331 ConstantRange A1(APInt(16, 0x0000), APInt(16, 0x0101));
1332 ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));
1333 EXPECT_NEVER_OVERFLOWS(B1.unsignedSubMayOverflow(A1));
1334 EXPECT_MAY_OVERFLOW(A1.unsignedSubMayOverflow(B1));
1335
1336 ConstantRange A2(APInt(16, 0x0000), APInt(16, 0x0102));
1337 ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));
1338 EXPECT_MAY_OVERFLOW(B2.unsignedSubMayOverflow(A2));
1339 EXPECT_MAY_OVERFLOW(A2.unsignedSubMayOverflow(B2));
1340}
1341
1342TEST_F(ConstantRangeTest, SignedAddOverflow) {
1343 // Ill-defined - may overflow is a conservative result.
1344 EXPECT_MAY_OVERFLOW(Some.signedAddMayOverflow(Empty));
1345 EXPECT_MAY_OVERFLOW(Empty.signedAddMayOverflow(Some));
1346
1347 // Never overflow despite one full/wrap set.
1348 ConstantRange Zero(APInt::getNullValue(16));
1349 EXPECT_NEVER_OVERFLOWS(Full.signedAddMayOverflow(Zero));
1350 EXPECT_NEVER_OVERFLOWS(Wrap.signedAddMayOverflow(Zero));
1351 EXPECT_NEVER_OVERFLOWS(Zero.signedAddMayOverflow(Full));
1352 EXPECT_NEVER_OVERFLOWS(Zero.signedAddMayOverflow(Wrap));
1353
1354 // But usually full/wrap always may overflow.
1355 EXPECT_MAY_OVERFLOW(Full.signedAddMayOverflow(One));
1356 EXPECT_MAY_OVERFLOW(Wrap.signedAddMayOverflow(One));
1357 EXPECT_MAY_OVERFLOW(One.signedAddMayOverflow(Full));
1358 EXPECT_MAY_OVERFLOW(One.signedAddMayOverflow(Wrap));
1359
1360 ConstantRange A(APInt(16, 0x7d00), APInt(16, 0x7e00));
1361 ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));
1362 ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));
1363 EXPECT_NEVER_OVERFLOWS(A.signedAddMayOverflow(B1));
1364 EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B2));
1365 ConstantRange B3(APInt(16, 0x8000), APInt(16, 0x0201));
1366 ConstantRange B4(APInt(16, 0x8000), APInt(16, 0x0202));
1367 EXPECT_NEVER_OVERFLOWS(A.signedAddMayOverflow(B3));
1368 EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B4));
1369 ConstantRange B5(APInt(16, 0x0299), APInt(16, 0x0400));
1370 ConstantRange B6(APInt(16, 0x0300), APInt(16, 0x0400));
1371 EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B5));
1372 EXPECT_ALWAYS_OVERFLOWS(A.signedAddMayOverflow(B6));
1373
1374 ConstantRange C(APInt(16, 0x8200), APInt(16, 0x8300));
1375 ConstantRange D1(APInt(16, 0xfe00), APInt(16, 0xff00));
1376 ConstantRange D2(APInt(16, 0xfd99), APInt(16, 0xff00));
1377 EXPECT_NEVER_OVERFLOWS(C.signedAddMayOverflow(D1));
1378 EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D2));
1379 ConstantRange D3(APInt(16, 0xfe00), APInt(16, 0x8000));
1380 ConstantRange D4(APInt(16, 0xfd99), APInt(16, 0x8000));
1381 EXPECT_NEVER_OVERFLOWS(C.signedAddMayOverflow(D3));
1382 EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D4));
1383 ConstantRange D5(APInt(16, 0xfc00), APInt(16, 0xfd02));
1384 ConstantRange D6(APInt(16, 0xfc00), APInt(16, 0xfd01));
1385 EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D5));
1386 EXPECT_ALWAYS_OVERFLOWS(C.signedAddMayOverflow(D6));
1387
1388 ConstantRange E(APInt(16, 0xff00), APInt(16, 0x0100));
1389 EXPECT_NEVER_OVERFLOWS(E.signedAddMayOverflow(E));
1390 ConstantRange F(APInt(16, 0xf000), APInt(16, 0x7000));
1391 EXPECT_MAY_OVERFLOW(F.signedAddMayOverflow(F));
1392}
1393
1394TEST_F(ConstantRangeTest, SignedSubOverflow) {
1395 // Ill-defined - may overflow is a conservative result.
1396 EXPECT_MAY_OVERFLOW(Some.signedSubMayOverflow(Empty));
1397 EXPECT_MAY_OVERFLOW(Empty.signedSubMayOverflow(Some));
1398
1399 // Never overflow despite one full/wrap set.
1400 ConstantRange Zero(APInt::getNullValue(16));
1401 EXPECT_NEVER_OVERFLOWS(Full.signedSubMayOverflow(Zero));
1402 EXPECT_NEVER_OVERFLOWS(Wrap.signedSubMayOverflow(Zero));
1403
1404 // But usually full/wrap always may overflow.
1405 EXPECT_MAY_OVERFLOW(Full.signedSubMayOverflow(One));
1406 EXPECT_MAY_OVERFLOW(Wrap.signedSubMayOverflow(One));
1407 EXPECT_MAY_OVERFLOW(One.signedSubMayOverflow(Full));
1408 EXPECT_MAY_OVERFLOW(One.signedSubMayOverflow(Wrap));
1409
1410 ConstantRange A(APInt(16, 0x7d00), APInt(16, 0x7e00));
1411 ConstantRange B1(APInt(16, 0xfe00), APInt(16, 0xff00));
1412 ConstantRange B2(APInt(16, 0xfd99), APInt(16, 0xff00));
1413 EXPECT_NEVER_OVERFLOWS(A.signedSubMayOverflow(B1));
1414 EXPECT_MAY_OVERFLOW(A.signedSubMayOverflow(B2));
1415 ConstantRange B3(APInt(16, 0xfc00), APInt(16, 0xfd02));
1416 ConstantRange B4(APInt(16, 0xfc00), APInt(16, 0xfd01));
1417 EXPECT_MAY_OVERFLOW(A.signedSubMayOverflow(B3));
1418 EXPECT_ALWAYS_OVERFLOWS(A.signedSubMayOverflow(B4));
1419
1420 ConstantRange C(APInt(16, 0x8200), APInt(16, 0x8300));
1421 ConstantRange D1(APInt(16, 0x0100), APInt(16, 0x0201));
1422 ConstantRange D2(APInt(16, 0x0100), APInt(16, 0x0202));
1423 EXPECT_NEVER_OVERFLOWS(C.signedSubMayOverflow(D1));
1424 EXPECT_MAY_OVERFLOW(C.signedSubMayOverflow(D2));
1425 ConstantRange D3(APInt(16, 0x0299), APInt(16, 0x0400));
1426 ConstantRange D4(APInt(16, 0x0300), APInt(16, 0x0400));
1427 EXPECT_MAY_OVERFLOW(C.signedSubMayOverflow(D3));
1428 EXPECT_ALWAYS_OVERFLOWS(C.signedSubMayOverflow(D4));
1429
1430 ConstantRange E(APInt(16, 0xff00), APInt(16, 0x0100));
1431 EXPECT_NEVER_OVERFLOWS(E.signedSubMayOverflow(E));
1432 ConstantRange F(APInt(16, 0xf000), APInt(16, 0x7001));
1433 EXPECT_MAY_OVERFLOW(F.signedSubMayOverflow(F));
1434}
1435
1436template<typename Fn1, typename Fn2>
1437static void TestOverflowExhaustive(Fn1 OverflowFn, Fn2 MayOverflowFn) {
1438 // Constant range overflow checks are tested exhaustively on 4-bit numbers.
1439 unsigned Bits = 4;
Nikita Popovee9f2ae2019-03-27 20:18:51 +00001440 EnumerateTwoConstantRanges(Bits,
1441 [=](const ConstantRange &CR1, const ConstantRange &CR2) {
1442 unsigned Size1 = CR1.getSetSize().getLimitedValue();
1443 unsigned Size2 = CR2.getSetSize().getLimitedValue();
Nikita Popove3d3e862019-03-15 17:29:05 +00001444
Nikita Popovee9f2ae2019-03-27 20:18:51 +00001445 // Loop over all N1 in CR1 and N2 in CR2 and check whether any of the
1446 // operations have overflow / have no overflow. These loops are based
1447 // on Size1/Size2 to properly handle empty/full ranges.
1448 bool RangeHasOverflow = false;
1449 bool RangeHasNoOverflow = false;
1450 APInt N1 = CR1.getLower();
1451 for (unsigned I1 = 0; I1 < Size1; ++I1, ++N1) {
1452 APInt N2 = CR2.getLower();
1453 for (unsigned I2 = 0; I2 < Size2; ++I2, ++N2) {
1454 assert(CR1.contains(N1));
1455 assert(CR2.contains(N2));
Nikita Popove3d3e862019-03-15 17:29:05 +00001456
Nikita Popovee9f2ae2019-03-27 20:18:51 +00001457 if (OverflowFn(N1, N2))
1458 RangeHasOverflow = true;
1459 else
1460 RangeHasNoOverflow = true;
Nikita Popove3d3e862019-03-15 17:29:05 +00001461 }
1462 }
Nikita Popovee9f2ae2019-03-27 20:18:51 +00001463
1464 ConstantRange::OverflowResult OR = MayOverflowFn(CR1, CR2);
1465 switch (OR) {
1466 case ConstantRange::OverflowResult::AlwaysOverflows:
1467 EXPECT_TRUE(RangeHasOverflow);
1468 EXPECT_FALSE(RangeHasNoOverflow);
1469 break;
1470 case ConstantRange::OverflowResult::NeverOverflows:
1471 EXPECT_FALSE(RangeHasOverflow);
1472 EXPECT_TRUE(RangeHasNoOverflow);
1473 break;
1474 case ConstantRange::OverflowResult::MayOverflow:
1475 // We return MayOverflow for empty sets as a conservative result,
1476 // but of course neither the RangeHasOverflow nor the
1477 // RangeHasNoOverflow flags will be set.
1478 if (CR1.isEmptySet() || CR2.isEmptySet())
1479 break;
1480
1481 EXPECT_TRUE(RangeHasOverflow);
1482 EXPECT_TRUE(RangeHasNoOverflow);
1483 break;
1484 }
1485 });
Nikita Popove3d3e862019-03-15 17:29:05 +00001486}
1487
1488TEST_F(ConstantRangeTest, UnsignedAddOverflowExhautive) {
1489 TestOverflowExhaustive(
1490 [](const APInt &N1, const APInt &N2) {
1491 bool Overflow;
Nikita Popov8d92b8e2019-03-15 18:08:06 +00001492 (void) N1.uadd_ov(N2, Overflow);
Nikita Popove3d3e862019-03-15 17:29:05 +00001493 return Overflow;
1494 },
1495 [](const ConstantRange &CR1, const ConstantRange &CR2) {
1496 return CR1.unsignedAddMayOverflow(CR2);
1497 });
1498}
1499
1500TEST_F(ConstantRangeTest, UnsignedSubOverflowExhautive) {
1501 TestOverflowExhaustive(
1502 [](const APInt &N1, const APInt &N2) {
1503 bool Overflow;
Nikita Popov8d92b8e2019-03-15 18:08:06 +00001504 (void) N1.usub_ov(N2, Overflow);
Nikita Popove3d3e862019-03-15 17:29:05 +00001505 return Overflow;
1506 },
1507 [](const ConstantRange &CR1, const ConstantRange &CR2) {
1508 return CR1.unsignedSubMayOverflow(CR2);
1509 });
1510}
1511
1512TEST_F(ConstantRangeTest, SignedAddOverflowExhautive) {
1513 TestOverflowExhaustive(
1514 [](const APInt &N1, const APInt &N2) {
1515 bool Overflow;
Nikita Popov8d92b8e2019-03-15 18:08:06 +00001516 (void) N1.sadd_ov(N2, Overflow);
Nikita Popove3d3e862019-03-15 17:29:05 +00001517 return Overflow;
1518 },
1519 [](const ConstantRange &CR1, const ConstantRange &CR2) {
1520 return CR1.signedAddMayOverflow(CR2);
1521 });
1522}
1523
1524TEST_F(ConstantRangeTest, SignedSubOverflowExhautive) {
1525 TestOverflowExhaustive(
1526 [](const APInt &N1, const APInt &N2) {
1527 bool Overflow;
Nikita Popov8d92b8e2019-03-15 18:08:06 +00001528 (void) N1.ssub_ov(N2, Overflow);
Nikita Popove3d3e862019-03-15 17:29:05 +00001529 return Overflow;
1530 },
1531 [](const ConstantRange &CR1, const ConstantRange &CR2) {
1532 return CR1.signedSubMayOverflow(CR2);
1533 });
1534}
1535
Nikita Popovef2d9792019-03-17 20:24:02 +00001536TEST_F(ConstantRangeTest, FromKnownBits) {
1537 KnownBits Unknown(16);
1538 EXPECT_EQ(Full, ConstantRange::fromKnownBits(Unknown, /*signed*/false));
1539 EXPECT_EQ(Full, ConstantRange::fromKnownBits(Unknown, /*signed*/true));
1540
1541 // .10..01. -> unsigned 01000010 (66) to 11011011 (219)
1542 // -> signed 11000010 (194) to 01011011 (91)
1543 KnownBits Known(8);
1544 Known.Zero = 36;
1545 Known.One = 66;
1546 ConstantRange Unsigned(APInt(8, 66), APInt(8, 219 + 1));
1547 ConstantRange Signed(APInt(8, 194), APInt(8, 91 + 1));
1548 EXPECT_EQ(Unsigned, ConstantRange::fromKnownBits(Known, /*signed*/false));
1549 EXPECT_EQ(Signed, ConstantRange::fromKnownBits(Known, /*signed*/true));
1550
1551 // 1.10.10. -> 10100100 (164) to 11101101 (237)
1552 Known.Zero = 18;
1553 Known.One = 164;
1554 ConstantRange CR1(APInt(8, 164), APInt(8, 237 + 1));
1555 EXPECT_EQ(CR1, ConstantRange::fromKnownBits(Known, /*signed*/false));
1556 EXPECT_EQ(CR1, ConstantRange::fromKnownBits(Known, /*signed*/true));
1557
1558 // 01.0.1.0 -> 01000100 (68) to 01101110 (110)
1559 Known.Zero = 145;
1560 Known.One = 68;
1561 ConstantRange CR2(APInt(8, 68), APInt(8, 110 + 1));
1562 EXPECT_EQ(CR2, ConstantRange::fromKnownBits(Known, /*signed*/false));
1563 EXPECT_EQ(CR2, ConstantRange::fromKnownBits(Known, /*signed*/true));
1564}
1565
1566TEST_F(ConstantRangeTest, FromKnownBitsExhaustive) {
1567 unsigned Bits = 4;
1568 unsigned Max = 1 << Bits;
1569 KnownBits Known(Bits);
1570 for (unsigned Zero = 0; Zero < Max; ++Zero) {
1571 for (unsigned One = 0; One < Max; ++One) {
1572 Known.Zero = Zero;
1573 Known.One = One;
1574 if (Known.hasConflict() || Known.isUnknown())
1575 continue;
1576
1577 APInt MinUnsigned = APInt::getMaxValue(Bits);
1578 APInt MaxUnsigned = APInt::getMinValue(Bits);
1579 APInt MinSigned = APInt::getSignedMaxValue(Bits);
1580 APInt MaxSigned = APInt::getSignedMinValue(Bits);
1581 for (unsigned N = 0; N < Max; ++N) {
1582 APInt Num(Bits, N);
1583 if ((Num & Known.Zero) != 0 || (~Num & Known.One) != 0)
1584 continue;
1585
1586 if (Num.ult(MinUnsigned)) MinUnsigned = Num;
1587 if (Num.ugt(MaxUnsigned)) MaxUnsigned = Num;
1588 if (Num.slt(MinSigned)) MinSigned = Num;
1589 if (Num.sgt(MaxSigned)) MaxSigned = Num;
1590 }
1591
1592 ConstantRange UnsignedCR(MinUnsigned, MaxUnsigned + 1);
1593 ConstantRange SignedCR(MinSigned, MaxSigned + 1);
1594 EXPECT_EQ(UnsignedCR, ConstantRange::fromKnownBits(Known, false));
1595 EXPECT_EQ(SignedCR, ConstantRange::fromKnownBits(Known, true));
1596 }
1597 }
1598}
1599
Dan Gohman5035fbf2009-07-09 22:07:27 +00001600} // anonymous namespace