[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / geps.ll
blob4ac15acfa76bcdbc74835a00af0ec7ff3d01dad2
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(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
5 ; CHECK-LABEL: @test.ult(
6 ; CHECK-NEXT:  check.0.min:
7 ; CHECK-NEXT:    [[C_MIN_0:%.*]] = icmp ult i32* [[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 i32* [[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, i32* [[SRC]], align 4
16 ; CHECK-NEXT:    [[ADD_PTR_I36:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
17 ; CHECK-NEXT:    [[C_3_MIN:%.*]] = icmp ult i32* [[ADD_PTR_I36]], [[MIN]]
18 ; CHECK-NEXT:    br i1 false, label [[TRAP]], label [[CHECK_3_MAX:%.*]]
19 ; CHECK:       check.3.max:
20 ; CHECK-NEXT:    [[C_3_MAX:%.*]] = icmp ult i32* [[ADD_PTR_I36]], [[MAX]]
21 ; CHECK-NEXT:    br i1 [[C_3_MAX]], label [[CHECK_1_MIN:%.*]], label [[TRAP]]
22 ; CHECK:       check.1.min:
23 ; CHECK-NEXT:    [[L1:%.*]] = load i32, i32* [[ADD_PTR_I36]], align 4
24 ; CHECK-NEXT:    [[ADD_PTR_I29:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
25 ; CHECK-NEXT:    [[C_1_MIN:%.*]] = icmp ult i32* [[ADD_PTR_I29]], [[MIN]]
26 ; CHECK-NEXT:    br i1 false, label [[TRAP]], label [[CHECK_1_MAX:%.*]]
27 ; CHECK:       check.1.max:
28 ; CHECK-NEXT:    [[C_1_MAX:%.*]] = icmp ult i32* [[ADD_PTR_I29]], [[MAX]]
29 ; CHECK-NEXT:    br i1 true, label [[CHECK_2_MIN:%.*]], label [[TRAP]]
30 ; CHECK:       check.2.min:
31 ; CHECK-NEXT:    [[L2:%.*]] = load i32, i32* [[ADD_PTR_I29]], align 4
32 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
33 ; CHECK-NEXT:    [[C_2_MIN:%.*]] = icmp ult i32* [[ADD_PTR_I]], [[MIN]]
34 ; CHECK-NEXT:    br i1 false, label [[TRAP]], label [[CHECK_2_MAX:%.*]]
35 ; CHECK:       check.2.max:
36 ; CHECK-NEXT:    [[C_2_MAX:%.*]] = icmp ult i32* [[ADD_PTR_I]], [[MAX]]
37 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[TRAP]]
38 ; CHECK:       exit:
39 ; CHECK-NEXT:    [[L3:%.*]] = load i32, i32* [[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]]
45 check.0.min:
46   %c.min.0 = icmp ult i32* %src, %min
47   br i1 %c.min.0, label %trap, label %check.0.max
49 trap:                                             ; preds = %check.2.max, %check.2.min, %check.1.max, %check.1.min, %check.3.max, %check.3.min, %check.0.max, %check.0.min
50   ret i32 10
52 check.0.max:                                      ; preds = %check.0.min
53   %c.max.0 = icmp ult i32* %src, %max
54   br i1 %c.max.0, label %check.3.min, label %trap
56 check.3.min:                                      ; preds = %check.0.max
57   %l0 = load i32, i32* %src, align 4
58   %add.ptr.i36 = getelementptr inbounds i32, i32* %src, i64 3
59   %c.3.min = icmp ult i32* %add.ptr.i36, %min
60   br i1 %c.3.min, label %trap, label %check.3.max
62 check.3.max:                                      ; preds = %check.3.min
63   %c.3.max = icmp ult i32* %add.ptr.i36, %max
64   br i1 %c.3.max, label %check.1.min, label %trap
66 check.1.min:                                      ; preds = %check.3.max
67   %l1 = load i32, i32* %add.ptr.i36, align 4
68   %add.ptr.i29 = getelementptr inbounds i32, i32* %src, i64 1
69   %c.1.min = icmp ult i32* %add.ptr.i29, %min
70   br i1 %c.1.min, label %trap, label %check.1.max
72 check.1.max:                                      ; preds = %check.1.min
73   %c.1.max = icmp ult i32* %add.ptr.i29, %max
74   br i1 %c.1.max, label %check.2.min, label %trap
76 check.2.min:                                      ; preds = %check.1.max
77   %l2 = load i32, i32* %add.ptr.i29, align 4
78   %add.ptr.i = getelementptr inbounds i32, i32* %src, i64 2
79   %c.2.min = icmp ult i32* %add.ptr.i, %min
80   br i1 %c.2.min, label %trap, label %check.2.max
82 check.2.max:                                      ; preds = %check.2.min
83   %c.2.max = icmp ult i32* %add.ptr.i, %max
84   br i1 %c.2.max, label %exit, label %trap
86 exit:                                             ; preds = %check.2.max
87   %l3 = load i32, i32* %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
91   ret i32 %add9
94 ; Same as test.ult, but without inbounds.
95 define i32 @test.ult_no_inbounds(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
96 ; CHECK-LABEL: @test.ult_no_inbounds(
97 ; CHECK-NEXT:  check.0.min:
98 ; CHECK-NEXT:    [[C_MIN_0:%.*]] = icmp ult i32* [[SRC:%.*]], [[MIN:%.*]]
99 ; CHECK-NEXT:    br i1 [[C_MIN_0]], label [[TRAP:%.*]], label [[CHECK_0_MAX:%.*]]
100 ; CHECK:       trap:
101 ; CHECK-NEXT:    ret i32 10
102 ; CHECK:       check.0.max:
103 ; CHECK-NEXT:    [[C_MAX_0:%.*]] = icmp ult i32* [[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, i32* [[SRC]], align 4
107 ; CHECK-NEXT:    [[ADD_PTR_I36:%.*]] = getelementptr i32, i32* [[SRC]], i64 3
108 ; CHECK-NEXT:    [[C_3_MIN:%.*]] = icmp ult i32* [[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 ult i32* [[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, i32* [[ADD_PTR_I36]], align 4
115 ; CHECK-NEXT:    [[ADD_PTR_I29:%.*]] = getelementptr i32, i32* [[SRC]], i64 1
116 ; CHECK-NEXT:    [[C_1_MIN:%.*]] = icmp ult i32* [[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 ult i32* [[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, i32* [[ADD_PTR_I29]], align 4
123 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr i32, i32* [[SRC]], i64 2
124 ; CHECK-NEXT:    [[C_2_MIN:%.*]] = icmp ult i32* [[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 ult i32* [[ADD_PTR_I]], [[MAX]]
128 ; CHECK-NEXT:    br i1 [[C_2_MAX]], label [[EXIT:%.*]], label [[TRAP]]
129 ; CHECK:       exit:
130 ; CHECK-NEXT:    [[L3:%.*]] = load i32, i32* [[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]]
136 check.0.min:
137   %c.min.0 = icmp ult i32* %src, %min
138   br i1 %c.min.0, label %trap, label %check.0.max
140 trap:                                             ; preds = %check.2.max, %check.2.min, %check.1.max, %check.1.min, %check.3.max, %check.3.min, %check.0.max, %check.0.min
141   ret i32 10
143 check.0.max:                                      ; preds = %check.0.min
144   %c.max.0 = icmp ult i32* %src, %max
145   br i1 %c.max.0, label %check.3.min, label %trap
147 check.3.min:                                      ; preds = %check.0.max
148   %l0 = load i32, i32* %src, align 4
149   %add.ptr.i36 = getelementptr i32, i32* %src, i64 3
150   %c.3.min = icmp ult i32* %add.ptr.i36, %min
151   br i1 %c.3.min, label %trap, label %check.3.max
153 check.3.max:                                      ; preds = %check.3.min
154   %c.3.max = icmp ult i32* %add.ptr.i36, %max
155   br i1 %c.3.max, label %check.1.min, label %trap
157 check.1.min:                                      ; preds = %check.3.max
158   %l1 = load i32, i32* %add.ptr.i36, align 4
159   %add.ptr.i29 = getelementptr i32, i32* %src, i64 1
160   %c.1.min = icmp ult i32* %add.ptr.i29, %min
161   br i1 %c.1.min, label %trap, label %check.1.max
163 check.1.max:                                      ; preds = %check.1.min
164   %c.1.max = icmp ult i32* %add.ptr.i29, %max
165   br i1 %c.1.max, label %check.2.min, label %trap
167 check.2.min:                                      ; preds = %check.1.max
168   %l2 = load i32, i32* %add.ptr.i29, align 4
169   %add.ptr.i = getelementptr i32, i32* %src, i64 2
170   %c.2.min = icmp ult i32* %add.ptr.i, %min
171   br i1 %c.2.min, label %trap, label %check.2.max
173 check.2.max:                                      ; preds = %check.2.min
174   %c.2.max = icmp ult i32* %add.ptr.i, %max
175   br i1 %c.2.max, label %exit, label %trap
177 exit:                                             ; preds = %check.2.max
178   %l3 = load i32, i32* %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
182   ret i32 %add9
186 define void @test.not.uge.ult(i8* %start, i8* %low, i8* %high) {
187 ; CHECK-LABEL: @test.not.uge.ult(
188 ; CHECK-NEXT:  entry:
189 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, i8* [[START:%.*]], i64 3
190 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8* [[ADD_PTR_I]], [[HIGH:%.*]]
191 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
192 ; CHECK:       if.then:
193 ; CHECK-NEXT:    ret void
194 ; CHECK:       if.end:
195 ; CHECK-NEXT:    [[T_0:%.*]] = icmp ult i8* [[START]], [[HIGH]]
196 ; CHECK-NEXT:    call void @use(i1 true)
197 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 1
198 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ult i8* [[START_1]], [[HIGH]]
199 ; CHECK-NEXT:    call void @use(i1 true)
200 ; CHECK-NEXT:    [[START_2:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 2
201 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ult i8* [[START_2]], [[HIGH]]
202 ; CHECK-NEXT:    call void @use(i1 true)
203 ; CHECK-NEXT:    [[START_3:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 3
204 ; CHECK-NEXT:    [[T_3:%.*]] = icmp ult i8* [[START_3]], [[HIGH]]
205 ; CHECK-NEXT:    call void @use(i1 true)
206 ; CHECK-NEXT:    [[START_4:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 4
207 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ult i8* [[START_4]], [[HIGH]]
208 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
209 ; CHECK-NEXT:    ret void
211 entry:
212   %add.ptr.i = getelementptr inbounds i8, i8* %start, i64 3
213   %c.1 = icmp uge i8* %add.ptr.i, %high
214   br i1 %c.1, label %if.then, label %if.end
216 if.then:                                          ; preds = %entry
217   ret void
219 if.end:                                           ; preds = %entry
220   %t.0 = icmp ult i8* %start, %high
221   call void @use(i1 %t.0)
222   %start.1 = getelementptr inbounds i8, i8* %start, i64 1
223   %t.1 = icmp ult i8* %start.1, %high
224   call void @use(i1 %t.1)
225   %start.2 = getelementptr inbounds i8, i8* %start, i64 2
226   %t.2 = icmp ult i8* %start.2, %high
227   call void @use(i1 %t.2)
228   %start.3 = getelementptr inbounds i8, i8* %start, i64 3
229   %t.3 = icmp ult i8* %start.3, %high
230   call void @use(i1 %t.3)
231   %start.4 = getelementptr inbounds i8, i8* %start, i64 4
232   %c.4 = icmp ult i8* %start.4, %high
233   call void @use(i1 %c.4)
234   ret void
237 ; Same as test.not.uge.ult, but without inbounds GEPs.
238 define void @test.not.uge.ult_no_inbounds(i8* %start, i8* %low, i8* %high) {
239 ; CHECK-LABEL: @test.not.uge.ult_no_inbounds(
240 ; CHECK-NEXT:  entry:
241 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr i8, i8* [[START:%.*]], i64 3
242 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8* [[ADD_PTR_I]], [[HIGH:%.*]]
243 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
244 ; CHECK:       if.then:
245 ; CHECK-NEXT:    ret void
246 ; CHECK:       if.end:
247 ; CHECK-NEXT:    [[T_0:%.*]] = icmp ult i8* [[START]], [[HIGH]]
248 ; CHECK-NEXT:    call void @use(i1 [[T_0]])
249 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr i8, i8* [[START]], i64 1
250 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ult i8* [[START_1]], [[HIGH]]
251 ; CHECK-NEXT:    call void @use(i1 [[T_1]])
252 ; CHECK-NEXT:    [[START_2:%.*]] = getelementptr i8, i8* [[START]], i64 2
253 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ult i8* [[START_2]], [[HIGH]]
254 ; CHECK-NEXT:    call void @use(i1 [[T_2]])
255 ; CHECK-NEXT:    [[START_3:%.*]] = getelementptr i8, i8* [[START]], i64 3
256 ; CHECK-NEXT:    [[T_3:%.*]] = icmp ult i8* [[START_3]], [[HIGH]]
257 ; CHECK-NEXT:    call void @use(i1 [[T_3]])
258 ; CHECK-NEXT:    [[START_4:%.*]] = getelementptr i8, i8* [[START]], i64 4
259 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ult i8* [[START_4]], [[HIGH]]
260 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
261 ; CHECK-NEXT:    ret void
263 entry:
264   %add.ptr.i = getelementptr i8, i8* %start, i64 3
265   %c.1 = icmp uge i8* %add.ptr.i, %high
266   br i1 %c.1, label %if.then, label %if.end
268 if.then:                                          ; preds = %entry
269   ret void
271 if.end:                                           ; preds = %entry
272   %t.0 = icmp ult i8* %start, %high
273   call void @use(i1 %t.0)
274   %start.1 = getelementptr i8, i8* %start, i64 1
275   %t.1 = icmp ult i8* %start.1, %high
276   call void @use(i1 %t.1)
277   %start.2 = getelementptr i8, i8* %start, i64 2
278   %t.2 = icmp ult i8* %start.2, %high
279   call void @use(i1 %t.2)
280   %start.3 = getelementptr i8, i8* %start, i64 3
281   %t.3 = icmp ult i8* %start.3, %high
282   call void @use(i1 %t.3)
283   %start.4 = getelementptr i8, i8* %start, i64 4
284   %c.4 = icmp ult i8* %start.4, %high
285   call void @use(i1 %c.4)
286   ret void
289 define void @test.not.uge.ule(i8* %start, i8* %low, i8* %high) {
290 ; CHECK-LABEL: @test.not.uge.ule(
291 ; CHECK-NEXT:  entry:
292 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, i8* [[START:%.*]], i64 3
293 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8* [[ADD_PTR_I]], [[HIGH:%.*]]
294 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
295 ; CHECK:       if.then:
296 ; CHECK-NEXT:    ret void
297 ; CHECK:       if.end:
298 ; CHECK-NEXT:    [[T_0:%.*]] = icmp ule i8* [[START]], [[HIGH]]
299 ; CHECK-NEXT:    call void @use(i1 true)
300 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 1
301 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8* [[START_1]], [[HIGH]]
302 ; CHECK-NEXT:    call void @use(i1 true)
303 ; CHECK-NEXT:    [[START_2:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 2
304 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8* [[START_2]], [[HIGH]]
305 ; CHECK-NEXT:    call void @use(i1 true)
306 ; CHECK-NEXT:    [[START_3:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 3
307 ; CHECK-NEXT:    [[T_3:%.*]] = icmp ule i8* [[START_3]], [[HIGH]]
308 ; CHECK-NEXT:    call void @use(i1 true)
309 ; CHECK-NEXT:    [[START_4:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 4
310 ; CHECK-NEXT:    [[T_4:%.*]] = icmp ule i8* [[START_4]], [[HIGH]]
311 ; CHECK-NEXT:    call void @use(i1 true)
312 ; CHECK-NEXT:    [[START_5:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 5
313 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ule i8* [[START_5]], [[HIGH]]
314 ; CHECK-NEXT:    call void @use(i1 [[C_5]])
315 ; CHECK-NEXT:    ret void
317 entry:
318   %add.ptr.i = getelementptr inbounds i8, i8* %start, i64 3
319   %c.1 = icmp uge i8* %add.ptr.i, %high
320   br i1 %c.1, label %if.then, label %if.end
322 if.then:                                          ; preds = %entry
323   ret void
325 if.end:                                           ; preds = %entry
326   %t.0 = icmp ule i8* %start, %high
327   call void @use(i1 %t.0)
328   %start.1 = getelementptr inbounds i8, i8* %start, i64 1
329   %t.1 = icmp ule i8* %start.1, %high
330   call void @use(i1 %t.1)
331   %start.2 = getelementptr inbounds i8, i8* %start, i64 2
332   %t.2 = icmp ule i8* %start.2, %high
333   call void @use(i1 %t.2)
334   %start.3 = getelementptr inbounds i8, i8* %start, i64 3
335   %t.3 = icmp ule i8* %start.3, %high
336   call void @use(i1 %t.3)
337   %start.4 = getelementptr inbounds i8, i8* %start, i64 4
338   %t.4 = icmp ule i8* %start.4, %high
339   call void @use(i1 %t.4)
341   %start.5 = getelementptr inbounds i8, i8* %start, i64 5
342   %c.5 = icmp ule i8* %start.5, %high
343   call void @use(i1 %c.5)
345   ret void
348 define void @test.not.uge.ugt(i8* %start, i8* %low, i8* %high) {
349 ; CHECK-LABEL: @test.not.uge.ugt(
350 ; CHECK-NEXT:  entry:
351 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, i8* [[START:%.*]], i64 3
352 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8* [[ADD_PTR_I]], [[HIGH:%.*]]
353 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
354 ; CHECK:       if.then:
355 ; CHECK-NEXT:    ret void
356 ; CHECK:       if.end:
357 ; CHECK-NEXT:    [[F_0:%.*]] = icmp ugt i8* [[START]], [[HIGH]]
358 ; CHECK-NEXT:    call void @use(i1 false)
359 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 1
360 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ugt i8* [[START_1]], [[HIGH]]
361 ; CHECK-NEXT:    call void @use(i1 false)
362 ; CHECK-NEXT:    [[START_2:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 2
363 ; CHECK-NEXT:    [[F_2:%.*]] = icmp ugt i8* [[START_2]], [[HIGH]]
364 ; CHECK-NEXT:    call void @use(i1 false)
365 ; CHECK-NEXT:    [[START_3:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 3
366 ; CHECK-NEXT:    [[F_3:%.*]] = icmp ugt i8* [[START_3]], [[HIGH]]
367 ; CHECK-NEXT:    call void @use(i1 false)
368 ; CHECK-NEXT:    [[START_4:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 4
369 ; CHECK-NEXT:    [[F_4:%.*]] = icmp ugt i8* [[START_4]], [[HIGH]]
370 ; CHECK-NEXT:    call void @use(i1 false)
371 ; CHECK-NEXT:    [[START_5:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 5
372 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8* [[START_5]], [[HIGH]]
373 ; CHECK-NEXT:    call void @use(i1 [[C_5]])
374 ; CHECK-NEXT:    ret void
376 entry:
377   %add.ptr.i = getelementptr inbounds i8, i8* %start, i64 3
378   %c.1 = icmp uge i8* %add.ptr.i, %high
379   br i1 %c.1, label %if.then, label %if.end
381 if.then:                                          ; preds = %entry
382   ret void
384 if.end:                                           ; preds = %entry
385   %f.0 = icmp ugt i8* %start, %high
386   call void @use(i1 %f.0)
388   %start.1 = getelementptr inbounds i8, i8* %start, i64 1
389   %f.1 = icmp ugt i8* %start.1, %high
390   call void @use(i1 %f.1)
392   %start.2 = getelementptr inbounds i8, i8* %start, i64 2
393   %f.2 = icmp ugt i8* %start.2, %high
394   call void @use(i1 %f.2)
396   %start.3 = getelementptr inbounds i8, i8* %start, i64 3
397   %f.3 = icmp ugt i8* %start.3, %high
398   call void @use(i1 %f.3)
400   %start.4 = getelementptr inbounds i8, i8* %start, i64 4
401   %f.4 = icmp ugt i8* %start.4, %high
402   call void @use(i1 %f.4)
404   %start.5 = getelementptr inbounds i8, i8* %start, i64 5
405   %c.5 = icmp ugt i8* %start.5, %high
406   call void @use(i1 %c.5)
408   ret void
411 define void @test.not.uge.uge(i8* %start, i8* %low, i8* %high) {
412 ; CHECK-LABEL: @test.not.uge.uge(
413 ; CHECK-NEXT:  entry:
414 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, i8* [[START:%.*]], i64 3
415 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8* [[ADD_PTR_I]], [[HIGH:%.*]]
416 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
417 ; CHECK:       if.then:
418 ; CHECK-NEXT:    ret void
419 ; CHECK:       if.end:
420 ; CHECK-NEXT:    [[F_0:%.*]] = icmp ugt i8* [[START]], [[HIGH]]
421 ; CHECK-NEXT:    call void @use(i1 false)
422 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 1
423 ; CHECK-NEXT:    [[F_1:%.*]] = icmp uge i8* [[START_1]], [[HIGH]]
424 ; CHECK-NEXT:    call void @use(i1 false)
425 ; CHECK-NEXT:    [[START_2:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 2
426 ; CHECK-NEXT:    [[F_2:%.*]] = icmp uge i8* [[START_2]], [[HIGH]]
427 ; CHECK-NEXT:    call void @use(i1 false)
428 ; CHECK-NEXT:    [[START_3:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 3
429 ; CHECK-NEXT:    [[F_3:%.*]] = icmp uge i8* [[START_3]], [[HIGH]]
430 ; CHECK-NEXT:    call void @use(i1 false)
431 ; CHECK-NEXT:    [[START_4:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 4
432 ; CHECK-NEXT:    [[C_4:%.*]] = icmp uge i8* [[START_4]], [[HIGH]]
433 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
434 ; CHECK-NEXT:    [[START_5:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 5
435 ; CHECK-NEXT:    [[C_5:%.*]] = icmp uge i8* [[START_5]], [[HIGH]]
436 ; CHECK-NEXT:    call void @use(i1 [[C_5]])
437 ; CHECK-NEXT:    ret void
439 entry:
440   %add.ptr.i = getelementptr inbounds i8, i8* %start, i64 3
441   %c.1 = icmp uge i8* %add.ptr.i, %high
442   br i1 %c.1, label %if.then, label %if.end
444 if.then:                                          ; preds = %entry
445   ret void
447 if.end:                                           ; preds = %entry
448   %f.0 = icmp ugt i8* %start, %high
449   call void @use(i1 %f.0)
451   %start.1 = getelementptr inbounds i8, i8* %start, i64 1
452   %f.1 = icmp uge i8* %start.1, %high
453   call void @use(i1 %f.1)
455   %start.2 = getelementptr inbounds i8, i8* %start, i64 2
456   %f.2 = icmp uge i8* %start.2, %high
457   call void @use(i1 %f.2)
459   %start.3 = getelementptr inbounds i8, i8* %start, i64 3
460   %f.3 = icmp uge i8* %start.3, %high
461   call void @use(i1 %f.3)
463   %start.4 = getelementptr inbounds i8, i8* %start, i64 4
464   %c.4 = icmp uge i8* %start.4, %high
465   call void @use(i1 %c.4)
467   %start.5 = getelementptr inbounds i8, i8* %start, i64 5
468   %c.5 = icmp uge i8* %start.5, %high
469   call void @use(i1 %c.5)
471   ret void
474 define void @test.not.uge.uge.nonconst(i8* %start, i8* %low, i8* %high, i8 %off) {
475 ; CHECK-LABEL: @test.not.uge.uge.nonconst(
476 ; CHECK-NEXT:  entry:
477 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, i8* [[START:%.*]], i8 [[OFF:%.*]]
478 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8* [[ADD_PTR_I]], [[HIGH:%.*]]
479 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
480 ; CHECK:       if.then:
481 ; CHECK-NEXT:    [[START_OFF_2:%.*]] = getelementptr inbounds i8, i8* [[START]], i8 [[OFF]]
482 ; CHECK-NEXT:    [[T_0:%.*]] = icmp uge i8* [[START_OFF_2]], [[HIGH]]
483 ; CHECK-NEXT:    call void @use(i1 true)
484 ; CHECK-NEXT:    ret void
485 ; CHECK:       if.end:
486 ; CHECK-NEXT:    [[START_1:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 1
487 ; CHECK-NEXT:    [[C_0:%.*]] = icmp uge i8* [[START_1]], [[HIGH]]
488 ; CHECK-NEXT:    call void @use(i1 [[C_0]])
489 ; CHECK-NEXT:    [[START_OFF:%.*]] = getelementptr inbounds i8, i8* [[START]], i8 [[OFF]]
490 ; CHECK-NEXT:    [[F_0:%.*]] = icmp uge i8* [[START_OFF]], [[HIGH]]
491 ; CHECK-NEXT:    call void @use(i1 false)
492 ; CHECK-NEXT:    ret void
494 entry:
495   %add.ptr.i = getelementptr inbounds i8, i8* %start, i8 %off
496   %c.1 = icmp uge i8* %add.ptr.i, %high
497   br i1 %c.1, label %if.then, label %if.end
499 if.then:                                          ; preds = %entry
500   %start.off.2 = getelementptr inbounds i8, i8* %start, i8 %off
501   %t.0 = icmp uge i8* %start.off.2, %high
502   call void @use(i1 %t.0)
504   ret void
506 if.end:                                           ; preds = %entry
507   %start.1 = getelementptr inbounds i8, i8* %start, i64 1
508   %c.0 = icmp uge i8* %start.1, %high
509   call void @use(i1 %c.0)
511   %start.off = getelementptr inbounds i8, i8* %start, i8 %off
512   %f.0 = icmp uge i8* %start.off, %high
513   call void @use(i1 %f.0)
515   ret void
518 ; Test which requires decomposing GEP %ptr, SHL().
519 define void @test.ult.gep.shl(i32* readonly %src, i32* readnone %max, i8 %idx) {
520 ; CHECK-LABEL: @test.ult.gep.shl(
521 ; CHECK-NEXT:  check.0.min:
522 ; CHECK-NEXT:    [[ADD_10:%.*]] = getelementptr inbounds i32, i32* [[SRC:%.*]], i32 10
523 ; CHECK-NEXT:    [[C_ADD_10_MAX:%.*]] = icmp ugt i32* [[ADD_10]], [[MAX:%.*]]
524 ; CHECK-NEXT:    br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]]
525 ; CHECK:       trap:
526 ; CHECK-NEXT:    ret void
527 ; CHECK:       check.idx:
528 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[IDX:%.*]], 5
529 ; CHECK-NEXT:    br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]]
530 ; CHECK:       check.max:
531 ; CHECK-NEXT:    [[IDX_SHL_1:%.*]] = shl nuw i8 [[IDX]], 1
532 ; CHECK-NEXT:    [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i8 [[IDX_SHL_1]]
533 ; CHECK-NEXT:    [[C_MAX_0:%.*]] = icmp ult i32* [[ADD_PTR_SHL_1]], [[MAX]]
534 ; CHECK-NEXT:    call void @use(i1 true)
535 ; CHECK-NEXT:    [[IDX_SHL_2:%.*]] = shl nuw i8 [[IDX]], 2
536 ; CHECK-NEXT:    [[ADD_PTR_SHL_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i8 [[IDX_SHL_2]]
537 ; CHECK-NEXT:    [[C_MAX_1:%.*]] = icmp ult i32* [[ADD_PTR_SHL_2]], [[MAX]]
538 ; CHECK-NEXT:    call void @use(i1 [[C_MAX_1]])
539 ; CHECK-NEXT:    [[IDX_SHL_NOT_NUW:%.*]] = shl i8 [[IDX]], 1
540 ; CHECK-NEXT:    [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i8 [[IDX_SHL_NOT_NUW]]
541 ; CHECK-NEXT:    [[C_MAX_2:%.*]] = icmp ult i32* [[ADD_PTR_SHL_NOT_NUW]], [[MAX]]
542 ; CHECK-NEXT:    call void @use(i1 [[C_MAX_2]])
543 ; CHECK-NEXT:    [[IDX_SHL_3:%.*]] = shl nuw i8 [[IDX]], 3
544 ; CHECK-NEXT:    [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i8 [[IDX_SHL_3]]
545 ; CHECK-NEXT:    [[C_MAX_3:%.*]] = icmp ult i32* [[ADD_PTR_SHL_3]], [[MAX]]
546 ; CHECK-NEXT:    call void @use(i1 [[C_MAX_3]])
547 ; CHECK-NEXT:    ret void
549 check.0.min:
550   %add.10 = getelementptr inbounds i32, i32* %src, i32 10
551   %c.add.10.max = icmp ugt i32* %add.10, %max
552   br i1 %c.add.10.max, label %trap, label %check.idx
554 trap:
555   ret void
557 check.idx:                                      ; preds = %check.0.min
558   %cmp = icmp ult i8 %idx, 5
559   br i1 %cmp, label %check.max, label %trap
561 check.max:                                      ; preds = %check.0.min
562   %idx.shl.1 = shl nuw i8 %idx, 1
563   %add.ptr.shl.1 = getelementptr inbounds i32, i32* %src, i8 %idx.shl.1
564   %c.max.0 = icmp ult i32* %add.ptr.shl.1, %max
565   call void @use(i1 %c.max.0)
567   %idx.shl.2 = shl nuw i8 %idx, 2
568   %add.ptr.shl.2 = getelementptr inbounds i32, i32* %src, i8 %idx.shl.2
569   %c.max.1 = icmp ult i32* %add.ptr.shl.2, %max
570   call void @use(i1 %c.max.1)
572   %idx.shl.not.nuw = shl i8 %idx, 1
573   %add.ptr.shl.not.nuw = getelementptr inbounds i32, i32* %src, i8 %idx.shl.not.nuw
574   %c.max.2 = icmp ult i32* %add.ptr.shl.not.nuw, %max
575   call void @use(i1 %c.max.2)
577   %idx.shl.3 = shl nuw i8 %idx, 3
578   %add.ptr.shl.3 = getelementptr inbounds i32, i32* %src, i8 %idx.shl.3
579   %c.max.3 = icmp ult i32* %add.ptr.shl.3, %max
580   call void @use(i1 %c.max.3)
582   ret void
585 ; Test which requires decomposing GEP %ptr, ZEXT(SHL()).
586 define void @test.ult.gep.shl.zext(i32* readonly %src, i32* readnone %max, i32 %idx, i32 %j) {
587 ; CHECK-LABEL: @test.ult.gep.shl.zext(
588 ; CHECK-NEXT:  check.0.min:
589 ; CHECK-NEXT:    [[ADD_10:%.*]] = getelementptr inbounds i32, i32* [[SRC:%.*]], i32 10
590 ; CHECK-NEXT:    [[C_ADD_10_MAX:%.*]] = icmp ugt i32* [[ADD_10]], [[MAX:%.*]]
591 ; CHECK-NEXT:    br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]]
592 ; CHECK:       trap:
593 ; CHECK-NEXT:    ret void
594 ; CHECK:       check.idx:
595 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 5
596 ; CHECK-NEXT:    br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]]
597 ; CHECK:       check.max:
598 ; CHECK-NEXT:    [[IDX_SHL:%.*]] = shl nuw i32 [[IDX]], 1
599 ; CHECK-NEXT:    [[EXT_1:%.*]] = zext i32 [[IDX_SHL]] to i64
600 ; CHECK-NEXT:    [[ADD_PTR_SHL:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 [[EXT_1]]
601 ; CHECK-NEXT:    [[C_MAX_0:%.*]] = icmp ult i32* [[ADD_PTR_SHL]], [[MAX]]
602 ; CHECK-NEXT:    call void @use(i1 true)
603 ; CHECK-NEXT:    [[IDX_SHL_NOT_NUW:%.*]] = shl i32 [[IDX]], 1
604 ; CHECK-NEXT:    [[EXT_2:%.*]] = zext i32 [[IDX_SHL_NOT_NUW]] to i64
605 ; CHECK-NEXT:    [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 [[EXT_2]]
606 ; CHECK-NEXT:    [[C_MAX_1:%.*]] = icmp ult i32* [[ADD_PTR_SHL_NOT_NUW]], [[MAX]]
607 ; CHECK-NEXT:    call void @use(i1 [[C_MAX_1]])
608 ; CHECK-NEXT:    [[IDX_SHL_3:%.*]] = shl nuw i32 [[IDX]], 2
609 ; CHECK-NEXT:    [[EXT_3:%.*]] = zext i32 [[IDX_SHL_3]] to i64
610 ; CHECK-NEXT:    [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 [[EXT_3]]
611 ; CHECK-NEXT:    [[C_MAX_2:%.*]] = icmp ult i32* [[ADD_PTR_SHL_3]], [[MAX]]
612 ; CHECK-NEXT:    call void @use(i1 [[C_MAX_2]])
613 ; CHECK-NEXT:    ret void
615 check.0.min:
616   %add.10 = getelementptr inbounds i32, i32* %src, i32 10
617   %c.add.10.max = icmp ugt i32* %add.10, %max
618   br i1 %c.add.10.max, label %trap, label %check.idx
620 trap:
621   ret void
623 check.idx:                                      ; preds = %check.0.min
624   %cmp = icmp ult i32 %idx, 5
625   br i1 %cmp, label %check.max, label %trap
627 check.max:                                      ; preds = %check.0.min
628   %idx.shl = shl nuw i32 %idx, 1
629   %ext.1 = zext i32 %idx.shl to i64
630   %add.ptr.shl = getelementptr inbounds i32, i32* %src, i64 %ext.1
631   %c.max.0 = icmp ult i32* %add.ptr.shl, %max
632   call void @use(i1 %c.max.0)
634   %idx.shl.not.nuw = shl i32 %idx, 1
635   %ext.2 = zext i32 %idx.shl.not.nuw to i64
636   %add.ptr.shl.not.nuw = getelementptr inbounds i32, i32* %src, i64 %ext.2
637   %c.max.1 = icmp ult i32* %add.ptr.shl.not.nuw, %max
638   call void @use(i1 %c.max.1)
640   %idx.shl.3 = shl nuw i32 %idx, 2
641   %ext.3 = zext i32 %idx.shl.3 to i64
642   %add.ptr.shl.3 = getelementptr inbounds i32, i32* %src, i64 %ext.3
643   %c.max.2 = icmp ult i32* %add.ptr.shl.3, %max
644   call void @use(i1 %c.max.2)
646   ret void
649 ; Make sure non-constant shift amounts are handled correctly.
650 define i1 @test.ult.gep.shl.nonconst.zext(i16 %B, i16* readonly %src, i16* readnone %max, i16 %idx, i16 %j) {
651 ; CHECK-LABEL: @test.ult.gep.shl.nonconst.zext(
652 ; CHECK-NEXT:  check.0.min:
653 ; CHECK-NEXT:    [[ADD_10:%.*]] = getelementptr inbounds i16, i16* [[SRC:%.*]], i16 10
654 ; CHECK-NEXT:    [[C_ADD_10_MAX:%.*]] = icmp ugt i16* [[ADD_10]], [[MAX:%.*]]
655 ; CHECK-NEXT:    br i1 [[C_ADD_10_MAX]], label [[EXIT_1:%.*]], label [[CHECK_IDX:%.*]]
656 ; CHECK:       exit.1:
657 ; CHECK-NEXT:    ret i1 true
658 ; CHECK:       check.idx:
659 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[IDX:%.*]], 5
660 ; CHECK-NEXT:    br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP:%.*]]
661 ; CHECK:       check.max:
662 ; CHECK-NEXT:    [[IDX_SHL:%.*]] = shl nuw i16 [[IDX]], [[B:%.*]]
663 ; CHECK-NEXT:    [[EXT:%.*]] = zext i16 [[IDX_SHL]] to i64
664 ; CHECK-NEXT:    [[ADD_PTR_SHL:%.*]] = getelementptr inbounds i16, i16* [[SRC]], i64 [[EXT]]
665 ; CHECK-NEXT:    [[C_MAX:%.*]] = icmp ult i16* [[ADD_PTR_SHL]], [[MAX]]
666 ; CHECK-NEXT:    ret i1 [[C_MAX]]
667 ; CHECK:       trap:
668 ; CHECK-NEXT:    [[IDX_SHL_1:%.*]] = shl nuw i16 [[IDX]], [[B]]
669 ; CHECK-NEXT:    [[EXT_1:%.*]] = zext i16 [[IDX_SHL_1]] to i64
670 ; CHECK-NEXT:    [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i16, i16* [[SRC]], i64 [[EXT_1]]
671 ; CHECK-NEXT:    [[C_MAX_1:%.*]] = icmp ult i16* [[ADD_PTR_SHL_1]], [[MAX]]
672 ; CHECK-NEXT:    ret i1 [[C_MAX_1]]
674 check.0.min:
675   %add.10 = getelementptr inbounds i16, i16* %src, i16 10
676   %c.add.10.max = icmp ugt i16* %add.10, %max
677   br i1 %c.add.10.max, label %exit.1, label %check.idx
679 exit.1:
680   ret i1 true
683 check.idx:                                        ; preds = %check.0.min
684   %cmp = icmp ult i16 %idx, 5
685   br i1 %cmp, label %check.max, label %trap
687 check.max:                                        ; preds = %check.idx
688   %idx.shl = shl nuw i16 %idx, %B
689   %ext = zext i16 %idx.shl to i64
690   %add.ptr.shl = getelementptr inbounds i16, i16* %src, i64 %ext
691   %c.max = icmp ult i16* %add.ptr.shl, %max
692   ret i1 %c.max
694 trap:                                             ; preds = %check.idx, %check.0.min
695   %idx.shl.1 = shl nuw i16 %idx, %B
696   %ext.1 = zext i16 %idx.shl.1 to i64
697   %add.ptr.shl.1 = getelementptr inbounds i16, i16* %src, i64 %ext.1
698   %c.max.1 = icmp ult i16* %add.ptr.shl.1, %max
699   ret i1 %c.max.1
702 declare void @use(i1)