Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / geps-unsigned-predicates.ll
blob6b185bc623813297b7064e870dfe249f96b83997
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 define i32 @test.ult(ptr readonly %src, ptr readnone %min, ptr readnone %max) {
5 ; CHECK-LABEL: @test.ult(
6 ; CHECK-NEXT:  check.0.min:
7 ; CHECK-NEXT:    [[C_MIN_0:%.*]] = icmp ult ptr [[SRC:%.*]], [[MIN:%.*]]
8 ; CHECK-NEXT:    br i1 [[C_MIN_0]], label [[TRAP:%.*]], label [[CHECK_0_MAX:%.*]]
9 ; CHECK:       trap:
10 ; CHECK-NEXT:    ret i32 10
11 ; CHECK:       check.0.max:
12 ; CHECK-NEXT:    [[C_MAX_0:%.*]] = icmp ult ptr [[SRC]], [[MAX:%.*]]
13 ; CHECK-NEXT:    br i1 [[C_MAX_0]], label [[CHECK_3_MIN:%.*]], label [[TRAP]]
14 ; CHECK:       check.3.min:
15 ; CHECK-NEXT:    [[L0:%.*]] = load i32, ptr [[SRC]], align 4
16 ; CHECK-NEXT:    [[ADD_PTR_I36:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 3
17 ; CHECK-NEXT:    br i1 false, label [[TRAP]], label [[CHECK_3_MAX:%.*]]
18 ; CHECK:       check.3.max:
19 ; CHECK-NEXT:    [[C_3_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I36]], [[MAX]]
20 ; CHECK-NEXT:    br i1 [[C_3_MAX]], label [[CHECK_1_MIN:%.*]], label [[TRAP]]
21 ; CHECK:       check.1.min:
22 ; CHECK-NEXT:    [[L1:%.*]] = load i32, ptr [[ADD_PTR_I36]], align 4
23 ; CHECK-NEXT:    [[ADD_PTR_I29:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 1
24 ; CHECK-NEXT:    br i1 false, label [[TRAP]], label [[CHECK_1_MAX:%.*]]
25 ; CHECK:       check.1.max:
26 ; CHECK-NEXT:    br i1 true, label [[CHECK_2_MIN:%.*]], label [[TRAP]]
27 ; CHECK:       check.2.min:
28 ; CHECK-NEXT:    [[L2:%.*]] = load i32, ptr [[ADD_PTR_I29]], align 4
29 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 2
30 ; CHECK-NEXT:    br i1 false, label [[TRAP]], label [[CHECK_2_MAX:%.*]]
31 ; CHECK:       check.2.max:
32 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[TRAP]]
33 ; CHECK:       exit:
34 ; CHECK-NEXT:    [[L3:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4
35 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[L1]], [[L0]]
36 ; CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[ADD]], [[L2]]
37 ; CHECK-NEXT:    [[ADD9:%.*]] = add nsw i32 [[ADD8]], [[L3]]
38 ; CHECK-NEXT:    ret i32 [[ADD9]]
40 check.0.min:
41   %c.min.0 = icmp ult ptr %src, %min
42   br i1 %c.min.0, label %trap, label %check.0.max
44 trap:
45   ret i32 10
47 check.0.max:
48   %c.max.0 = icmp ult ptr %src, %max
49   br i1 %c.max.0, label %check.3.min, label %trap
51 check.3.min:
52   %l0 = load i32, ptr %src, align 4
53   %add.ptr.i36 = getelementptr inbounds i32, ptr %src, i64 3
54   %c.3.min = icmp ult ptr %add.ptr.i36, %min
55   br i1 %c.3.min, label %trap, label %check.3.max
57 check.3.max:
58   %c.3.max = icmp ult ptr %add.ptr.i36, %max
59   br i1 %c.3.max, label %check.1.min, label %trap
61 check.1.min:
62   %l1 = load i32, ptr %add.ptr.i36, align 4
63   %add.ptr.i29 = getelementptr inbounds i32, ptr %src, i64 1
64   %c.1.min = icmp ult ptr %add.ptr.i29, %min
65   br i1 %c.1.min, label %trap, label %check.1.max
67 check.1.max:
68   %c.1.max = icmp ult ptr %add.ptr.i29, %max
69   br i1 %c.1.max, label %check.2.min, label %trap
71 check.2.min:
72   %l2 = load i32, ptr %add.ptr.i29, align 4
73   %add.ptr.i = getelementptr inbounds i32, ptr %src, i64 2
74   %c.2.min = icmp ult ptr %add.ptr.i, %min
75   br i1 %c.2.min, label %trap, label %check.2.max
77 check.2.max:
78   %c.2.max = icmp ult ptr %add.ptr.i, %max
79   br i1 %c.2.max, label %exit, label %trap
81 exit:
82   %l3 = load i32, ptr %add.ptr.i, align 4
83   %add = add nsw i32 %l1, %l0
84   %add8 = add nsw i32 %add, %l2
85   %add9 = add nsw i32 %add8, %l3
86   ret i32 %add9
89 ; Same as test.ult, but without inbounds.
90 define i32 @test.ult_no_inbounds(ptr readonly %src, ptr readnone %min, ptr readnone %max) {
91 ; CHECK-LABEL: @test.ult_no_inbounds(
92 ; CHECK-NEXT:  check.0.min:
93 ; CHECK-NEXT:    [[C_MIN_0:%.*]] = icmp ult ptr [[SRC:%.*]], [[MIN:%.*]]
94 ; CHECK-NEXT:    br i1 [[C_MIN_0]], label [[TRAP:%.*]], label [[CHECK_0_MAX:%.*]]
95 ; CHECK:       trap:
96 ; CHECK-NEXT:    ret i32 10
97 ; CHECK:       check.0.max:
98 ; CHECK-NEXT:    [[C_MAX_0:%.*]] = icmp ult ptr [[SRC]], [[MAX:%.*]]
99 ; CHECK-NEXT:    br i1 [[C_MAX_0]], label [[CHECK_3_MIN:%.*]], label [[TRAP]]
100 ; CHECK:       check.3.min:
101 ; CHECK-NEXT:    [[L0:%.*]] = load i32, ptr [[SRC]], align 4
102 ; CHECK-NEXT:    [[ADD_PTR_I36:%.*]] = getelementptr i32, ptr [[SRC]], i64 3
103 ; CHECK-NEXT:    [[C_3_MIN:%.*]] = icmp ult ptr [[ADD_PTR_I36]], [[MIN]]
104 ; CHECK-NEXT:    br i1 [[C_3_MIN]], label [[TRAP]], label [[CHECK_3_MAX:%.*]]
105 ; CHECK:       check.3.max:
106 ; CHECK-NEXT:    [[C_3_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I36]], [[MAX]]
107 ; CHECK-NEXT:    br i1 [[C_3_MAX]], label [[CHECK_1_MIN:%.*]], label [[TRAP]]
108 ; CHECK:       check.1.min:
109 ; CHECK-NEXT:    [[L1:%.*]] = load i32, ptr [[ADD_PTR_I36]], align 4
110 ; CHECK-NEXT:    [[ADD_PTR_I29:%.*]] = getelementptr i32, ptr [[SRC]], i64 1
111 ; CHECK-NEXT:    [[C_1_MIN:%.*]] = icmp ult ptr [[ADD_PTR_I29]], [[MIN]]
112 ; CHECK-NEXT:    br i1 [[C_1_MIN]], label [[TRAP]], label [[CHECK_1_MAX:%.*]]
113 ; CHECK:       check.1.max:
114 ; CHECK-NEXT:    [[C_1_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I29]], [[MAX]]
115 ; CHECK-NEXT:    br i1 [[C_1_MAX]], label [[CHECK_2_MIN:%.*]], label [[TRAP]]
116 ; CHECK:       check.2.min:
117 ; CHECK-NEXT:    [[L2:%.*]] = load i32, ptr [[ADD_PTR_I29]], align 4
118 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr i32, ptr [[SRC]], i64 2
119 ; CHECK-NEXT:    [[C_2_MIN:%.*]] = icmp ult ptr [[ADD_PTR_I]], [[MIN]]
120 ; CHECK-NEXT:    br i1 [[C_2_MIN]], label [[TRAP]], label [[CHECK_2_MAX:%.*]]
121 ; CHECK:       check.2.max:
122 ; CHECK-NEXT:    [[C_2_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I]], [[MAX]]
123 ; CHECK-NEXT:    br i1 [[C_2_MAX]], label [[EXIT:%.*]], label [[TRAP]]
124 ; CHECK:       exit:
125 ; CHECK-NEXT:    [[L3:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4
126 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[L1]], [[L0]]
127 ; CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[ADD]], [[L2]]
128 ; CHECK-NEXT:    [[ADD9:%.*]] = add nsw i32 [[ADD8]], [[L3]]
129 ; CHECK-NEXT:    ret i32 [[ADD9]]
131 check.0.min:
132   %c.min.0 = icmp ult ptr %src, %min
133   br i1 %c.min.0, label %trap, label %check.0.max
135 trap:
136   ret i32 10
138 check.0.max:
139   %c.max.0 = icmp ult ptr %src, %max
140   br i1 %c.max.0, label %check.3.min, label %trap
142 check.3.min:
143   %l0 = load i32, ptr %src, align 4
144   %add.ptr.i36 = getelementptr i32, ptr %src, i64 3
145   %c.3.min = icmp ult ptr %add.ptr.i36, %min
146   br i1 %c.3.min, label %trap, label %check.3.max
148 check.3.max:
149   %c.3.max = icmp ult ptr %add.ptr.i36, %max
150   br i1 %c.3.max, label %check.1.min, label %trap
152 check.1.min:
153   %l1 = load i32, ptr %add.ptr.i36, align 4
154   %add.ptr.i29 = getelementptr i32, ptr %src, i64 1
155   %c.1.min = icmp ult ptr %add.ptr.i29, %min
156   br i1 %c.1.min, label %trap, label %check.1.max
158 check.1.max:
159   %c.1.max = icmp ult ptr %add.ptr.i29, %max
160   br i1 %c.1.max, label %check.2.min, label %trap
162 check.2.min:
163   %l2 = load i32, ptr %add.ptr.i29, align 4
164   %add.ptr.i = getelementptr i32, ptr %src, i64 2
165   %c.2.min = icmp ult ptr %add.ptr.i, %min
166   br i1 %c.2.min, label %trap, label %check.2.max
168 check.2.max:
169   %c.2.max = icmp ult ptr %add.ptr.i, %max
170   br i1 %c.2.max, label %exit, label %trap
172 exit:
173   %l3 = load i32, ptr %add.ptr.i, align 4
174   %add = add nsw i32 %l1, %l0
175   %add8 = add nsw i32 %add, %l2
176   %add9 = add nsw i32 %add8, %l3
177   ret i32 %add9
180 define void @test.not.uge.ult(ptr %start, ptr %low, ptr %high) {
181 ; CHECK-LABEL: @test.not.uge.ult(
182 ; CHECK-NEXT:  entry:
183 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3
184 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
185 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
186 ; CHECK:       if.then:
187 ; CHECK-NEXT:    ret void
188 ; CHECK:       if.end:
189 ; CHECK-NEXT:    call void @use(i1 true)
190 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1
191 ; CHECK-NEXT:    call void @use(i1 true)
192 ; CHECK-NEXT:    [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2
193 ; CHECK-NEXT:    call void @use(i1 true)
194 ; CHECK-NEXT:    [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3
195 ; CHECK-NEXT:    call void @use(i1 true)
196 ; CHECK-NEXT:    [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4
197 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ult ptr [[START_4]], [[HIGH]]
198 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
199 ; CHECK-NEXT:    ret void
201 entry:
202   %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3
203   %c.1 = icmp uge ptr %add.ptr.i, %high
204   br i1 %c.1, label %if.then, label %if.end
206 if.then:
207   ret void
209 if.end:
210   %t.0 = icmp ult ptr %start, %high
211   call void @use(i1 %t.0)
212   %start.1 = getelementptr inbounds i8, ptr %start, i64 1
213   %t.1 = icmp ult ptr %start.1, %high
214   call void @use(i1 %t.1)
215   %start.2 = getelementptr inbounds i8, ptr %start, i64 2
216   %t.2 = icmp ult ptr %start.2, %high
217   call void @use(i1 %t.2)
218   %start.3 = getelementptr inbounds i8, ptr %start, i64 3
219   %t.3 = icmp ult ptr %start.3, %high
220   call void @use(i1 %t.3)
221   %start.4 = getelementptr inbounds i8, ptr %start, i64 4
222   %c.4 = icmp ult ptr %start.4, %high
223   call void @use(i1 %c.4)
224   ret void
227 ; Same as test.not.uge.ult, but without inbounds GEPs.
228 define void @test.not.uge.ult_no_inbounds(ptr %start, ptr %low, ptr %high) {
229 ; CHECK-LABEL: @test.not.uge.ult_no_inbounds(
230 ; CHECK-NEXT:  entry:
231 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr i8, ptr [[START:%.*]], i64 3
232 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
233 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
234 ; CHECK:       if.then:
235 ; CHECK-NEXT:    ret void
236 ; CHECK:       if.end:
237 ; CHECK-NEXT:    [[T_0:%.*]] = icmp ult ptr [[START]], [[HIGH]]
238 ; CHECK-NEXT:    call void @use(i1 [[T_0]])
239 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr i8, ptr [[START]], i64 1
240 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ult ptr [[START_1]], [[HIGH]]
241 ; CHECK-NEXT:    call void @use(i1 [[T_1]])
242 ; CHECK-NEXT:    [[START_2:%.*]] = getelementptr i8, ptr [[START]], i64 2
243 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[START_2]], [[HIGH]]
244 ; CHECK-NEXT:    call void @use(i1 [[T_2]])
245 ; CHECK-NEXT:    [[START_3:%.*]] = getelementptr i8, ptr [[START]], i64 3
246 ; CHECK-NEXT:    [[T_3:%.*]] = icmp ult ptr [[START_3]], [[HIGH]]
247 ; CHECK-NEXT:    call void @use(i1 [[T_3]])
248 ; CHECK-NEXT:    [[START_4:%.*]] = getelementptr i8, ptr [[START]], i64 4
249 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ult ptr [[START_4]], [[HIGH]]
250 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
251 ; CHECK-NEXT:    ret void
253 entry:
254   %add.ptr.i = getelementptr i8, ptr %start, i64 3
255   %c.1 = icmp uge ptr %add.ptr.i, %high
256   br i1 %c.1, label %if.then, label %if.end
258 if.then:
259   ret void
261 if.end:
262   %t.0 = icmp ult ptr %start, %high
263   call void @use(i1 %t.0)
264   %start.1 = getelementptr i8, ptr %start, i64 1
265   %t.1 = icmp ult ptr %start.1, %high
266   call void @use(i1 %t.1)
267   %start.2 = getelementptr i8, ptr %start, i64 2
268   %t.2 = icmp ult ptr %start.2, %high
269   call void @use(i1 %t.2)
270   %start.3 = getelementptr i8, ptr %start, i64 3
271   %t.3 = icmp ult ptr %start.3, %high
272   call void @use(i1 %t.3)
273   %start.4 = getelementptr i8, ptr %start, i64 4
274   %c.4 = icmp ult ptr %start.4, %high
275   call void @use(i1 %c.4)
276   ret void
279 define void @test.not.uge.ule(ptr %start, ptr %low, ptr %high) {
280 ; CHECK-LABEL: @test.not.uge.ule(
281 ; CHECK-NEXT:  entry:
282 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3
283 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
284 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
285 ; CHECK:       if.then:
286 ; CHECK-NEXT:    ret void
287 ; CHECK:       if.end:
288 ; CHECK-NEXT:    call void @use(i1 true)
289 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1
290 ; CHECK-NEXT:    call void @use(i1 true)
291 ; CHECK-NEXT:    [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2
292 ; CHECK-NEXT:    call void @use(i1 true)
293 ; CHECK-NEXT:    [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3
294 ; CHECK-NEXT:    call void @use(i1 true)
295 ; CHECK-NEXT:    [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4
296 ; CHECK-NEXT:    call void @use(i1 true)
297 ; CHECK-NEXT:    [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5
298 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ule ptr [[START_5]], [[HIGH]]
299 ; CHECK-NEXT:    call void @use(i1 [[C_5]])
300 ; CHECK-NEXT:    ret void
302 entry:
303   %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3
304   %c.1 = icmp uge ptr %add.ptr.i, %high
305   br i1 %c.1, label %if.then, label %if.end
307 if.then:
308   ret void
310 if.end:
311   %t.0 = icmp ule ptr %start, %high
312   call void @use(i1 %t.0)
313   %start.1 = getelementptr inbounds i8, ptr %start, i64 1
314   %t.1 = icmp ule ptr %start.1, %high
315   call void @use(i1 %t.1)
316   %start.2 = getelementptr inbounds i8, ptr %start, i64 2
317   %t.2 = icmp ule ptr %start.2, %high
318   call void @use(i1 %t.2)
319   %start.3 = getelementptr inbounds i8, ptr %start, i64 3
320   %t.3 = icmp ule ptr %start.3, %high
321   call void @use(i1 %t.3)
322   %start.4 = getelementptr inbounds i8, ptr %start, i64 4
323   %t.4 = icmp ule ptr %start.4, %high
324   call void @use(i1 %t.4)
325   %start.5 = getelementptr inbounds i8, ptr %start, i64 5
326   %c.5 = icmp ule ptr %start.5, %high
327   call void @use(i1 %c.5)
328   ret void
331 define void @test.not.uge.ugt(ptr %start, ptr %low, ptr %high) {
332 ; CHECK-LABEL: @test.not.uge.ugt(
333 ; CHECK-NEXT:  entry:
334 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3
335 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
336 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
337 ; CHECK:       if.then:
338 ; CHECK-NEXT:    ret void
339 ; CHECK:       if.end:
340 ; CHECK-NEXT:    call void @use(i1 false)
341 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1
342 ; CHECK-NEXT:    call void @use(i1 false)
343 ; CHECK-NEXT:    [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2
344 ; CHECK-NEXT:    call void @use(i1 false)
345 ; CHECK-NEXT:    [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3
346 ; CHECK-NEXT:    call void @use(i1 false)
347 ; CHECK-NEXT:    [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4
348 ; CHECK-NEXT:    call void @use(i1 false)
349 ; CHECK-NEXT:    [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5
350 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt ptr [[START_5]], [[HIGH]]
351 ; CHECK-NEXT:    call void @use(i1 [[C_5]])
352 ; CHECK-NEXT:    ret void
354 entry:
355   %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3
356   %c.1 = icmp uge ptr %add.ptr.i, %high
357   br i1 %c.1, label %if.then, label %if.end
359 if.then:
360   ret void
362 if.end:
363   %f.0 = icmp ugt ptr %start, %high
364   call void @use(i1 %f.0)
365   %start.1 = getelementptr inbounds i8, ptr %start, i64 1
366   %f.1 = icmp ugt ptr %start.1, %high
367   call void @use(i1 %f.1)
368   %start.2 = getelementptr inbounds i8, ptr %start, i64 2
369   %f.2 = icmp ugt ptr %start.2, %high
370   call void @use(i1 %f.2)
371   %start.3 = getelementptr inbounds i8, ptr %start, i64 3
372   %f.3 = icmp ugt ptr %start.3, %high
373   call void @use(i1 %f.3)
374   %start.4 = getelementptr inbounds i8, ptr %start, i64 4
375   %f.4 = icmp ugt ptr %start.4, %high
376   call void @use(i1 %f.4)
377   %start.5 = getelementptr inbounds i8, ptr %start, i64 5
378   %c.5 = icmp ugt ptr %start.5, %high
379   call void @use(i1 %c.5)
380   ret void
383 define void @test.not.uge.uge(ptr %start, ptr %low, ptr %high) {
384 ; CHECK-LABEL: @test.not.uge.uge(
385 ; CHECK-NEXT:  entry:
386 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3
387 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
388 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
389 ; CHECK:       if.then:
390 ; CHECK-NEXT:    ret void
391 ; CHECK:       if.end:
392 ; CHECK-NEXT:    call void @use(i1 false)
393 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1
394 ; CHECK-NEXT:    call void @use(i1 false)
395 ; CHECK-NEXT:    [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2
396 ; CHECK-NEXT:    call void @use(i1 false)
397 ; CHECK-NEXT:    [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3
398 ; CHECK-NEXT:    call void @use(i1 false)
399 ; CHECK-NEXT:    [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4
400 ; CHECK-NEXT:    [[C_4:%.*]] = icmp uge ptr [[START_4]], [[HIGH]]
401 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
402 ; CHECK-NEXT:    [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5
403 ; CHECK-NEXT:    [[C_5:%.*]] = icmp uge ptr [[START_5]], [[HIGH]]
404 ; CHECK-NEXT:    call void @use(i1 [[C_5]])
405 ; CHECK-NEXT:    ret void
407 entry:
408   %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3
409   %c.1 = icmp uge ptr %add.ptr.i, %high
410   br i1 %c.1, label %if.then, label %if.end
412 if.then:
413   ret void
415 if.end:
416   %f.0 = icmp ugt ptr %start, %high
417   call void @use(i1 %f.0)
418   %start.1 = getelementptr inbounds i8, ptr %start, i64 1
419   %f.1 = icmp uge ptr %start.1, %high
420   call void @use(i1 %f.1)
421   %start.2 = getelementptr inbounds i8, ptr %start, i64 2
422   %f.2 = icmp uge ptr %start.2, %high
423   call void @use(i1 %f.2)
424   %start.3 = getelementptr inbounds i8, ptr %start, i64 3
425   %f.3 = icmp uge ptr %start.3, %high
426   call void @use(i1 %f.3)
427   %start.4 = getelementptr inbounds i8, ptr %start, i64 4
428   %c.4 = icmp uge ptr %start.4, %high
429   call void @use(i1 %c.4)
430   %start.5 = getelementptr inbounds i8, ptr %start, i64 5
431   %c.5 = icmp uge ptr %start.5, %high
432   call void @use(i1 %c.5)
433   ret void
436 define void @test.not.uge.uge.nonconst(ptr %start, ptr %low, ptr %high, i8 %off) {
437 ; CHECK-LABEL: @test.not.uge.uge.nonconst(
438 ; CHECK-NEXT:  entry:
439 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i8 [[OFF:%.*]]
440 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
441 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
442 ; CHECK:       if.then:
443 ; CHECK-NEXT:    [[START_OFF_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i8 [[OFF]]
444 ; CHECK-NEXT:    [[T_0:%.*]] = icmp uge ptr [[START_OFF_2]], [[HIGH]]
445 ; CHECK-NEXT:    call void @use(i1 [[T_0]])
446 ; CHECK-NEXT:    ret void
447 ; CHECK:       if.end:
448 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1
449 ; CHECK-NEXT:    [[C_0:%.*]] = icmp uge ptr [[START_1]], [[HIGH]]
450 ; CHECK-NEXT:    call void @use(i1 [[C_0]])
451 ; CHECK-NEXT:    [[START_OFF:%.*]] = getelementptr inbounds i8, ptr [[START]], i8 [[OFF]]
452 ; CHECK-NEXT:    [[F_0:%.*]] = icmp uge ptr [[START_OFF]], [[HIGH]]
453 ; CHECK-NEXT:    call void @use(i1 [[F_0]])
454 ; CHECK-NEXT:    ret void
456 entry:
457   %add.ptr.i = getelementptr inbounds i8, ptr %start, i8 %off
458   %c.1 = icmp uge ptr %add.ptr.i, %high
459   br i1 %c.1, label %if.then, label %if.end
461 if.then:
462   %start.off.2 = getelementptr inbounds i8, ptr %start, i8 %off
463   %t.0 = icmp uge ptr %start.off.2, %high
464   call void @use(i1 %t.0)
465   ret void
467 if.end:
468   %start.1 = getelementptr inbounds i8, ptr %start, i64 1
469   %c.0 = icmp uge ptr %start.1, %high
470   call void @use(i1 %c.0)
471   %start.off = getelementptr inbounds i8, ptr %start, i8 %off
472   %f.0 = icmp uge ptr %start.off, %high
473   call void @use(i1 %f.0)
474   ret void
477 ; Test which requires decomposing GEP %ptr, SHL().
478 define void @test.ult.gep.shl(ptr readonly %src, ptr readnone %max, i8 %idx) {
479 ; CHECK-LABEL: @test.ult.gep.shl(
480 ; CHECK-NEXT:  check.0.min:
481 ; CHECK-NEXT:    [[ADD_10:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i32 10
482 ; CHECK-NEXT:    [[C_ADD_10_MAX:%.*]] = icmp ugt ptr [[ADD_10]], [[MAX:%.*]]
483 ; CHECK-NEXT:    br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]]
484 ; CHECK:       trap:
485 ; CHECK-NEXT:    ret void
486 ; CHECK:       check.idx:
487 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[IDX:%.*]], 5
488 ; CHECK-NEXT:    br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]]
489 ; CHECK:       check.max:
490 ; CHECK-NEXT:    [[IDX_SHL_1:%.*]] = shl nuw nsw i8 [[IDX]], 1
491 ; CHECK-NEXT:    [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_1]]
492 ; CHECK-NEXT:    call void @use(i1 true)
493 ; CHECK-NEXT:    [[IDX_SHL_2:%.*]] = shl nuw i8 [[IDX]], 2
494 ; CHECK-NEXT:    [[ADD_PTR_SHL_2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_2]]
495 ; CHECK-NEXT:    [[C_MAX_1:%.*]] = icmp ult ptr [[ADD_PTR_SHL_2]], [[MAX]]
496 ; CHECK-NEXT:    call void @use(i1 [[C_MAX_1]])
497 ; CHECK-NEXT:    [[IDX_SHL_NOT_NUW:%.*]] = shl i8 [[IDX]], 1
498 ; CHECK-NEXT:    [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_NOT_NUW]]
499 ; CHECK-NEXT:    [[C_MAX_2:%.*]] = icmp ult ptr [[ADD_PTR_SHL_NOT_NUW]], [[MAX]]
500 ; CHECK-NEXT:    call void @use(i1 [[C_MAX_2]])
501 ; CHECK-NEXT:    [[IDX_SHL_3:%.*]] = shl nuw i8 [[IDX]], 3
502 ; CHECK-NEXT:    [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_3]]
503 ; CHECK-NEXT:    [[C_MAX_3:%.*]] = icmp ult ptr [[ADD_PTR_SHL_3]], [[MAX]]
504 ; CHECK-NEXT:    call void @use(i1 [[C_MAX_3]])
505 ; CHECK-NEXT:    ret void
507 check.0.min:
508   %add.10 = getelementptr inbounds i32, ptr %src, i32 10
509   %c.add.10.max = icmp ugt ptr %add.10, %max
510   br i1 %c.add.10.max, label %trap, label %check.idx
512 trap:
513   ret void
515 check.idx:
516   %cmp = icmp ult i8 %idx, 5
517   br i1 %cmp, label %check.max, label %trap
519 check.max:
520   %idx.shl.1 = shl nsw nuw i8 %idx, 1
521   %add.ptr.shl.1 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.1
522   %c.max.0 = icmp ult ptr %add.ptr.shl.1, %max
523   call void @use(i1 %c.max.0)
524   %idx.shl.2 = shl nuw i8 %idx, 2
525   %add.ptr.shl.2 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.2
526   %c.max.1 = icmp ult ptr %add.ptr.shl.2, %max
527   call void @use(i1 %c.max.1)
528   %idx.shl.not.nuw = shl i8 %idx, 1
529   %add.ptr.shl.not.nuw = getelementptr inbounds i32, ptr %src, i8 %idx.shl.not.nuw
530   %c.max.2 = icmp ult ptr %add.ptr.shl.not.nuw, %max
531   call void @use(i1 %c.max.2)
532   %idx.shl.3 = shl nuw i8 %idx, 3
533   %add.ptr.shl.3 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.3
534   %c.max.3 = icmp ult ptr %add.ptr.shl.3, %max
535   call void @use(i1 %c.max.3)
536   ret void
539 ; Test which requires decomposing GEP %ptr, ZEXT(SHL()).
540 define void @test.ult.gep.shl.zext(ptr readonly %src, ptr readnone %max, i32 %idx, i32 %j) {
541 ; CHECK-LABEL: @test.ult.gep.shl.zext(
542 ; CHECK-NEXT:  check.0.min:
543 ; CHECK-NEXT:    [[ADD_10:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i32 10
544 ; CHECK-NEXT:    [[C_ADD_10_MAX:%.*]] = icmp ugt ptr [[ADD_10]], [[MAX:%.*]]
545 ; CHECK-NEXT:    br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]]
546 ; CHECK:       trap:
547 ; CHECK-NEXT:    ret void
548 ; CHECK:       check.idx:
549 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 5
550 ; CHECK-NEXT:    br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]]
551 ; CHECK:       check.max:
552 ; CHECK-NEXT:    [[IDX_SHL:%.*]] = shl nuw i32 [[IDX]], 1
553 ; CHECK-NEXT:    [[EXT_1:%.*]] = zext i32 [[IDX_SHL]] to i64
554 ; CHECK-NEXT:    [[ADD_PTR_SHL:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_1]]
555 ; CHECK-NEXT:    call void @use(i1 true)
556 ; CHECK-NEXT:    [[IDX_SHL_NOT_NUW:%.*]] = shl i32 [[IDX]], 1
557 ; CHECK-NEXT:    [[EXT_2:%.*]] = zext i32 [[IDX_SHL_NOT_NUW]] to i64
558 ; CHECK-NEXT:    [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_2]]
559 ; CHECK-NEXT:    [[C_MAX_1:%.*]] = icmp ult ptr [[ADD_PTR_SHL_NOT_NUW]], [[MAX]]
560 ; CHECK-NEXT:    call void @use(i1 [[C_MAX_1]])
561 ; CHECK-NEXT:    [[IDX_SHL_3:%.*]] = shl nuw i32 [[IDX]], 2
562 ; CHECK-NEXT:    [[EXT_3:%.*]] = zext i32 [[IDX_SHL_3]] to i64
563 ; CHECK-NEXT:    [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_3]]
564 ; CHECK-NEXT:    [[C_MAX_2:%.*]] = icmp ult ptr [[ADD_PTR_SHL_3]], [[MAX]]
565 ; CHECK-NEXT:    call void @use(i1 [[C_MAX_2]])
566 ; CHECK-NEXT:    ret void
568 check.0.min:
569   %add.10 = getelementptr inbounds i32, ptr %src, i32 10
570   %c.add.10.max = icmp ugt ptr %add.10, %max
571   br i1 %c.add.10.max, label %trap, label %check.idx
573 trap:
574   ret void
576 check.idx:
577   %cmp = icmp ult i32 %idx, 5
578   br i1 %cmp, label %check.max, label %trap
580 check.max:
581   %idx.shl = shl nuw i32 %idx, 1
582   %ext.1 = zext i32 %idx.shl to i64
583   %add.ptr.shl = getelementptr inbounds i32, ptr %src, i64 %ext.1
584   %c.max.0 = icmp ult ptr %add.ptr.shl, %max
585   call void @use(i1 %c.max.0)
586   %idx.shl.not.nuw = shl i32 %idx, 1
587   %ext.2 = zext i32 %idx.shl.not.nuw to i64
588   %add.ptr.shl.not.nuw = getelementptr inbounds i32, ptr %src, i64 %ext.2
589   %c.max.1 = icmp ult ptr %add.ptr.shl.not.nuw, %max
590   call void @use(i1 %c.max.1)
591   %idx.shl.3 = shl nuw i32 %idx, 2
592   %ext.3 = zext i32 %idx.shl.3 to i64
593   %add.ptr.shl.3 = getelementptr inbounds i32, ptr %src, i64 %ext.3
594   %c.max.2 = icmp ult ptr %add.ptr.shl.3, %max
595   call void @use(i1 %c.max.2)
596   ret void
599 ; Make sure non-constant shift amounts are handled correctly.
600 define i1 @test.ult.gep.shl.nonconst.zext(i16 %B, ptr readonly %src, ptr readnone %max, i16 %idx, i16 %j) {
601 ; CHECK-LABEL: @test.ult.gep.shl.nonconst.zext(
602 ; CHECK-NEXT:  check.0.min:
603 ; CHECK-NEXT:    [[ADD_10:%.*]] = getelementptr inbounds i16, ptr [[SRC:%.*]], i16 10
604 ; CHECK-NEXT:    [[C_ADD_10_MAX:%.*]] = icmp ugt ptr [[ADD_10]], [[MAX:%.*]]
605 ; CHECK-NEXT:    br i1 [[C_ADD_10_MAX]], label [[EXIT_1:%.*]], label [[CHECK_IDX:%.*]]
606 ; CHECK:       exit.1:
607 ; CHECK-NEXT:    ret i1 true
608 ; CHECK:       check.idx:
609 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[IDX:%.*]], 5
610 ; CHECK-NEXT:    br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP:%.*]]
611 ; CHECK:       check.max:
612 ; CHECK-NEXT:    [[IDX_SHL:%.*]] = shl nuw i16 [[IDX]], [[B:%.*]]
613 ; CHECK-NEXT:    [[EXT:%.*]] = zext i16 [[IDX_SHL]] to i64
614 ; CHECK-NEXT:    [[ADD_PTR_SHL:%.*]] = getelementptr inbounds i16, ptr [[SRC]], i64 [[EXT]]
615 ; CHECK-NEXT:    [[C_MAX:%.*]] = icmp ult ptr [[ADD_PTR_SHL]], [[MAX]]
616 ; CHECK-NEXT:    ret i1 [[C_MAX]]
617 ; CHECK:       trap:
618 ; CHECK-NEXT:    [[IDX_SHL_1:%.*]] = shl nuw i16 [[IDX]], [[B]]
619 ; CHECK-NEXT:    [[EXT_1:%.*]] = zext i16 [[IDX_SHL_1]] to i64
620 ; CHECK-NEXT:    [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i16, ptr [[SRC]], i64 [[EXT_1]]
621 ; CHECK-NEXT:    [[C_MAX_1:%.*]] = icmp ult ptr [[ADD_PTR_SHL_1]], [[MAX]]
622 ; CHECK-NEXT:    ret i1 [[C_MAX_1]]
624 check.0.min:
625   %add.10 = getelementptr inbounds i16, ptr %src, i16 10
626   %c.add.10.max = icmp ugt ptr %add.10, %max
627   br i1 %c.add.10.max, label %exit.1, label %check.idx
629 exit.1:
630   ret i1 true
632 check.idx:
633   %cmp = icmp ult i16 %idx, 5
634   br i1 %cmp, label %check.max, label %trap
636 check.max:
637   %idx.shl = shl nuw i16 %idx, %B
638   %ext = zext i16 %idx.shl to i64
639   %add.ptr.shl = getelementptr inbounds i16, ptr %src, i64 %ext
640   %c.max = icmp ult ptr %add.ptr.shl, %max
641   ret i1 %c.max
643 trap:
644   %idx.shl.1 = shl nuw i16 %idx, %B
645   %ext.1 = zext i16 %idx.shl.1 to i64
646   %add.ptr.shl.1 = getelementptr inbounds i16, ptr %src, i64 %ext.1
647   %c.max.1 = icmp ult ptr %add.ptr.shl.1, %max
648   ret i1 %c.max.1
651 declare void @use(i1)