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.slt(ptr readonly %src, ptr readnone %min, ptr readnone %max) {
5 ; CHECK-LABEL: @test.slt(
6 ; CHECK-NEXT: check.0.min:
7 ; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp slt ptr [[SRC:%.*]], [[MIN:%.*]]
8 ; CHECK-NEXT: br i1 [[C_MIN_0]], label [[TRAP:%.*]], label [[CHECK_0_MAX:%.*]]
10 ; CHECK-NEXT: ret i32 10
12 ; CHECK-NEXT: [[C_MAX_0:%.*]] = icmp slt ptr [[SRC]], [[MAX:%.*]]
13 ; CHECK-NEXT: br i1 [[C_MAX_0]], label [[CHECK_3_MIN:%.*]], label [[TRAP]]
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: [[C_3_MIN:%.*]] = icmp slt ptr [[ADD_PTR_I36]], [[MIN]]
18 ; CHECK-NEXT: br i1 [[C_3_MIN]], label [[TRAP]], label [[CHECK_3_MAX:%.*]]
20 ; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp slt ptr [[ADD_PTR_I36]], [[MAX]]
21 ; CHECK-NEXT: br i1 [[C_3_MAX]], label [[CHECK_1_MIN:%.*]], label [[TRAP]]
23 ; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[ADD_PTR_I36]], align 4
24 ; CHECK-NEXT: [[ADD_PTR_I29:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 1
25 ; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp slt ptr [[ADD_PTR_I29]], [[MIN]]
26 ; CHECK-NEXT: br i1 [[C_1_MIN]], label [[TRAP]], label [[CHECK_1_MAX:%.*]]
28 ; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp slt ptr [[ADD_PTR_I29]], [[MAX]]
29 ; CHECK-NEXT: br i1 [[C_1_MAX]], label [[CHECK_2_MIN:%.*]], label [[TRAP]]
31 ; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[ADD_PTR_I29]], align 4
32 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 2
33 ; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp slt ptr [[ADD_PTR_I]], [[MIN]]
34 ; CHECK-NEXT: br i1 [[C_2_MIN]], label [[TRAP]], label [[CHECK_2_MAX:%.*]]
36 ; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp slt ptr [[ADD_PTR_I]], [[MAX]]
37 ; CHECK-NEXT: br i1 [[C_2_MAX]], label [[EXIT:%.*]], label [[TRAP]]
39 ; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4
40 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[L1]], [[L0]]
41 ; CHECK-NEXT: [[ADD8:%.*]] = add nsw i32 [[ADD]], [[L2]]
42 ; CHECK-NEXT: [[ADD9:%.*]] = add nsw i32 [[ADD8]], [[L3]]
43 ; CHECK-NEXT: ret i32 [[ADD9]]
46 %c.min.0 = icmp slt ptr %src, %min
47 br i1 %c.min.0, label %trap, label %check.0.max
53 %c.max.0 = icmp slt ptr %src, %max
54 br i1 %c.max.0, label %check.3.min, label %trap
57 %l0 = load i32, ptr %src, align 4
58 %add.ptr.i36 = getelementptr inbounds i32, ptr %src, i64 3
59 %c.3.min = icmp slt ptr %add.ptr.i36, %min
60 br i1 %c.3.min, label %trap, label %check.3.max
63 %c.3.max = icmp slt ptr %add.ptr.i36, %max
64 br i1 %c.3.max, label %check.1.min, label %trap
67 %l1 = load i32, ptr %add.ptr.i36, align 4
68 %add.ptr.i29 = getelementptr inbounds i32, ptr %src, i64 1
69 %c.1.min = icmp slt ptr %add.ptr.i29, %min
70 br i1 %c.1.min, label %trap, label %check.1.max
73 %c.1.max = icmp slt ptr %add.ptr.i29, %max
74 br i1 %c.1.max, label %check.2.min, label %trap
77 %l2 = load i32, ptr %add.ptr.i29, align 4
78 %add.ptr.i = getelementptr inbounds i32, ptr %src, i64 2
79 %c.2.min = icmp slt ptr %add.ptr.i, %min
80 br i1 %c.2.min, label %trap, label %check.2.max
83 %c.2.max = icmp slt ptr %add.ptr.i, %max
84 br i1 %c.2.max, label %exit, label %trap
87 %l3 = load i32, ptr %add.ptr.i, align 4
88 %add = add nsw i32 %l1, %l0
89 %add8 = add nsw i32 %add, %l2
90 %add9 = add nsw i32 %add8, %l3
94 ; Same as test.slt, but without inbounds.
95 define i32 @test.slt_no_inbounds(ptr readonly %src, ptr readnone %min, ptr readnone %max) {
96 ; CHECK-LABEL: @test.slt_no_inbounds(
97 ; CHECK-NEXT: check.0.min:
98 ; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp slt ptr [[SRC:%.*]], [[MIN:%.*]]
99 ; CHECK-NEXT: br i1 [[C_MIN_0]], label [[TRAP:%.*]], label [[CHECK_0_MAX:%.*]]
101 ; CHECK-NEXT: ret i32 10
102 ; CHECK: check.0.max:
103 ; CHECK-NEXT: [[C_MAX_0:%.*]] = icmp slt ptr [[SRC]], [[MAX:%.*]]
104 ; CHECK-NEXT: br i1 [[C_MAX_0]], label [[CHECK_3_MIN:%.*]], label [[TRAP]]
105 ; CHECK: check.3.min:
106 ; CHECK-NEXT: [[L0:%.*]] = load i32, ptr [[SRC]], align 4
107 ; CHECK-NEXT: [[ADD_PTR_I36:%.*]] = getelementptr i32, ptr [[SRC]], i64 3
108 ; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp slt ptr [[ADD_PTR_I36]], [[MIN]]
109 ; CHECK-NEXT: br i1 [[C_3_MIN]], label [[TRAP]], label [[CHECK_3_MAX:%.*]]
110 ; CHECK: check.3.max:
111 ; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp slt ptr [[ADD_PTR_I36]], [[MAX]]
112 ; CHECK-NEXT: br i1 [[C_3_MAX]], label [[CHECK_1_MIN:%.*]], label [[TRAP]]
113 ; CHECK: check.1.min:
114 ; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[ADD_PTR_I36]], align 4
115 ; CHECK-NEXT: [[ADD_PTR_I29:%.*]] = getelementptr i32, ptr [[SRC]], i64 1
116 ; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp slt ptr [[ADD_PTR_I29]], [[MIN]]
117 ; CHECK-NEXT: br i1 [[C_1_MIN]], label [[TRAP]], label [[CHECK_1_MAX:%.*]]
118 ; CHECK: check.1.max:
119 ; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp slt ptr [[ADD_PTR_I29]], [[MAX]]
120 ; CHECK-NEXT: br i1 [[C_1_MAX]], label [[CHECK_2_MIN:%.*]], label [[TRAP]]
121 ; CHECK: check.2.min:
122 ; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[ADD_PTR_I29]], align 4
123 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr i32, ptr [[SRC]], i64 2
124 ; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp slt ptr [[ADD_PTR_I]], [[MIN]]
125 ; CHECK-NEXT: br i1 [[C_2_MIN]], label [[TRAP]], label [[CHECK_2_MAX:%.*]]
126 ; CHECK: check.2.max:
127 ; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp slt ptr [[ADD_PTR_I]], [[MAX]]
128 ; CHECK-NEXT: br i1 [[C_2_MAX]], label [[EXIT:%.*]], label [[TRAP]]
130 ; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4
131 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[L1]], [[L0]]
132 ; CHECK-NEXT: [[ADD8:%.*]] = add nsw i32 [[ADD]], [[L2]]
133 ; CHECK-NEXT: [[ADD9:%.*]] = add nsw i32 [[ADD8]], [[L3]]
134 ; CHECK-NEXT: ret i32 [[ADD9]]
137 %c.min.0 = icmp slt ptr %src, %min
138 br i1 %c.min.0, label %trap, label %check.0.max
144 %c.max.0 = icmp slt ptr %src, %max
145 br i1 %c.max.0, label %check.3.min, label %trap
148 %l0 = load i32, ptr %src, align 4
149 %add.ptr.i36 = getelementptr i32, ptr %src, i64 3
150 %c.3.min = icmp slt ptr %add.ptr.i36, %min
151 br i1 %c.3.min, label %trap, label %check.3.max
154 %c.3.max = icmp slt ptr %add.ptr.i36, %max
155 br i1 %c.3.max, label %check.1.min, label %trap
158 %l1 = load i32, ptr %add.ptr.i36, align 4
159 %add.ptr.i29 = getelementptr i32, ptr %src, i64 1
160 %c.1.min = icmp slt ptr %add.ptr.i29, %min
161 br i1 %c.1.min, label %trap, label %check.1.max
164 %c.1.max = icmp slt ptr %add.ptr.i29, %max
165 br i1 %c.1.max, label %check.2.min, label %trap
168 %l2 = load i32, ptr %add.ptr.i29, align 4
169 %add.ptr.i = getelementptr i32, ptr %src, i64 2
170 %c.2.min = icmp slt ptr %add.ptr.i, %min
171 br i1 %c.2.min, label %trap, label %check.2.max
174 %c.2.max = icmp slt ptr %add.ptr.i, %max
175 br i1 %c.2.max, label %exit, label %trap
178 %l3 = load i32, ptr %add.ptr.i, align 4
179 %add = add nsw i32 %l1, %l0
180 %add8 = add nsw i32 %add, %l2
181 %add9 = add nsw i32 %add8, %l3
185 define void @test.not.sge.slt(ptr %start, ptr %low, ptr %high) {
186 ; CHECK-LABEL: @test.not.sge.slt(
188 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3
189 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
190 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
192 ; CHECK-NEXT: ret void
194 ; CHECK-NEXT: [[T_0:%.*]] = icmp slt ptr [[START]], [[HIGH]]
195 ; CHECK-NEXT: call void @use(i1 [[T_0]])
196 ; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1
197 ; CHECK-NEXT: [[T_1:%.*]] = icmp slt ptr [[START_1]], [[HIGH]]
198 ; CHECK-NEXT: call void @use(i1 [[T_1]])
199 ; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2
200 ; CHECK-NEXT: [[T_2:%.*]] = icmp slt ptr [[START_2]], [[HIGH]]
201 ; CHECK-NEXT: call void @use(i1 [[T_2]])
202 ; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3
203 ; CHECK-NEXT: [[T_3:%.*]] = icmp slt ptr [[START_3]], [[HIGH]]
204 ; CHECK-NEXT: call void @use(i1 [[T_3]])
205 ; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4
206 ; CHECK-NEXT: [[C_4:%.*]] = icmp slt ptr [[START_4]], [[HIGH]]
207 ; CHECK-NEXT: call void @use(i1 [[C_4]])
208 ; CHECK-NEXT: ret void
211 %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3
212 %c.1 = icmp sge ptr %add.ptr.i, %high
213 br i1 %c.1, label %if.then, label %if.end
219 %t.0 = icmp slt ptr %start, %high
220 call void @use(i1 %t.0)
221 %start.1 = getelementptr inbounds i8, ptr %start, i64 1
222 %t.1 = icmp slt ptr %start.1, %high
223 call void @use(i1 %t.1)
224 %start.2 = getelementptr inbounds i8, ptr %start, i64 2
225 %t.2 = icmp slt ptr %start.2, %high
226 call void @use(i1 %t.2)
227 %start.3 = getelementptr inbounds i8, ptr %start, i64 3
228 %t.3 = icmp slt ptr %start.3, %high
229 call void @use(i1 %t.3)
230 %start.4 = getelementptr inbounds i8, ptr %start, i64 4
231 %c.4 = icmp slt ptr %start.4, %high
232 call void @use(i1 %c.4)
236 ; Same as test.not.sge.slt, but without inbounds GEPs.
237 define void @test.not.sge.slt_no_inbounds(ptr %start, ptr %low, ptr %high) {
238 ; CHECK-LABEL: @test.not.sge.slt_no_inbounds(
240 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr i8, ptr [[START:%.*]], i64 3
241 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
242 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
244 ; CHECK-NEXT: ret void
246 ; CHECK-NEXT: [[T_0:%.*]] = icmp slt ptr [[START]], [[HIGH]]
247 ; CHECK-NEXT: call void @use(i1 [[T_0]])
248 ; CHECK-NEXT: [[START_1:%.*]] = getelementptr i8, ptr [[START]], i64 1
249 ; CHECK-NEXT: [[T_1:%.*]] = icmp slt ptr [[START_1]], [[HIGH]]
250 ; CHECK-NEXT: call void @use(i1 [[T_1]])
251 ; CHECK-NEXT: [[START_2:%.*]] = getelementptr i8, ptr [[START]], i64 2
252 ; CHECK-NEXT: [[T_2:%.*]] = icmp slt ptr [[START_2]], [[HIGH]]
253 ; CHECK-NEXT: call void @use(i1 [[T_2]])
254 ; CHECK-NEXT: [[START_3:%.*]] = getelementptr i8, ptr [[START]], i64 3
255 ; CHECK-NEXT: [[T_3:%.*]] = icmp slt ptr [[START_3]], [[HIGH]]
256 ; CHECK-NEXT: call void @use(i1 [[T_3]])
257 ; CHECK-NEXT: [[START_4:%.*]] = getelementptr i8, ptr [[START]], i64 4
258 ; CHECK-NEXT: [[C_4:%.*]] = icmp slt ptr [[START_4]], [[HIGH]]
259 ; CHECK-NEXT: call void @use(i1 [[C_4]])
260 ; CHECK-NEXT: ret void
263 %add.ptr.i = getelementptr i8, ptr %start, i64 3
264 %c.1 = icmp sge ptr %add.ptr.i, %high
265 br i1 %c.1, label %if.then, label %if.end
271 %t.0 = icmp slt ptr %start, %high
272 call void @use(i1 %t.0)
273 %start.1 = getelementptr i8, ptr %start, i64 1
274 %t.1 = icmp slt ptr %start.1, %high
275 call void @use(i1 %t.1)
276 %start.2 = getelementptr i8, ptr %start, i64 2
277 %t.2 = icmp slt ptr %start.2, %high
278 call void @use(i1 %t.2)
279 %start.3 = getelementptr i8, ptr %start, i64 3
280 %t.3 = icmp slt ptr %start.3, %high
281 call void @use(i1 %t.3)
282 %start.4 = getelementptr i8, ptr %start, i64 4
283 %c.4 = icmp slt ptr %start.4, %high
284 call void @use(i1 %c.4)
288 define void @test.not.sge.sle(ptr %start, ptr %low, ptr %high) {
289 ; CHECK-LABEL: @test.not.sge.sle(
291 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3
292 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
293 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
295 ; CHECK-NEXT: ret void
297 ; CHECK-NEXT: [[T_0:%.*]] = icmp sle ptr [[START]], [[HIGH]]
298 ; CHECK-NEXT: call void @use(i1 [[T_0]])
299 ; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1
300 ; CHECK-NEXT: [[T_1:%.*]] = icmp sle ptr [[START_1]], [[HIGH]]
301 ; CHECK-NEXT: call void @use(i1 [[T_1]])
302 ; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2
303 ; CHECK-NEXT: [[T_2:%.*]] = icmp sle ptr [[START_2]], [[HIGH]]
304 ; CHECK-NEXT: call void @use(i1 [[T_2]])
305 ; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3
306 ; CHECK-NEXT: [[T_3:%.*]] = icmp sle ptr [[START_3]], [[HIGH]]
307 ; CHECK-NEXT: call void @use(i1 [[T_3]])
308 ; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4
309 ; CHECK-NEXT: [[T_4:%.*]] = icmp sle ptr [[START_4]], [[HIGH]]
310 ; CHECK-NEXT: call void @use(i1 [[T_4]])
311 ; CHECK-NEXT: [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5
312 ; CHECK-NEXT: [[C_5:%.*]] = icmp sle ptr [[START_5]], [[HIGH]]
313 ; CHECK-NEXT: call void @use(i1 [[C_5]])
314 ; CHECK-NEXT: ret void
317 %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3
318 %c.1 = icmp sge ptr %add.ptr.i, %high
319 br i1 %c.1, label %if.then, label %if.end
325 %t.0 = icmp sle ptr %start, %high
326 call void @use(i1 %t.0)
327 %start.1 = getelementptr inbounds i8, ptr %start, i64 1
328 %t.1 = icmp sle ptr %start.1, %high
329 call void @use(i1 %t.1)
330 %start.2 = getelementptr inbounds i8, ptr %start, i64 2
331 %t.2 = icmp sle ptr %start.2, %high
332 call void @use(i1 %t.2)
333 %start.3 = getelementptr inbounds i8, ptr %start, i64 3
334 %t.3 = icmp sle ptr %start.3, %high
335 call void @use(i1 %t.3)
336 %start.4 = getelementptr inbounds i8, ptr %start, i64 4
337 %t.4 = icmp sle ptr %start.4, %high
338 call void @use(i1 %t.4)
339 %start.5 = getelementptr inbounds i8, ptr %start, i64 5
340 %c.5 = icmp sle ptr %start.5, %high
341 call void @use(i1 %c.5)
345 define void @test.not.sge.sgt(ptr %start, ptr %low, ptr %high) {
346 ; CHECK-LABEL: @test.not.sge.sgt(
348 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3
349 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
350 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
352 ; CHECK-NEXT: ret void
354 ; CHECK-NEXT: [[F_0:%.*]] = icmp sgt ptr [[START]], [[HIGH]]
355 ; CHECK-NEXT: call void @use(i1 [[F_0]])
356 ; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1
357 ; CHECK-NEXT: [[F_1:%.*]] = icmp sgt ptr [[START_1]], [[HIGH]]
358 ; CHECK-NEXT: call void @use(i1 [[F_1]])
359 ; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2
360 ; CHECK-NEXT: [[F_2:%.*]] = icmp sgt ptr [[START_2]], [[HIGH]]
361 ; CHECK-NEXT: call void @use(i1 [[F_2]])
362 ; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3
363 ; CHECK-NEXT: [[F_3:%.*]] = icmp sgt ptr [[START_3]], [[HIGH]]
364 ; CHECK-NEXT: call void @use(i1 [[F_3]])
365 ; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4
366 ; CHECK-NEXT: [[F_4:%.*]] = icmp sgt ptr [[START_4]], [[HIGH]]
367 ; CHECK-NEXT: call void @use(i1 [[F_4]])
368 ; CHECK-NEXT: [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5
369 ; CHECK-NEXT: [[C_5:%.*]] = icmp sgt ptr [[START_5]], [[HIGH]]
370 ; CHECK-NEXT: call void @use(i1 [[C_5]])
371 ; CHECK-NEXT: ret void
374 %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3
375 %c.1 = icmp sge ptr %add.ptr.i, %high
376 br i1 %c.1, label %if.then, label %if.end
382 %f.0 = icmp sgt ptr %start, %high
383 call void @use(i1 %f.0)
384 %start.1 = getelementptr inbounds i8, ptr %start, i64 1
385 %f.1 = icmp sgt ptr %start.1, %high
386 call void @use(i1 %f.1)
387 %start.2 = getelementptr inbounds i8, ptr %start, i64 2
388 %f.2 = icmp sgt ptr %start.2, %high
389 call void @use(i1 %f.2)
390 %start.3 = getelementptr inbounds i8, ptr %start, i64 3
391 %f.3 = icmp sgt ptr %start.3, %high
392 call void @use(i1 %f.3)
393 %start.4 = getelementptr inbounds i8, ptr %start, i64 4
394 %f.4 = icmp sgt ptr %start.4, %high
395 call void @use(i1 %f.4)
396 %start.5 = getelementptr inbounds i8, ptr %start, i64 5
397 %c.5 = icmp sgt ptr %start.5, %high
398 call void @use(i1 %c.5)
402 define void @test.not.sge.sge(ptr %start, ptr %low, ptr %high) {
403 ; CHECK-LABEL: @test.not.sge.sge(
405 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3
406 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
407 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
409 ; CHECK-NEXT: ret void
411 ; CHECK-NEXT: [[F_0:%.*]] = icmp sgt ptr [[START]], [[HIGH]]
412 ; CHECK-NEXT: call void @use(i1 [[F_0]])
413 ; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1
414 ; CHECK-NEXT: [[F_1:%.*]] = icmp sge ptr [[START_1]], [[HIGH]]
415 ; CHECK-NEXT: call void @use(i1 [[F_1]])
416 ; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2
417 ; CHECK-NEXT: [[F_2:%.*]] = icmp sge ptr [[START_2]], [[HIGH]]
418 ; CHECK-NEXT: call void @use(i1 [[F_2]])
419 ; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3
420 ; CHECK-NEXT: [[F_3:%.*]] = icmp sge ptr [[START_3]], [[HIGH]]
421 ; CHECK-NEXT: call void @use(i1 [[F_3]])
422 ; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4
423 ; CHECK-NEXT: [[C_4:%.*]] = icmp sge ptr [[START_4]], [[HIGH]]
424 ; CHECK-NEXT: call void @use(i1 [[C_4]])
425 ; CHECK-NEXT: [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5
426 ; CHECK-NEXT: [[C_5:%.*]] = icmp sge ptr [[START_5]], [[HIGH]]
427 ; CHECK-NEXT: call void @use(i1 [[C_5]])
428 ; CHECK-NEXT: ret void
431 %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3
432 %c.1 = icmp sge ptr %add.ptr.i, %high
433 br i1 %c.1, label %if.then, label %if.end
439 %f.0 = icmp sgt ptr %start, %high
440 call void @use(i1 %f.0)
441 %start.1 = getelementptr inbounds i8, ptr %start, i64 1
442 %f.1 = icmp sge ptr %start.1, %high
443 call void @use(i1 %f.1)
444 %start.2 = getelementptr inbounds i8, ptr %start, i64 2
445 %f.2 = icmp sge ptr %start.2, %high
446 call void @use(i1 %f.2)
447 %start.3 = getelementptr inbounds i8, ptr %start, i64 3
448 %f.3 = icmp sge ptr %start.3, %high
449 call void @use(i1 %f.3)
450 %start.4 = getelementptr inbounds i8, ptr %start, i64 4
451 %c.4 = icmp sge ptr %start.4, %high
452 call void @use(i1 %c.4)
453 %start.5 = getelementptr inbounds i8, ptr %start, i64 5
454 %c.5 = icmp sge ptr %start.5, %high
455 call void @use(i1 %c.5)
459 define void @test.not.sge.sge.nonconst(ptr %start, ptr %low, ptr %high, i8 %off) {
460 ; CHECK-LABEL: @test.not.sge.sge.nonconst(
462 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i8 [[OFF:%.*]]
463 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge ptr [[ADD_PTR_I]], [[HIGH:%.*]]
464 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
466 ; CHECK-NEXT: [[START_OFF_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i8 [[OFF]]
467 ; CHECK-NEXT: [[T_0:%.*]] = icmp sge ptr [[START_OFF_2]], [[HIGH]]
468 ; CHECK-NEXT: call void @use(i1 [[T_0]])
469 ; CHECK-NEXT: ret void
471 ; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1
472 ; CHECK-NEXT: [[C_0:%.*]] = icmp sge ptr [[START_1]], [[HIGH]]
473 ; CHECK-NEXT: call void @use(i1 [[C_0]])
474 ; CHECK-NEXT: [[START_OFF:%.*]] = getelementptr inbounds i8, ptr [[START]], i8 [[OFF]]
475 ; CHECK-NEXT: [[F_0:%.*]] = icmp sge ptr [[START_OFF]], [[HIGH]]
476 ; CHECK-NEXT: call void @use(i1 [[F_0]])
477 ; CHECK-NEXT: ret void
480 %add.ptr.i = getelementptr inbounds i8, ptr %start, i8 %off
481 %c.1 = icmp sge ptr %add.ptr.i, %high
482 br i1 %c.1, label %if.then, label %if.end
485 %start.off.2 = getelementptr inbounds i8, ptr %start, i8 %off
486 %t.0 = icmp sge ptr %start.off.2, %high
487 call void @use(i1 %t.0)
491 %start.1 = getelementptr inbounds i8, ptr %start, i64 1
492 %c.0 = icmp sge ptr %start.1, %high
493 call void @use(i1 %c.0)
494 %start.off = getelementptr inbounds i8, ptr %start, i8 %off
495 %f.0 = icmp sge ptr %start.off, %high
496 call void @use(i1 %f.0)
500 ; Test which requires decomposing GEP %ptr, SHL().
501 define void @test.slt.gep.shl(ptr readonly %src, ptr readnone %max, i8 %idx) {
502 ; CHECK-LABEL: @test.slt.gep.shl(
503 ; CHECK-NEXT: check.0.min:
504 ; CHECK-NEXT: [[ADD_10:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i32 10
505 ; CHECK-NEXT: [[C_ADD_10_MAX:%.*]] = icmp sgt ptr [[ADD_10]], [[MAX:%.*]]
506 ; CHECK-NEXT: br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]]
508 ; CHECK-NEXT: ret void
510 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[IDX:%.*]], 5
511 ; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]]
513 ; CHECK-NEXT: [[IDX_SHL_1:%.*]] = shl nuw i8 [[IDX]], 1
514 ; CHECK-NEXT: [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_1]]
515 ; CHECK-NEXT: [[C_MAX_0:%.*]] = icmp slt ptr [[ADD_PTR_SHL_1]], [[MAX]]
516 ; CHECK-NEXT: call void @use(i1 [[C_MAX_0]])
517 ; CHECK-NEXT: [[IDX_SHL_2:%.*]] = shl nuw i8 [[IDX]], 2
518 ; CHECK-NEXT: [[ADD_PTR_SHL_2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_2]]
519 ; CHECK-NEXT: [[C_MAX_1:%.*]] = icmp slt ptr [[ADD_PTR_SHL_2]], [[MAX]]
520 ; CHECK-NEXT: call void @use(i1 [[C_MAX_1]])
521 ; CHECK-NEXT: [[IDX_SHL_NOT_NUW:%.*]] = shl i8 [[IDX]], 1
522 ; CHECK-NEXT: [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_NOT_NUW]]
523 ; CHECK-NEXT: [[C_MAX_2:%.*]] = icmp slt ptr [[ADD_PTR_SHL_NOT_NUW]], [[MAX]]
524 ; CHECK-NEXT: call void @use(i1 [[C_MAX_2]])
525 ; CHECK-NEXT: [[IDX_SHL_3:%.*]] = shl nuw i8 [[IDX]], 3
526 ; CHECK-NEXT: [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_3]]
527 ; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp slt ptr [[ADD_PTR_SHL_3]], [[MAX]]
528 ; CHECK-NEXT: call void @use(i1 [[C_MAX_3]])
529 ; CHECK-NEXT: ret void
532 %add.10 = getelementptr inbounds i32, ptr %src, i32 10
533 %c.add.10.max = icmp sgt ptr %add.10, %max
534 br i1 %c.add.10.max, label %trap, label %check.idx
540 %cmp = icmp slt i8 %idx, 5
541 br i1 %cmp, label %check.max, label %trap
544 %idx.shl.1 = shl nuw i8 %idx, 1
545 %add.ptr.shl.1 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.1
546 %c.max.0 = icmp slt ptr %add.ptr.shl.1, %max
547 call void @use(i1 %c.max.0)
548 %idx.shl.2 = shl nuw i8 %idx, 2
549 %add.ptr.shl.2 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.2
550 %c.max.1 = icmp slt ptr %add.ptr.shl.2, %max
551 call void @use(i1 %c.max.1)
552 %idx.shl.not.nuw = shl i8 %idx, 1
553 %add.ptr.shl.not.nuw = getelementptr inbounds i32, ptr %src, i8 %idx.shl.not.nuw
554 %c.max.2 = icmp slt ptr %add.ptr.shl.not.nuw, %max
555 call void @use(i1 %c.max.2)
556 %idx.shl.3 = shl nuw i8 %idx, 3
557 %add.ptr.shl.3 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.3
558 %c.max.3 = icmp slt ptr %add.ptr.shl.3, %max
559 call void @use(i1 %c.max.3)
563 ; Test which requires decomposing GEP %ptr, ZEXT(SHL()).
564 define void @test.slt.gep.shl.zext(ptr readonly %src, ptr readnone %max, i32 %idx, i32 %j) {
565 ; CHECK-LABEL: @test.slt.gep.shl.zext(
566 ; CHECK-NEXT: check.0.min:
567 ; CHECK-NEXT: [[ADD_10:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i32 10
568 ; CHECK-NEXT: [[C_ADD_10_MAX:%.*]] = icmp sgt ptr [[ADD_10]], [[MAX:%.*]]
569 ; CHECK-NEXT: br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]]
571 ; CHECK-NEXT: ret void
573 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IDX:%.*]], 5
574 ; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]]
576 ; CHECK-NEXT: [[IDX_SHL:%.*]] = shl nuw i32 [[IDX]], 1
577 ; CHECK-NEXT: [[EXT_1:%.*]] = zext i32 [[IDX_SHL]] to i64
578 ; CHECK-NEXT: [[ADD_PTR_SHL:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_1]]
579 ; CHECK-NEXT: [[C_MAX_0:%.*]] = icmp slt ptr [[ADD_PTR_SHL]], [[MAX]]
580 ; CHECK-NEXT: call void @use(i1 [[C_MAX_0]])
581 ; CHECK-NEXT: [[IDX_SHL_NOT_NUW:%.*]] = shl i32 [[IDX]], 1
582 ; CHECK-NEXT: [[EXT_2:%.*]] = zext i32 [[IDX_SHL_NOT_NUW]] to i64
583 ; CHECK-NEXT: [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_2]]
584 ; CHECK-NEXT: [[C_MAX_1:%.*]] = icmp slt ptr [[ADD_PTR_SHL_NOT_NUW]], [[MAX]]
585 ; CHECK-NEXT: call void @use(i1 [[C_MAX_1]])
586 ; CHECK-NEXT: [[IDX_SHL_3:%.*]] = shl nuw i32 [[IDX]], 2
587 ; CHECK-NEXT: [[EXT_3:%.*]] = zext i32 [[IDX_SHL_3]] to i64
588 ; CHECK-NEXT: [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_3]]
589 ; CHECK-NEXT: [[C_MAX_2:%.*]] = icmp slt ptr [[ADD_PTR_SHL_3]], [[MAX]]
590 ; CHECK-NEXT: call void @use(i1 [[C_MAX_2]])
591 ; CHECK-NEXT: ret void
594 %add.10 = getelementptr inbounds i32, ptr %src, i32 10
595 %c.add.10.max = icmp sgt ptr %add.10, %max
596 br i1 %c.add.10.max, label %trap, label %check.idx
602 %cmp = icmp slt i32 %idx, 5
603 br i1 %cmp, label %check.max, label %trap
606 %idx.shl = shl nuw i32 %idx, 1
607 %ext.1 = zext i32 %idx.shl to i64
608 %add.ptr.shl = getelementptr inbounds i32, ptr %src, i64 %ext.1
609 %c.max.0 = icmp slt ptr %add.ptr.shl, %max
610 call void @use(i1 %c.max.0)
611 %idx.shl.not.nuw = shl i32 %idx, 1
612 %ext.2 = zext i32 %idx.shl.not.nuw to i64
613 %add.ptr.shl.not.nuw = getelementptr inbounds i32, ptr %src, i64 %ext.2
614 %c.max.1 = icmp slt ptr %add.ptr.shl.not.nuw, %max
615 call void @use(i1 %c.max.1)
616 %idx.shl.3 = shl nuw i32 %idx, 2
617 %ext.3 = zext i32 %idx.shl.3 to i64
618 %add.ptr.shl.3 = getelementptr inbounds i32, ptr %src, i64 %ext.3
619 %c.max.2 = icmp slt ptr %add.ptr.shl.3, %max
620 call void @use(i1 %c.max.2)
624 ; Make sure non-constant shift amounts are handled correctly.
625 define i1 @test.slt.gep.shl.nonconst.zext(i16 %B, ptr readonly %src, ptr readnone %max, i16 %idx, i16 %j) {
626 ; CHECK-LABEL: @test.slt.gep.shl.nonconst.zext(
627 ; CHECK-NEXT: check.0.min:
628 ; CHECK-NEXT: [[ADD_10:%.*]] = getelementptr inbounds i16, ptr [[SRC:%.*]], i16 10
629 ; CHECK-NEXT: [[C_ADD_10_MAX:%.*]] = icmp sgt ptr [[ADD_10]], [[MAX:%.*]]
630 ; CHECK-NEXT: br i1 [[C_ADD_10_MAX]], label [[EXIT_1:%.*]], label [[CHECK_IDX:%.*]]
632 ; CHECK-NEXT: ret i1 true
634 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[IDX:%.*]], 5
635 ; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP:%.*]]
637 ; CHECK-NEXT: [[IDX_SHL:%.*]] = shl nuw i16 [[IDX]], [[B:%.*]]
638 ; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[IDX_SHL]] to i64
639 ; CHECK-NEXT: [[ADD_PTR_SHL:%.*]] = getelementptr inbounds i16, ptr [[SRC]], i64 [[EXT]]
640 ; CHECK-NEXT: [[C_MAX:%.*]] = icmp slt ptr [[ADD_PTR_SHL]], [[MAX]]
641 ; CHECK-NEXT: ret i1 [[C_MAX]]
643 ; CHECK-NEXT: [[IDX_SHL_1:%.*]] = shl nuw i16 [[IDX]], [[B]]
644 ; CHECK-NEXT: [[EXT_1:%.*]] = zext i16 [[IDX_SHL_1]] to i64
645 ; CHECK-NEXT: [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i16, ptr [[SRC]], i64 [[EXT_1]]
646 ; CHECK-NEXT: [[C_MAX_1:%.*]] = icmp slt ptr [[ADD_PTR_SHL_1]], [[MAX]]
647 ; CHECK-NEXT: ret i1 [[C_MAX_1]]
650 %add.10 = getelementptr inbounds i16, ptr %src, i16 10
651 %c.add.10.max = icmp sgt ptr %add.10, %max
652 br i1 %c.add.10.max, label %exit.1, label %check.idx
658 %cmp = icmp slt i16 %idx, 5
659 br i1 %cmp, label %check.max, label %trap
662 %idx.shl = shl nuw i16 %idx, %B
663 %ext = zext i16 %idx.shl to i64
664 %add.ptr.shl = getelementptr inbounds i16, ptr %src, i64 %ext
665 %c.max = icmp slt ptr %add.ptr.shl, %max
669 %idx.shl.1 = shl nuw i16 %idx, %B
670 %ext.1 = zext i16 %idx.shl.1 to i64
671 %add.ptr.shl.1 = getelementptr inbounds i16, ptr %src, i64 %ext.1
672 %c.max.1 = icmp slt ptr %add.ptr.shl.1, %max
676 declare void @use(i1)