Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / gep-arithmetic-add-signed-predicates.ll
blobb0a869683cc600218a245e57346022358764b854
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 sge 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:    [[PRE_2:%.*]] = icmp sge i32 [[I:%.*]], 0
18 ; CHECK-NEXT:    br i1 [[PRE_2]], label [[TGT_BB:%.*]], label [[EXIT]]
19 ; CHECK:       tgt.bb:
20 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[I]], [[N]]
21 ; CHECK-NEXT:    ret i1 [[CMP1]]
23 entry:
24   %sub = add i32 %n, -1
25   %idxprom = zext i32 %sub to i64
26   %ptr.n.sub.1 = getelementptr i32, ptr %dst, i64 %idxprom
27   %cmp.ptr.dst = icmp sge ptr %ptr.n.sub.1, %dst
28   br i1 %cmp.ptr.dst, label %pre.bb.2, label %exit
30 exit:
31   ret i1 false
33 pre.bb.2:
34   %pre.2 = icmp sge i32 %i, 0
35   br i1 %pre.2, label %tgt.bb, label %exit
37 tgt.bb:
38   %cmp1 = icmp slt i32 %i, %n
39   ret i1 %cmp1
42 define i1 @n_known_zero_due_to_nuw(ptr %dst, i32 %n, i32 %i) {
43 ; CHECK-LABEL: @n_known_zero_due_to_nuw(
44 ; CHECK-NEXT:  entry:
45 ; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[N:%.*]], -1
46 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[SUB]] to i64
47 ; CHECK-NEXT:    [[PTR_N_SUB_1:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 [[IDXPROM]]
48 ; CHECK-NEXT:    [[CMP_PTR_DST:%.*]] = icmp sge ptr [[PTR_N_SUB_1]], [[DST]]
49 ; CHECK-NEXT:    br i1 [[CMP_PTR_DST]], label [[PRE_BB_2:%.*]], label [[EXIT:%.*]]
50 ; CHECK:       exit:
51 ; CHECK-NEXT:    ret i1 false
52 ; CHECK:       pre.bb.2:
53 ; CHECK-NEXT:    [[PRE_2:%.*]] = icmp sge i32 [[I:%.*]], 0
54 ; CHECK-NEXT:    br i1 [[PRE_2]], label [[TGT_BB:%.*]], label [[EXIT]]
55 ; CHECK:       tgt.bb:
56 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[I]], [[N]]
57 ; CHECK-NEXT:    ret i1 [[CMP1]]
59 entry:
60   %sub = add i32 %n, -1
61   %idxprom = zext i32 %sub to i64
62   %ptr.n.sub.1 = getelementptr i32, ptr %dst, i64 %idxprom
63   %cmp.ptr.dst = icmp sge ptr %ptr.n.sub.1, %dst
64   br i1 %cmp.ptr.dst, label %pre.bb.2, label %exit
66 exit:
67   ret i1 false
69 pre.bb.2:
70   %pre.2 = icmp sge i32 %i, 0
71   br i1 %pre.2, label %tgt.bb, label %exit
73 tgt.bb:
74   %cmp1 = icmp slt i32 %i, %n
75   ret i1 %cmp1
78 define i4 @inc_ptr_N_could_be_negative(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
79 ; CHECK-LABEL: @inc_ptr_N_could_be_negative(
80 ; CHECK-NEXT:  entry:
81 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
82 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
83 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
84 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
85 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
86 ; CHECK:       trap.bb:
87 ; CHECK-NEXT:    ret i4 2
88 ; CHECK:       step.check:
89 ; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i8 [[STEP:%.*]], 0
90 ; CHECK-NEXT:    [[NEXT:%.*]] = add nuw nsw i8 [[STEP]], 2
91 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i8 [[NEXT]], [[N]]
92 ; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
93 ; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
94 ; CHECK:       ptr.check:
95 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
96 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
97 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
98 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
99 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
100 ; CHECK:       exit:
101 ; CHECK-NEXT:    ret i4 3
103 entry:
104   %src.end = getelementptr inbounds i8, ptr %src, i8 %N
105   %cmp.src.start = icmp slt ptr %src, %lower
106   %cmp.src.end = icmp sge ptr %src.end, %upper
107   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
108   br i1 %or.precond.0, label %trap.bb, label %step.check
110 trap.bb:
111   ret i4 2
113 step.check:
114   %step.pos = icmp sge i8 %step, 0
115   %next = add nuw nsw i8 %step, 2
116   %step.slt.N = icmp slt i8 %next, %N
117   %and.step = and i1 %step.pos, %step.slt.N
118   br i1 %and.step, label %ptr.check, label %exit
120 ptr.check:
121   %src.step = getelementptr inbounds i8, ptr %src, i8 %step
122   %cmp.step.start = icmp slt ptr %src.step, %lower
123   %cmp.step.end = icmp sge ptr %src.step, %upper
124   %or.check = or i1 %cmp.step.start, %cmp.step.end
125   br i1 %or.check, label %trap.bb, label %exit
127 exit:
128   ret i4 3
131 define i4 @inc_ptr_src_sge_end(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
132 ; CHECK-LABEL: @inc_ptr_src_sge_end(
133 ; CHECK-NEXT:  entry:
134 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
135 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
136 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
137 ; CHECK-NEXT:    [[CMP_OVERFLOW:%.*]] = icmp sgt ptr [[SRC]], [[SRC_END]]
138 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
139 ; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]]
140 ; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
141 ; CHECK:       trap.bb:
142 ; CHECK-NEXT:    ret i4 2
143 ; CHECK:       step.check:
144 ; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
145 ; CHECK-NEXT:    [[NEXT:%.*]] = add nuw nsw i16 [[STEP]], 2
146 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[NEXT]], [[N]]
147 ; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
148 ; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
149 ; CHECK:       ptr.check:
150 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
151 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
152 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
153 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
154 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
155 ; CHECK:       exit:
156 ; CHECK-NEXT:    ret i4 3
158 entry:
159   %src.end = getelementptr inbounds i8, ptr %src, i16 %N
160   %cmp.src.start = icmp slt ptr %src, %lower
161   %cmp.src.end = icmp sge ptr %src.end, %upper
162   %cmp.overflow = icmp sgt ptr %src, %src.end
163   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
164   %or.precond.1 = or i1 %or.precond.0, %cmp.overflow
165   br i1 %or.precond.1, label %trap.bb, label %step.check
167 trap.bb:
168   ret i4 2
170 step.check:
171   %step.pos = icmp sge i16 %step, 0
172   %next = add nuw nsw i16 %step, 2
173   %step.slt.N = icmp slt i16 %next, %N
174   %and.step = and i1 %step.pos, %step.slt.N
175   br i1 %and.step, label %ptr.check, label %exit
177 ptr.check:
178   %src.step = getelementptr inbounds i8, ptr %src, i16 %step
179   %cmp.step.start = icmp slt ptr %src.step, %lower
180   %cmp.step.end = icmp sge ptr %src.step, %upper
181   %or.check = or i1 %cmp.step.start, %cmp.step.end
182   br i1 %or.check, label %trap.bb, label %exit
184 exit:
185   ret i4 3
188 define i4 @inc_ptr_src_sge_end_no_nsw_add(ptr %src, ptr %lower, ptr %upper, i16 %idx, i16 %N, i16 %step) {
189 ; CHECK-LABEL: @inc_ptr_src_sge_end_no_nsw_add(
190 ; CHECK-NEXT:  entry.1:
191 ; CHECK-NEXT:    [[IDX_POS:%.*]] = icmp sge i16 [[IDX:%.*]], 0
192 ; CHECK-NEXT:    br i1 [[IDX_POS]], label [[ENTRY:%.*]], label [[TRAP_BB:%.*]]
193 ; CHECK:       entry:
194 ; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[IDX]]
195 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC_IDX]], [[LOWER:%.*]]
196 ; CHECK-NEXT:    br i1 [[CMP_SRC_START]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
197 ; CHECK:       trap.bb:
198 ; CHECK-NEXT:    ret i4 2
199 ; CHECK:       step.check:
200 ; CHECK-NEXT:    [[NEXT:%.*]] = add i16 [[IDX]], 2
201 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[NEXT]]
202 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
203 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER:%.*]]
204 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
205 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT:%.*]]
206 ; CHECK:       exit:
207 ; CHECK-NEXT:    ret i4 3
209 entry.1:
210   %idx.pos = icmp sge i16 %idx, 0
211   br i1 %idx.pos, label %entry, label %trap.bb
213 entry:
214   %src.idx = getelementptr inbounds i8, ptr %src, i16 %idx
215   %cmp.src.start = icmp slt ptr %src.idx, %lower
216   br i1 %cmp.src.start, label %trap.bb, label %step.check
218 trap.bb:
219   ret i4 2
221 step.check:
222   %next = add i16 %idx, 2
223   %src.step = getelementptr inbounds i8, ptr %src, i16 %next
224   %cmp.step.start = icmp slt ptr %src.step, %lower
225   %cmp.step.end = icmp sge ptr %src.step, %upper
226   %or.check = or i1 %cmp.step.start, %cmp.step.end
227   br i1 %or.check, label %trap.bb, label %exit
229 exit:
230   ret i4 3
233 define i4 @inc_ptr_src_sge_end_no_nsw_add_sge_0(ptr %src, ptr %lower, ptr %upper, i16 %idx, i16 %N, i16 %step) {
234 ; CHECK-LABEL: @inc_ptr_src_sge_end_no_nsw_add_sge_0(
235 ; CHECK-NEXT:  entry.1:
236 ; CHECK-NEXT:    [[IDX_POS:%.*]] = icmp sge i16 [[IDX:%.*]], 0
237 ; CHECK-NEXT:    br i1 [[IDX_POS]], label [[ENTRY:%.*]], label [[TRAP_BB:%.*]]
238 ; CHECK:       entry:
239 ; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[IDX]]
240 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC_IDX]], [[LOWER:%.*]]
241 ; CHECK-NEXT:    br i1 [[CMP_SRC_START]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
242 ; CHECK:       trap.bb:
243 ; CHECK-NEXT:    ret i4 2
244 ; CHECK:       step.check:
245 ; CHECK-NEXT:    [[NEXT:%.*]] = add i16 [[IDX]], 2
246 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[NEXT]]
247 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
248 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER:%.*]]
249 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
250 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT:%.*]]
251 ; CHECK:       exit:
252 ; CHECK-NEXT:    ret i4 3
254 entry.1:
255   %idx.pos = icmp sge i16 %idx, 0
256   br i1 %idx.pos, label %entry, label %trap.bb
258 entry:
259   %src.idx = getelementptr inbounds i8, ptr %src, i16 %idx
260   %cmp.src.start = icmp slt ptr %src.idx, %lower
261   br i1 %cmp.src.start, label %trap.bb, label %step.check
263 trap.bb:
264   ret i4 2
266 step.check:
267   %next = add i16 %idx, 2
268   %src.step = getelementptr inbounds i8, ptr %src, i16 %next
269   %cmp.step.start = icmp slt ptr %src.step, %lower
270   %cmp.step.end = icmp sge ptr %src.step, %upper
271   %or.check = or i1 %cmp.step.start, %cmp.step.end
272   br i1 %or.check, label %trap.bb, label %exit
274 exit:
275   ret i4 3
277 define i4 @ptr_N_step_zext_n_zext(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
278 ; CHECK-LABEL: @ptr_N_step_zext_n_zext(
279 ; CHECK-NEXT:  entry:
280 ; CHECK-NEXT:    [[N_ADD_1:%.*]] = add nuw nsw i16 [[N:%.*]], 1
281 ; CHECK-NEXT:    [[N_ADD_1_EXT:%.*]] = zext i16 [[N_ADD_1]] to i32
282 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i32 [[N_ADD_1_EXT]]
283 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
284 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
285 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
286 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
287 ; CHECK:       trap.bb:
288 ; CHECK-NEXT:    ret i4 2
289 ; CHECK:       step.check:
290 ; CHECK-NEXT:    [[STEP_ADD_1:%.*]] = add nuw nsw i16 [[STEP:%.*]], 1
291 ; CHECK-NEXT:    [[STEP_ADD_1_EXT:%.*]] = zext i16 [[STEP_ADD_1]] to i32
292 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i32 [[STEP_ADD_1_EXT]], [[N_ADD_1_EXT]]
293 ; CHECK-NEXT:    br i1 [[STEP_SLT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
294 ; CHECK:       ptr.check:
295 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 [[STEP_ADD_1_EXT]]
296 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
297 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
298 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
299 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
300 ; CHECK:       exit:
301 ; CHECK-NEXT:    ret i4 3
303 entry:
304   %N.add.1 = add nuw nsw i16 %N, 1
305   %N.add.1.ext = zext i16 %N.add.1 to i32
306   %src.end = getelementptr inbounds i8, ptr %src, i32 %N.add.1.ext
307   %cmp.src.start = icmp slt ptr %src, %lower
308   %cmp.src.end = icmp sge ptr %src.end, %upper
309   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
310   br i1 %or.precond.0, label %trap.bb, label %step.check
312 trap.bb:
313   ret i4 2
315 step.check:
316   %step.add.1 = add nuw nsw i16 %step, 1
317   %step.add.1.ext = zext i16 %step.add.1 to i32
318   %step.slt.N = icmp slt i32 %step.add.1.ext, %N.add.1.ext
319   br i1 %step.slt.N, label %ptr.check, label %exit
321 ptr.check:
322   %src.step = getelementptr inbounds i8, ptr %src, i32 %step.add.1.ext
323   %cmp.step.start = icmp slt ptr %src.step, %lower
324   %cmp.step.end = icmp sge ptr %src.step, %upper
325   %or.check = or i1 %cmp.step.start, %cmp.step.end
326   br i1 %or.check, label %trap.bb, label %exit
328 exit:
329   ret i4 3
332 define i4 @ptr_N_step_zext_n_zext_out_of_bounds(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
333 ; CHECK-LABEL: @ptr_N_step_zext_n_zext_out_of_bounds(
334 ; CHECK-NEXT:  entry:
335 ; CHECK-NEXT:    [[N_ADD_2:%.*]] = add nuw nsw i16 [[N:%.*]], 2
336 ; CHECK-NEXT:    [[N_ADD_2_EXT:%.*]] = zext i16 [[N_ADD_2]] to i32
337 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i32 [[N_ADD_2_EXT]]
338 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
339 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
340 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
341 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
342 ; CHECK:       trap.bb:
343 ; CHECK-NEXT:    ret i4 2
344 ; CHECK:       step.check:
345 ; CHECK-NEXT:    [[STEP_ADD_2:%.*]] = add nuw nsw i16 [[STEP:%.*]], 2
346 ; CHECK-NEXT:    [[STEP_ADD_2_EXT:%.*]] = zext i16 [[STEP_ADD_2]] to i32
347 ; CHECK-NEXT:    [[STEP_EXT:%.*]] = zext i16 [[STEP]] to i32
348 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i32 [[STEP_EXT]], [[N_ADD_2_EXT]]
349 ; CHECK-NEXT:    br i1 [[STEP_SLT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
350 ; CHECK:       ptr.check:
351 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 [[STEP_ADD_2_EXT]]
352 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
353 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
354 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
355 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
356 ; CHECK:       exit:
357 ; CHECK-NEXT:    ret i4 3
359 entry:
360   %N.add.2 = add nuw nsw i16 %N, 2
361   %N.add.2.ext = zext i16 %N.add.2 to i32
362   %src.end = getelementptr inbounds i8, ptr %src, i32 %N.add.2.ext
363   %cmp.src.start = icmp slt ptr %src, %lower
364   %cmp.src.end = icmp sge ptr %src.end, %upper
365   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
366   br i1 %or.precond.0, label %trap.bb, label %step.check
368 trap.bb:
369   ret i4 2
371 step.check:
372   %step.add.2 = add nuw nsw i16 %step, 2
373   %step.add.2.ext = zext i16 %step.add.2 to i32
374   %step.ext = zext i16 %step to i32
375   %step.slt.N = icmp slt i32 %step.ext, %N.add.2.ext
376   br i1 %step.slt.N, label %ptr.check, label %exit
378 ptr.check:
379   %src.step = getelementptr inbounds i8, ptr %src, i32 %step.add.2.ext
380   %cmp.step.start = icmp slt ptr %src.step, %lower
381   %cmp.step.end = icmp sge ptr %src.step, %upper
382   %or.check = or i1 %cmp.step.start, %cmp.step.end
383   br i1 %or.check, label %trap.bb, label %exit
385 exit:
386   ret i4 3
389 define i1 @gep_count_add_1_sge_known_slt_1(i32 %count, ptr %p) {
390 ; CHECK-LABEL: @gep_count_add_1_sge_known_slt_1(
391 ; CHECK-NEXT:  entry:
392 ; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
393 ; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
394 ; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
395 ; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
396 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -1
397 ; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
398 ; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
399 ; CHECK-NEXT:    [[C:%.*]] = icmp slt ptr [[GEP_SUB]], [[GEP_COUNT]]
400 ; CHECK-NEXT:    ret i1 [[C]]
402 entry:
403   %sge = icmp sge i32 %count, 1
404   call void @llvm.assume(i1 %sge)
405   %count.ext = zext i32 %count to i64
406   %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
407   %sub = add nsw i32 %count, -1
408   %sub.ext = zext i32 %sub to i64
409   %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
410   %c = icmp slt ptr %gep.sub, %gep.count
411   ;%2 = icmp sge ptr %0, %p
412   ret i1 %c
415 define i1 @gep_count_add_1_sge_known_sge_1(i32 %count, ptr %p) {
416 ; CHECK-LABEL: @gep_count_add_1_sge_known_sge_1(
417 ; CHECK-NEXT:  entry:
418 ; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
419 ; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
420 ; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
421 ; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
422 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -1
423 ; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
424 ; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
425 ; CHECK-NEXT:    [[C:%.*]] = icmp sge ptr [[GEP_SUB]], [[P]]
426 ; CHECK-NEXT:    ret i1 [[C]]
428 entry:
429   %sge = icmp sge i32 %count, 1
430   call void @llvm.assume(i1 %sge)
431   %count.ext = zext i32 %count to i64
432   %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
433   %sub = add nsw i32 %count, -1
434   %sub.ext = zext i32 %sub to i64
435   %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
436   %c = icmp sge ptr %gep.sub, %p
437   ret i1 %c
440 define i1 @gep_count_add_2_sge_not_known_slt_1(i32 %count, ptr %p) {
441 ; CHECK-LABEL: @gep_count_add_2_sge_not_known_slt_1(
442 ; CHECK-NEXT:  entry:
443 ; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
444 ; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
445 ; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
446 ; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
447 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -2
448 ; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
449 ; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
450 ; CHECK-NEXT:    [[C:%.*]] = icmp slt ptr [[GEP_SUB]], [[GEP_COUNT]]
451 ; CHECK-NEXT:    ret i1 [[C]]
453 entry:
454   %sge = icmp sge i32 %count, 1
455   call void @llvm.assume(i1 %sge)
456   %count.ext = zext i32 %count to i64
457   %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
458   %sub = add nsw i32 %count, -2
459   %sub.ext = zext i32 %sub to i64
460   %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
461   %c = icmp slt ptr %gep.sub, %gep.count
462   ret i1 %c
465 define i1 @gep_count_add_2_sge_not_known_sge_1(i32 %count, ptr %p) {
466 ; CHECK-LABEL: @gep_count_add_2_sge_not_known_sge_1(
467 ; CHECK-NEXT:  entry:
468 ; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
469 ; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
470 ; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
471 ; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
472 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -2
473 ; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
474 ; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
475 ; CHECK-NEXT:    [[C:%.*]] = icmp sge ptr [[GEP_SUB]], [[P]]
476 ; CHECK-NEXT:    ret i1 [[C]]
478 entry:
479   %sge = icmp sge i32 %count, 1
480   call void @llvm.assume(i1 %sge)
481   %count.ext = zext i32 %count to i64
482   %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
483   %sub = add nsw i32 %count, -2
484   %sub.ext = zext i32 %sub to i64
485   %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
486   %c = icmp sge ptr %gep.sub, %p
487   ret i1 %c