Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / geps-precondition-overflow-check.ll
blob08b25c6065aace6d5299d633466add3a50c99454
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 ; Tests for cases with explicit checks that %ptr + x >= %ptr. The information can
5 ; be used to determine that certain GEPs do not overflow.
7 define i1 @overflow_check_1(ptr %dst) {
8 ; CHECK-LABEL: @overflow_check_1(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    [[DST_5:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 5
11 ; CHECK-NEXT:    [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
12 ; CHECK-NEXT:    br i1 [[DST_5_UGE]], label [[THEN:%.*]], label [[ELSE:%.*]]
13 ; CHECK:       then:
14 ; CHECK-NEXT:    [[DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4
15 ; CHECK-NEXT:    [[TRUE_DST_4_UGE:%.*]] = icmp uge ptr [[DST_4]], [[DST]]
16 ; CHECK-NEXT:    ret i1 [[TRUE_DST_4_UGE]]
17 ; CHECK:       else:
18 ; CHECK-NEXT:    ret i1 false
20 entry:
21   %dst.5 = getelementptr i32, ptr %dst, i64 5
22   %dst.5.uge = icmp uge ptr %dst.5, %dst
23   br i1 %dst.5.uge, label %then, label %else
25 then:
26   %dst.4 = getelementptr i32, ptr %dst, i64 4
27   %true.dst.4.uge = icmp uge ptr %dst.4, %dst
28   ret i1 %true.dst.4.uge
30 else:
31   ret i1 0
34 define i1 @overflow_check_2_and(ptr %dst) {
35 ; CHECK-LABEL: @overflow_check_2_and(
36 ; CHECK-NEXT:  entry:
37 ; CHECK-NEXT:    [[DST_5:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 5
38 ; CHECK-NEXT:    [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
39 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[DST_5_UGE]]
40 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
41 ; CHECK:       then:
42 ; CHECK-NEXT:    [[DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4
43 ; CHECK-NEXT:    [[TRUE_DST_4_UGE:%.*]] = icmp uge ptr [[DST_4]], [[DST]]
44 ; CHECK-NEXT:    ret i1 [[TRUE_DST_4_UGE]]
45 ; CHECK:       else:
46 ; CHECK-NEXT:    ret i1 true
48 entry:
49   %dst.5 = getelementptr i32, ptr %dst, i64 5
50   %dst.5.uge = icmp uge ptr %dst.5, %dst
51   %and = and i1 %dst.5.uge, %dst.5.uge
52   br i1 %and, label %then, label %else
54 then:
55   %dst.4 = getelementptr i32, ptr %dst, i64 4
56   %true.dst.4.uge = icmp uge ptr %dst.4, %dst
57   ret i1 %true.dst.4.uge
59 else:
60   ret i1 true
63 define i1 @overflow_check_3_and(ptr %dst) {
64 ; CHECK-LABEL: @overflow_check_3_and(
65 ; CHECK-NEXT:  entry:
66 ; CHECK-NEXT:    [[DST_5:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 5
67 ; CHECK-NEXT:    [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
68 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[DST_5_UGE]]
69 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
70 ; CHECK:       then:
71 ; CHECK-NEXT:    [[DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4
72 ; CHECK-NEXT:    [[DST_4_UGE:%.*]] = icmp uge ptr [[DST_4]], [[DST]]
73 ; CHECK-NEXT:    ret i1 [[DST_4_UGE]]
74 ; CHECK:       else:
75 ; CHECK-NEXT:    [[ELSE_DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4
76 ; CHECK-NEXT:    [[ELSE_DST_4_UGE:%.*]] = icmp uge ptr [[ELSE_DST_4]], [[DST]]
77 ; CHECK-NEXT:    ret i1 [[ELSE_DST_4_UGE]]
79 entry:
80   %dst.5 = getelementptr i32, ptr %dst, i64 5
81   %dst.5.uge = icmp uge ptr %dst.5, %dst
82   %and = and i1 %dst.5.uge, %dst.5.uge
83   br i1 %and, label %then, label %else
85 then:
86   %dst.4 = getelementptr i32, ptr %dst, i64 4
87   %dst.4.uge = icmp uge ptr %dst.4, %dst
88   ret i1 %dst.4.uge
90 else:
91   %else.dst.4 = getelementptr i32, ptr %dst, i64 4
92   %else.dst.4.uge = icmp uge ptr %else.dst.4, %dst
93   ret i1 %else.dst.4.uge
96 define i1 @overflow_check_4_and(ptr %dst) {
97 ; CHECK-LABEL: @overflow_check_4_and(
98 ; CHECK-NEXT:  entry:
99 ; CHECK-NEXT:    [[DST_5:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 5
100 ; CHECK-NEXT:    [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
101 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[DST_5_UGE]]
102 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
103 ; CHECK:       then:
104 ; CHECK-NEXT:    [[DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4
105 ; CHECK-NEXT:    [[TRUE_DST_4_UGE:%.*]] = icmp uge ptr [[DST_4]], [[DST]]
106 ; CHECK-NEXT:    [[DST_5_2:%.*]] = getelementptr i32, ptr [[DST]], i64 5
107 ; CHECK-NEXT:    [[TRUE_DST_5_UGE:%.*]] = icmp uge ptr [[DST_5_2]], [[DST]]
108 ; CHECK-NEXT:    [[RES_0:%.*]] = xor i1 [[TRUE_DST_4_UGE]], [[TRUE_DST_5_UGE]]
109 ; CHECK-NEXT:    [[DST_6:%.*]] = getelementptr i32, ptr [[DST]], i64 6
110 ; CHECK-NEXT:    [[C_DST_6_UGE:%.*]] = icmp uge ptr [[DST_6]], [[DST]]
111 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[RES_0]], [[C_DST_6_UGE]]
112 ; CHECK-NEXT:    ret i1 [[RES_1]]
113 ; CHECK:       else:
114 ; CHECK-NEXT:    [[ELSE_DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4
115 ; CHECK-NEXT:    [[ELSE_DST_4_UGE:%.*]] = icmp uge ptr [[ELSE_DST_4]], [[DST]]
116 ; CHECK-NEXT:    [[ELSE_DST_6:%.*]] = getelementptr i32, ptr [[DST]], i64 6
117 ; CHECK-NEXT:    [[ELSE_DST_6_UGE:%.*]] = icmp uge ptr [[ELSE_DST_6]], [[DST]]
118 ; CHECK-NEXT:    [[ELSE_RES_0:%.*]] = xor i1 [[ELSE_DST_4_UGE]], [[ELSE_DST_6_UGE]]
119 ; CHECK-NEXT:    ret i1 [[ELSE_RES_0]]
121 entry:
122   %dst.5 = getelementptr i32, ptr %dst, i64 5
123   %dst.5.uge = icmp uge ptr %dst.5, %dst
124   %and = and i1 %dst.5.uge, %dst.5.uge
125   br i1 %and, label %then, label %else
127 then:
128   %dst.4 = getelementptr i32, ptr %dst, i64 4
129   %true.dst.4.uge = icmp uge ptr %dst.4, %dst
130   %dst.5.2 = getelementptr i32, ptr %dst, i64 5
131   %true.dst.5.uge = icmp uge ptr %dst.5.2, %dst
132   %res.0 = xor i1 %true.dst.4.uge, %true.dst.5.uge
134   %dst.6 = getelementptr i32, ptr %dst, i64 6
135   %c.dst.6.uge = icmp uge ptr %dst.6, %dst
136   %res.1 = xor i1 %res.0, %c.dst.6.uge
138   ret i1 %res.1
140 else:
141   %else.dst.4 = getelementptr i32, ptr %dst, i64 4
142   %else.dst.4.uge = icmp uge ptr %else.dst.4, %dst
143   %else.dst.6 = getelementptr i32, ptr %dst, i64 6
144   %else.dst.6.uge = icmp uge ptr %else.dst.6, %dst
145   %else.res.0 = xor i1 %else.dst.4.uge, %else.dst.6.uge
147   ret i1 %else.res.0
150 define i1 @overflow_check_3_or(ptr %dst) {
151 ; CHECK-LABEL: @overflow_check_3_or(
152 ; CHECK-NEXT:  entry:
153 ; CHECK-NEXT:    [[DST_5:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 5
154 ; CHECK-NEXT:    [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
155 ; CHECK-NEXT:    [[OR:%.*]] = or i1 false, [[DST_5_UGE]]
156 ; CHECK-NEXT:    br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
157 ; CHECK:       then:
158 ; CHECK-NEXT:    [[DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4
159 ; CHECK-NEXT:    [[TRUE_DST_4_UGE:%.*]] = icmp uge ptr [[DST_4]], [[DST]]
160 ; CHECK-NEXT:    ret i1 [[TRUE_DST_4_UGE]]
161 ; CHECK:       else:
162 ; CHECK-NEXT:    ret i1 false
164 entry:
165   %dst.5 = getelementptr i32, ptr %dst, i64 5
166   %dst.5.uge = icmp uge ptr %dst.5, %dst
167   %or = or i1 %dst.5.uge, %dst.5.uge
168   br i1 %or, label %then, label %else
170 then:
171   %dst.4 = getelementptr i32, ptr %dst, i64 4
172   %true.dst.4.uge = icmp uge ptr %dst.4, %dst
173   ret i1 %true.dst.4.uge
175 else:
176   ret i1 0
179 define i1 @upper_and_lower_checks_1(ptr %dst, i32 %n) {
180 ; CHECK-LABEL: @upper_and_lower_checks_1(
181 ; CHECK-NEXT:  entry:
182 ; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64
183 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST:%.*]], i64 [[N_EXT]]
184 ; CHECK-NEXT:    [[DST_5:%.*]] = getelementptr i32, ptr [[DST]], i64 5
185 ; CHECK-NEXT:    [[DST_5_ULT:%.*]] = icmp ult ptr [[DST_5]], [[UPPER]]
186 ; CHECK-NEXT:    [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
187 ; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[DST_5_ULT]], [[DST_5_UGE]]
188 ; CHECK-NEXT:    br i1 [[AND_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
189 ; CHECK:       then:
190 ; CHECK-NEXT:    [[DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4
191 ; CHECK-NEXT:    [[TRUE_DST_4_ULT:%.*]] = icmp ult ptr [[DST_4]], [[UPPER]]
192 ; CHECK-NEXT:    [[TRUE_DST_4_UGE:%.*]] = icmp uge ptr [[DST_4]], [[DST]]
193 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[TRUE_DST_4_ULT]], [[TRUE_DST_4_UGE]]
194 ; CHECK-NEXT:    ret i1 [[AND]]
195 ; CHECK:       else:
196 ; CHECK-NEXT:    ret i1 false
198 entry:
199   %n.ext = zext i32 %n to i64
200   %upper = getelementptr inbounds i32, ptr %dst, i64 %n.ext
201   %dst.5 = getelementptr i32, ptr %dst, i64 5
202   %dst.5.ult = icmp ult ptr %dst.5, %upper
203   %dst.5.uge = icmp uge ptr %dst.5, %dst
204   %and.1 = and i1 %dst.5.ult, %dst.5.uge
205   br i1 %and.1, label %then, label %else
207 then:
208   %dst.4 = getelementptr i32, ptr %dst, i64 4
209   %true.dst.4.ult = icmp ult ptr %dst.4, %upper
210   %true.dst.4.uge = icmp uge ptr %dst.4, %dst
211   %and = and i1 %true.dst.4.ult, %true.dst.4.uge
212   ret i1 %and
214 else:
215   ret i1 0
218 define i1 @upper_and_lower_checks_2_dst6(ptr %dst, i32 %n) {
219 ; CHECK-LABEL: @upper_and_lower_checks_2_dst6(
220 ; CHECK-NEXT:  entry:
221 ; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64
222 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST:%.*]], i64 [[N_EXT]]
223 ; CHECK-NEXT:    [[DST_5:%.*]] = getelementptr i32, ptr [[DST]], i64 5
224 ; CHECK-NEXT:    [[DST_5_ULT:%.*]] = icmp ult ptr [[DST_5]], [[UPPER]]
225 ; CHECK-NEXT:    [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
226 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[DST_5_ULT]], [[DST_5_UGE]]
227 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
228 ; CHECK:       then:
229 ; CHECK-NEXT:    [[DST_6:%.*]] = getelementptr i32, ptr [[DST]], i64 6
230 ; CHECK-NEXT:    [[C_DST_6_ULT:%.*]] = icmp ult ptr [[DST_6]], [[UPPER]]
231 ; CHECK-NEXT:    [[TRUE_DST_6_UGE:%.*]] = icmp uge ptr [[DST_6]], [[DST]]
232 ; CHECK-NEXT:    [[RES:%.*]] = and i1 [[C_DST_6_ULT]], [[TRUE_DST_6_UGE]]
233 ; CHECK-NEXT:    ret i1 [[RES]]
234 ; CHECK:       else:
235 ; CHECK-NEXT:    ret i1 false
237 entry:
238   %n.ext = zext i32 %n to i64
239   %upper = getelementptr inbounds i32, ptr %dst, i64 %n.ext
240   %dst.5 = getelementptr i32, ptr %dst, i64 5
241   %dst.5.ult = icmp ult ptr %dst.5, %upper
242   %dst.5.uge = icmp uge ptr %dst.5, %dst
243   %and = and i1 %dst.5.ult, %dst.5.uge
244   br i1 %and, label %then, label %else
246 then:
247   %dst.6 = getelementptr i32, ptr %dst, i64 6
248   %c.dst.6.ult = icmp ult ptr %dst.6, %upper
249   %true.dst.6.uge = icmp uge ptr %dst.6, %dst
250   %res = and i1 %c.dst.6.ult, %true.dst.6.uge
251   ret i1 %res
253 else:
254   ret i1 0
257 define i1 @upper_and_lower_checks_2_dst7(ptr %dst, i32 %n) {
258 ; CHECK-LABEL: @upper_and_lower_checks_2_dst7(
259 ; CHECK-NEXT:  entry:
260 ; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64
261 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST:%.*]], i64 [[N_EXT]]
262 ; CHECK-NEXT:    [[DST_5:%.*]] = getelementptr i32, ptr [[DST]], i64 5
263 ; CHECK-NEXT:    [[DST_5_ULT:%.*]] = icmp ult ptr [[DST_5]], [[UPPER]]
264 ; CHECK-NEXT:    [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
265 ; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[DST_5_ULT]], [[DST_5_UGE]]
266 ; CHECK-NEXT:    br i1 [[OR_COND]], label [[THEN:%.*]], label [[ELSE:%.*]]
267 ; CHECK:       then:
268 ; CHECK-NEXT:    [[DST_7:%.*]] = getelementptr i32, ptr [[DST]], i64 7
269 ; CHECK-NEXT:    [[C_DST_7_ULT:%.*]] = icmp ult ptr [[DST_7]], [[UPPER]]
270 ; CHECK-NEXT:    [[C_DST_7_UGE:%.*]] = icmp uge ptr [[DST_7]], [[DST]]
271 ; CHECK-NEXT:    [[RES:%.*]] = and i1 [[C_DST_7_ULT]], [[C_DST_7_UGE]]
272 ; CHECK-NEXT:    ret i1 [[RES]]
273 ; CHECK:       else:
274 ; CHECK-NEXT:    ret i1 false
276 entry:
277   %n.ext = zext i32 %n to i64
278   %upper = getelementptr inbounds i32, ptr %dst, i64 %n.ext
279   %dst.5 = getelementptr i32, ptr %dst, i64 5
280   %dst.5.ult = icmp ult ptr %dst.5, %upper
281   %dst.5.uge = icmp uge ptr %dst.5, %dst
282   %or.cond = and i1 %dst.5.ult, %dst.5.uge
283   br i1 %or.cond, label %then, label %else
285 then:
286   %dst.7 = getelementptr i32, ptr %dst, i64 7
287   %c.dst.7.ult = icmp ult ptr %dst.7, %upper
288   %c.dst.7.uge = icmp uge ptr %dst.7, %dst
289   %res = and i1 %c.dst.7.ult, %c.dst.7.uge
290   ret i1 %res
292 else:
293   ret i1 0
296 define i1 @upper_and_lower_checks_lt(ptr %dst, i32 %n) {
297 ; CHECK-LABEL: @upper_and_lower_checks_lt(
298 ; CHECK-NEXT:  entry:
299 ; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64
300 ; CHECK-NEXT:    [[DST_5:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 [[N_EXT]]
301 ; CHECK-NEXT:    [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
302 ; CHECK-NEXT:    [[N_EXT_UGE:%.*]] = icmp uge i64 [[N_EXT]], 3
303 ; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[DST_5_UGE]], [[N_EXT_UGE]]
304 ; CHECK-NEXT:    br i1 [[OR_COND]], label [[THEN:%.*]], label [[ELSE:%.*]]
305 ; CHECK:       then:
306 ; CHECK-NEXT:    [[DST_3:%.*]] = getelementptr i32, ptr [[DST]], i64 3
307 ; CHECK-NEXT:    [[TRUE_DST_3_UGE:%.*]] = icmp uge ptr [[DST_3]], [[DST]]
308 ; CHECK-NEXT:    [[DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4
309 ; CHECK-NEXT:    [[C_DST_4_UGE:%.*]] = icmp uge ptr [[DST_4]], [[DST]]
310 ; CHECK-NEXT:    [[RES_0:%.*]] = xor i1 [[TRUE_DST_3_UGE]], [[C_DST_4_UGE]]
311 ; CHECK-NEXT:    ret i1 [[RES_0]]
312 ; CHECK:       else:
313 ; CHECK-NEXT:    ret i1 false
315 entry:
316   %n.ext = zext i32 %n to i64
317   %dst.5 = getelementptr i32, ptr %dst, i64 %n.ext
318   %dst.5.uge = icmp uge ptr %dst.5, %dst
319   %n.ext.uge = icmp uge i64 %n.ext, 3
320   %or.cond = and i1 %dst.5.uge, %n.ext.uge
321   br i1 %or.cond, label %then, label %else
323 then:
324   %dst.3 = getelementptr i32, ptr %dst, i64 3
325   %true.dst.3.uge = icmp uge ptr %dst.3, %dst
326   %dst.4 = getelementptr i32, ptr %dst, i64 4
327   %c.dst.4.uge = icmp uge ptr %dst.4, %dst
328   %res.0 = xor i1 %true.dst.3.uge, %c.dst.4.uge
329   ret i1 %res.0
331 else:
332   ret i1 0