[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / gep-arithmetic-add.ll
blob52adc78b4e159bfbfd0d222d234aa767ee3129ee
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 declare void @llvm.assume(i1 noundef) #0
6 define i1 @n_unknown(ptr %dst, i32 %n, i32 %i) {
7 ; CHECK-LABEL: @n_unknown(
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[N:%.*]], -1
10 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[SUB]] to i64
11 ; CHECK-NEXT:    [[PTR_N_SUB_1:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 [[IDXPROM]]
12 ; CHECK-NEXT:    [[CMP_PTR_DST:%.*]] = icmp uge ptr [[PTR_N_SUB_1]], [[DST]]
13 ; CHECK-NEXT:    br i1 [[CMP_PTR_DST]], label [[PRE_BB_2:%.*]], label [[EXIT:%.*]]
14 ; CHECK:       exit:
15 ; CHECK-NEXT:    ret i1 false
16 ; CHECK:       pre.bb.2:
17 ; CHECK-NEXT:    br i1 true, label [[TGT_BB:%.*]], label [[EXIT]]
18 ; CHECK:       tgt.bb:
19 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I:%.*]], [[N]]
20 ; CHECK-NEXT:    ret i1 [[CMP1]]
22 entry:
23   %sub = add i32 %n, -1
24   %idxprom = zext i32 %sub to i64
25   %ptr.n.sub.1 = getelementptr i32, ptr %dst, i64 %idxprom
26   %cmp.ptr.dst = icmp uge ptr %ptr.n.sub.1, %dst
27   br i1 %cmp.ptr.dst, label %pre.bb.2, label %exit
29 exit:
30   ret i1 false
32 pre.bb.2:
33   %pre.2 = icmp uge i32 %i, 0
34   br i1 %pre.2, label %tgt.bb, label %exit
36 tgt.bb:
37   %cmp1 = icmp ult i32 %i, %n
38   ret i1 %cmp1
41 define i1 @n_known_zero_due_to_nuw(ptr %dst, i32 %n, i32 %i) {
42 ; CHECK-LABEL: @n_known_zero_due_to_nuw(
43 ; CHECK-NEXT:  entry:
44 ; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[N:%.*]], -1
45 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[SUB]] to i64
46 ; CHECK-NEXT:    [[PTR_N_SUB_1:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 [[IDXPROM]]
47 ; CHECK-NEXT:    [[CMP_PTR_DST:%.*]] = icmp uge ptr [[PTR_N_SUB_1]], [[DST]]
48 ; CHECK-NEXT:    br i1 [[CMP_PTR_DST]], label [[PRE_BB_2:%.*]], label [[EXIT:%.*]]
49 ; CHECK:       exit:
50 ; CHECK-NEXT:    ret i1 false
51 ; CHECK:       pre.bb.2:
52 ; CHECK-NEXT:    br i1 true, label [[TGT_BB:%.*]], label [[EXIT]]
53 ; CHECK:       tgt.bb:
54 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I:%.*]], [[N]]
55 ; CHECK-NEXT:    ret i1 [[CMP1]]
57 entry:
58   %sub = add i32 %n, -1
59   %idxprom = zext i32 %sub to i64
60   %ptr.n.sub.1 = getelementptr i32, ptr %dst, i64 %idxprom
61   %cmp.ptr.dst = icmp uge ptr %ptr.n.sub.1, %dst
62   br i1 %cmp.ptr.dst, label %pre.bb.2, label %exit
64 exit:
65   ret i1 false
67 pre.bb.2:
68   %pre.2 = icmp uge i32 %i, 0
69   br i1 %pre.2, label %tgt.bb, label %exit
71 tgt.bb:
72   %cmp1 = icmp ult i32 %i, %n
73   ret i1 %cmp1
76 define i4 @inc_ptr_N_could_be_negative(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
77 ; CHECK-LABEL: @inc_ptr_N_could_be_negative(
78 ; CHECK-NEXT:  entry:
79 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
80 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
81 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
82 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
83 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
84 ; CHECK:       trap.bb:
85 ; CHECK-NEXT:    ret i4 2
86 ; CHECK:       step.check:
87 ; CHECK-NEXT:    [[NEXT:%.*]] = add nuw nsw i8 [[STEP:%.*]], 2
88 ; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i8 [[NEXT]], [[N]]
89 ; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
90 ; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
91 ; CHECK:       ptr.check:
92 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
93 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
94 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
95 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
96 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
97 ; CHECK:       exit:
98 ; CHECK-NEXT:    ret i4 3
100 entry:
101   %src.end = getelementptr inbounds i8, ptr %src, i8 %N
102   %cmp.src.start = icmp ult ptr %src, %lower
103   %cmp.src.end = icmp uge ptr %src.end, %upper
104   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
105   br i1 %or.precond.0, label %trap.bb, label %step.check
107 trap.bb:
108   ret i4 2
110 step.check:
111   %step.pos = icmp uge i8 %step, 0
112   %next = add nuw nsw i8 %step, 2
113   %step.ult.N = icmp ult i8 %next, %N
114   %and.step = and i1 %step.pos, %step.ult.N
115   br i1 %and.step, label %ptr.check, label %exit
117 ptr.check:
118   %src.step = getelementptr inbounds i8, ptr %src, i8 %step
119   %cmp.step.start = icmp ult ptr %src.step, %lower
120   %cmp.step.end = icmp uge ptr %src.step, %upper
121   %or.check = or i1 %cmp.step.start, %cmp.step.end
122   br i1 %or.check, label %trap.bb, label %exit
124 exit:
125   ret i4 3
128 define i4 @inc_ptr_src_uge_end(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
129 ; CHECK-LABEL: @inc_ptr_src_uge_end(
130 ; CHECK-NEXT:  entry:
131 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
132 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
133 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
134 ; CHECK-NEXT:    [[CMP_OVERFLOW:%.*]] = icmp ugt ptr [[SRC]], [[SRC_END]]
135 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
136 ; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]]
137 ; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
138 ; CHECK:       trap.bb:
139 ; CHECK-NEXT:    ret i4 2
140 ; CHECK:       step.check:
141 ; CHECK-NEXT:    [[NEXT:%.*]] = add nuw nsw i16 [[STEP:%.*]], 2
142 ; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i16 [[NEXT]], [[N]]
143 ; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
144 ; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
145 ; CHECK:       ptr.check:
146 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
147 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
148 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
149 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
150 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
151 ; CHECK:       exit:
152 ; CHECK-NEXT:    ret i4 3
154 entry:
155   %src.end = getelementptr inbounds i8, ptr %src, i16 %N
156   %cmp.src.start = icmp ult ptr %src, %lower
157   %cmp.src.end = icmp uge ptr %src.end, %upper
158   %cmp.overflow = icmp ugt ptr %src, %src.end
159   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
160   %or.precond.1 = or i1 %or.precond.0, %cmp.overflow
161   br i1 %or.precond.1, label %trap.bb, label %step.check
163 trap.bb:
164   ret i4 2
166 step.check:
167   %step.pos = icmp uge i16 %step, 0
168   %next = add nuw nsw i16 %step, 2
169   %step.ult.N = icmp ult i16 %next, %N
170   %and.step = and i1 %step.pos, %step.ult.N
171   br i1 %and.step, label %ptr.check, label %exit
173 ptr.check:
174   %src.step = getelementptr inbounds i8, ptr %src, i16 %step
175   %cmp.step.start = icmp ult ptr %src.step, %lower
176   %cmp.step.end = icmp uge ptr %src.step, %upper
177   %or.check = or i1 %cmp.step.start, %cmp.step.end
178   br i1 %or.check, label %trap.bb, label %exit
180 exit:
181   ret i4 3
184 define i4 @inc_ptr_src_uge_end_no_nsw_add(ptr %src, ptr %lower, ptr %upper, i16 %idx, i16 %N, i16 %step) {
185 ; CHECK-LABEL: @inc_ptr_src_uge_end_no_nsw_add(
186 ; CHECK-NEXT:  entry.1:
187 ; CHECK-NEXT:    [[IDX_POS:%.*]] = icmp sge i16 [[IDX:%.*]], 0
188 ; CHECK-NEXT:    br i1 [[IDX_POS]], label [[ENTRY:%.*]], label [[TRAP_BB:%.*]]
189 ; CHECK:       entry:
190 ; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[IDX]]
191 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC_IDX]], [[LOWER:%.*]]
192 ; CHECK-NEXT:    br i1 [[CMP_SRC_START]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
193 ; CHECK:       trap.bb:
194 ; CHECK-NEXT:    ret i4 2
195 ; CHECK:       step.check:
196 ; CHECK-NEXT:    [[NEXT:%.*]] = add i16 [[IDX]], 2
197 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[NEXT]]
198 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
199 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER:%.*]]
200 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
201 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT:%.*]]
202 ; CHECK:       exit:
203 ; CHECK-NEXT:    ret i4 3
205 entry.1:
206   %idx.pos = icmp sge i16 %idx, 0
207   br i1 %idx.pos, label %entry, label %trap.bb
209 entry:
210   %src.idx = getelementptr inbounds i8, ptr %src, i16 %idx
211   %cmp.src.start = icmp ult ptr %src.idx, %lower
212   br i1 %cmp.src.start, label %trap.bb, label %step.check
214 trap.bb:
215   ret i4 2
217 step.check:
218   %next = add i16 %idx, 2
219   %src.step = getelementptr inbounds i8, ptr %src, i16 %next
220   %cmp.step.start = icmp ult ptr %src.step, %lower
221   %cmp.step.end = icmp uge ptr %src.step, %upper
222   %or.check = or i1 %cmp.step.start, %cmp.step.end
223   br i1 %or.check, label %trap.bb, label %exit
225 exit:
226   ret i4 3
229 define i4 @inc_ptr_src_uge_end_no_nsw_add_sge_0(ptr %src, ptr %lower, ptr %upper, i16 %idx, i16 %N, i16 %step) {
230 ; CHECK-LABEL: @inc_ptr_src_uge_end_no_nsw_add_sge_0(
231 ; CHECK-NEXT:  entry.1:
232 ; CHECK-NEXT:    [[IDX_POS:%.*]] = icmp sge i16 [[IDX:%.*]], 0
233 ; CHECK-NEXT:    br i1 [[IDX_POS]], label [[ENTRY:%.*]], label [[TRAP_BB:%.*]]
234 ; CHECK:       entry:
235 ; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[IDX]]
236 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC_IDX]], [[LOWER:%.*]]
237 ; CHECK-NEXT:    br i1 [[CMP_SRC_START]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
238 ; CHECK:       trap.bb:
239 ; CHECK-NEXT:    ret i4 2
240 ; CHECK:       step.check:
241 ; CHECK-NEXT:    [[NEXT:%.*]] = add i16 [[IDX]], 2
242 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[NEXT]]
243 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
244 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER:%.*]]
245 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
246 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT:%.*]]
247 ; CHECK:       exit:
248 ; CHECK-NEXT:    ret i4 3
250 entry.1:
251   %idx.pos = icmp sge i16 %idx, 0
252   br i1 %idx.pos, label %entry, label %trap.bb
254 entry:
255   %src.idx = getelementptr inbounds i8, ptr %src, i16 %idx
256   %cmp.src.start = icmp ult ptr %src.idx, %lower
257   br i1 %cmp.src.start, label %trap.bb, label %step.check
259 trap.bb:
260   ret i4 2
262 step.check:
263   %next = add i16 %idx, 2
264   %src.step = getelementptr inbounds i8, ptr %src, i16 %next
265   %cmp.step.start = icmp ult ptr %src.step, %lower
266   %cmp.step.end = icmp uge ptr %src.step, %upper
267   %or.check = or i1 %cmp.step.start, %cmp.step.end
268   br i1 %or.check, label %trap.bb, label %exit
270 exit:
271   ret i4 3
273 define i4 @ptr_N_step_zext_n_zext(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
274 ; CHECK-LABEL: @ptr_N_step_zext_n_zext(
275 ; CHECK-NEXT:  entry:
276 ; CHECK-NEXT:    [[N_ADD_1:%.*]] = add nuw nsw i16 [[N:%.*]], 1
277 ; CHECK-NEXT:    [[N_ADD_1_EXT:%.*]] = zext i16 [[N_ADD_1]] to i32
278 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i32 [[N_ADD_1_EXT]]
279 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
280 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
281 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
282 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
283 ; CHECK:       trap.bb:
284 ; CHECK-NEXT:    ret i4 2
285 ; CHECK:       step.check:
286 ; CHECK-NEXT:    [[STEP_ADD_1:%.*]] = add nuw nsw i16 [[STEP:%.*]], 1
287 ; CHECK-NEXT:    [[STEP_ADD_1_EXT:%.*]] = zext i16 [[STEP_ADD_1]] to i32
288 ; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i32 [[STEP_ADD_1_EXT]], [[N_ADD_1_EXT]]
289 ; CHECK-NEXT:    br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
290 ; CHECK:       ptr.check:
291 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 [[STEP_ADD_1_EXT]]
292 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 false, false
293 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
294 ; CHECK:       exit:
295 ; CHECK-NEXT:    ret i4 3
297 entry:
298   %N.add.1 = add nuw nsw i16 %N, 1
299   %N.add.1.ext = zext i16 %N.add.1 to i32
300   %src.end = getelementptr inbounds i8, ptr %src, i32 %N.add.1.ext
301   %cmp.src.start = icmp ult ptr %src, %lower
302   %cmp.src.end = icmp uge ptr %src.end, %upper
303   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
304   br i1 %or.precond.0, label %trap.bb, label %step.check
306 trap.bb:
307   ret i4 2
309 step.check:
310   %step.add.1 = add nuw nsw i16 %step, 1
311   %step.add.1.ext = zext i16 %step.add.1 to i32
312   %step.ult.N = icmp ult i32 %step.add.1.ext, %N.add.1.ext
313   br i1 %step.ult.N, label %ptr.check, label %exit
315 ptr.check:
316   %src.step = getelementptr inbounds i8, ptr %src, i32 %step.add.1.ext
317   %cmp.step.start = icmp ult ptr %src.step, %lower
318   %cmp.step.end = icmp uge ptr %src.step, %upper
319   %or.check = or i1 %cmp.step.start, %cmp.step.end
320   br i1 %or.check, label %trap.bb, label %exit
322 exit:
323   ret i4 3
326 define i4 @ptr_N_step_zext_n_zext_out_of_bounds(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
327 ; CHECK-LABEL: @ptr_N_step_zext_n_zext_out_of_bounds(
328 ; CHECK-NEXT:  entry:
329 ; CHECK-NEXT:    [[N_ADD_2:%.*]] = add nuw nsw i16 [[N:%.*]], 2
330 ; CHECK-NEXT:    [[N_ADD_2_EXT:%.*]] = zext i16 [[N_ADD_2]] to i32
331 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i32 [[N_ADD_2_EXT]]
332 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
333 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
334 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
335 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
336 ; CHECK:       trap.bb:
337 ; CHECK-NEXT:    ret i4 2
338 ; CHECK:       step.check:
339 ; CHECK-NEXT:    [[STEP_ADD_2:%.*]] = add nuw nsw i16 [[STEP:%.*]], 2
340 ; CHECK-NEXT:    [[STEP_ADD_2_EXT:%.*]] = zext i16 [[STEP_ADD_2]] to i32
341 ; CHECK-NEXT:    [[STEP_EXT:%.*]] = zext i16 [[STEP]] to i32
342 ; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i32 [[STEP_EXT]], [[N_ADD_2_EXT]]
343 ; CHECK-NEXT:    br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
344 ; CHECK:       ptr.check:
345 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 [[STEP_ADD_2_EXT]]
346 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
347 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 false, [[CMP_STEP_END]]
348 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
349 ; CHECK:       exit:
350 ; CHECK-NEXT:    ret i4 3
352 entry:
353   %N.add.2 = add nuw nsw i16 %N, 2
354   %N.add.2.ext = zext i16 %N.add.2 to i32
355   %src.end = getelementptr inbounds i8, ptr %src, i32 %N.add.2.ext
356   %cmp.src.start = icmp ult ptr %src, %lower
357   %cmp.src.end = icmp uge ptr %src.end, %upper
358   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
359   br i1 %or.precond.0, label %trap.bb, label %step.check
361 trap.bb:
362   ret i4 2
364 step.check:
365   %step.add.2 = add nuw nsw i16 %step, 2
366   %step.add.2.ext = zext i16 %step.add.2 to i32
367   %step.ext = zext i16 %step to i32
368   %step.ult.N = icmp ult i32 %step.ext, %N.add.2.ext
369   br i1 %step.ult.N, label %ptr.check, label %exit
371 ptr.check:
372   %src.step = getelementptr inbounds i8, ptr %src, i32 %step.add.2.ext
373   %cmp.step.start = icmp ult ptr %src.step, %lower
374   %cmp.step.end = icmp uge ptr %src.step, %upper
375   %or.check = or i1 %cmp.step.start, %cmp.step.end
376   br i1 %or.check, label %trap.bb, label %exit
378 exit:
379   ret i4 3
382 define i1 @gep_count_add_1_sge_known_ult_1(i32 %count, ptr %p) {
383 ; CHECK-LABEL: @gep_count_add_1_sge_known_ult_1(
384 ; CHECK-NEXT:  entry:
385 ; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
386 ; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
387 ; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
388 ; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
389 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -1
390 ; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
391 ; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
392 ; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_SUB]], [[GEP_COUNT]]
393 ; CHECK-NEXT:    ret i1 [[C]]
395 entry:
396   %sge = icmp sge i32 %count, 1
397   call void @llvm.assume(i1 %sge)
398   %count.ext = zext i32 %count to i64
399   %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
400   %sub = add nsw i32 %count, -1
401   %sub.ext = zext i32 %sub to i64
402   %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
403   %c = icmp ult ptr %gep.sub, %gep.count
404   ;%2 = icmp uge ptr %0, %p
405   ret i1 %c
408 define i1 @gep_count_add_1_sge_known_uge_1(i32 %count, ptr %p) {
409 ; CHECK-LABEL: @gep_count_add_1_sge_known_uge_1(
410 ; CHECK-NEXT:  entry:
411 ; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
412 ; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
413 ; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
414 ; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
415 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -1
416 ; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
417 ; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
418 ; CHECK-NEXT:    [[C:%.*]] = icmp uge ptr [[GEP_SUB]], [[P]]
419 ; CHECK-NEXT:    ret i1 [[C]]
421 entry:
422   %sge = icmp sge i32 %count, 1
423   call void @llvm.assume(i1 %sge)
424   %count.ext = zext i32 %count to i64
425   %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
426   %sub = add nsw i32 %count, -1
427   %sub.ext = zext i32 %sub to i64
428   %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
429   %c = icmp uge ptr %gep.sub, %p
430   ret i1 %c
433 define i1 @gep_count_add_2_sge_not_known_ult_1(i32 %count, ptr %p) {
434 ; CHECK-LABEL: @gep_count_add_2_sge_not_known_ult_1(
435 ; CHECK-NEXT:  entry:
436 ; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
437 ; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
438 ; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
439 ; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
440 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -2
441 ; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
442 ; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
443 ; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_SUB]], [[GEP_COUNT]]
444 ; CHECK-NEXT:    ret i1 [[C]]
446 entry:
447   %sge = icmp sge i32 %count, 1
448   call void @llvm.assume(i1 %sge)
449   %count.ext = zext i32 %count to i64
450   %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
451   %sub = add nsw i32 %count, -2
452   %sub.ext = zext i32 %sub to i64
453   %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
454   %c = icmp ult ptr %gep.sub, %gep.count
455   ret i1 %c
458 define i1 @gep_count_add_2_sge_not_known_uge_1(i32 %count, ptr %p) {
459 ; CHECK-LABEL: @gep_count_add_2_sge_not_known_uge_1(
460 ; CHECK-NEXT:  entry:
461 ; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
462 ; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
463 ; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
464 ; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
465 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -2
466 ; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
467 ; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
468 ; CHECK-NEXT:    [[C:%.*]] = icmp uge ptr [[GEP_SUB]], [[P]]
469 ; CHECK-NEXT:    ret i1 [[C]]
471 entry:
472   %sge = icmp sge i32 %count, 1
473   call void @llvm.assume(i1 %sge)
474   %count.ext = zext i32 %count to i64
475   %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
476   %sub = add nsw i32 %count, -2
477   %sub.ext = zext i32 %sub to i64
478   %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
479   %c = icmp uge ptr %gep.sub, %p
480   ret i1 %c