[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / gep-arithmetic-signed-predicates.ll
blob52094914f6962d23babbdbb525f90ee42992cbc8
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 @gep_constant_positive_index(ptr %dst, ptr %lower, ptr %upper) {
7 ; CHECK-LABEL: @gep_constant_positive_index(
8 ; CHECK-NEXT:    [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 4
9 ; CHECK-NEXT:    [[PRE_DST_LOWER:%.*]] = icmp sge ptr [[DST]], [[LOWER:%.*]]
10 ; CHECK-NEXT:    [[PRE_DST_UPPER:%.*]] = icmp slt ptr [[DST_ADD_4]], [[UPPER:%.*]]
11 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]]
12 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
13 ; CHECK:       then:
14 ; CHECK-NEXT:    [[CMP_DST_UPPER:%.*]] = icmp slt ptr [[DST]], [[UPPER]]
15 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[CMP_DST_UPPER]]
16 ; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
17 ; CHECK-NEXT:    [[CMP_DST_ADD_3_LOWER:%.*]] = icmp sge ptr [[DST_ADD_3]], [[LOWER]]
18 ; CHECK-NEXT:    [[CMP_DST_ADD_3_UPPER:%.*]] = icmp slt ptr [[DST_ADD_3]], [[UPPER]]
19 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_DST_ADD_3_LOWER]]
20 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_DST_ADD_3_UPPER]]
21 ; CHECK-NEXT:    [[CMP_DST_ADD_4_LOWER:%.*]] = icmp sge ptr [[DST_ADD_4]], [[LOWER]]
22 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[CMP_DST_ADD_4_LOWER]]
23 ; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_4]], true
24 ; CHECK-NEXT:    [[DST_ADD_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5
25 ; CHECK-NEXT:    [[CMP_DST_ADD_5_LOWER:%.*]] = icmp sge ptr [[DST_ADD_5]], [[LOWER]]
26 ; CHECK-NEXT:    [[CMP_DST_ADD_5_UPPER:%.*]] = icmp slt ptr [[DST_ADD_5]], [[UPPER]]
27 ; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], [[CMP_DST_ADD_5_LOWER]]
28 ; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_ADD_5_UPPER]]
29 ; CHECK-NEXT:    ret i1 [[RES_7]]
30 ; CHECK:       else:
31 ; CHECK-NEXT:    ret i1 false
33   %dst.add.4 = getelementptr inbounds i8, ptr %dst, i64 4
34   %pre.dst.lower = icmp sge ptr %dst, %lower
35   %pre.dst.upper = icmp slt ptr %dst.add.4, %upper
36   %and = and i1 %pre.dst.lower, %pre.dst.upper
37   br i1 %and, label %then, label %else
39 then:
40   %cmp.dst.lower = icmp sge ptr %dst, %lower
41   %cmp.dst.upper = icmp slt ptr %dst, %upper
42   %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper
43   %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
44   %cmp.dst.add.3.lower = icmp sge ptr %dst.add.3, %lower
45   %cmp.dst.add.3.upper = icmp slt ptr %dst.add.3, %upper
46   %res.2 = xor i1 %res.1, %cmp.dst.add.3.lower
47   %res.3 = xor i1 %res.2, %cmp.dst.add.3.upper
48   %cmp.dst.add.4.lower = icmp sge ptr %dst.add.4, %lower
49   %cmp.dst.add.4.upper = icmp slt ptr %dst.add.4, %upper
50   %res.4 = xor i1 %res.3, %cmp.dst.add.4.lower
51   %res.5 = xor i1 %res.4, %cmp.dst.add.4.upper
52   %dst.add.5 = getelementptr inbounds i8, ptr %dst, i64 5
53   %cmp.dst.add.5.lower = icmp sge ptr %dst.add.5, %lower
54   %cmp.dst.add.5.upper = icmp slt ptr %dst.add.5, %upper
55   %res.6 = xor i1 %res.5, %cmp.dst.add.5.lower
56   %res.7 = xor i1 %res.6, %cmp.dst.add.5.upper
57   ret i1 %res.7
59 else:
60   ret i1 false
63 define i1 @gep_constant_negative_index(ptr %dst, ptr %lower, ptr %upper) {
64 ; CHECK-LABEL: @gep_constant_negative_index(
65 ; CHECK-NEXT:    [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 -4
66 ; CHECK-NEXT:    [[PRE_DST_LOWER:%.*]] = icmp sge ptr [[DST]], [[LOWER:%.*]]
67 ; CHECK-NEXT:    [[PRE_DST_UPPER:%.*]] = icmp slt ptr [[DST_SUB_4]], [[UPPER:%.*]]
68 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]]
69 ; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
70 ; CHECK:       then:
71 ; CHECK-NEXT:    [[CMP_DST_UPPER:%.*]] = icmp slt ptr [[DST]], [[UPPER]]
72 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[CMP_DST_UPPER]]
73 ; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -3
74 ; CHECK-NEXT:    [[CMP_DST_SUB_3_LOWER:%.*]] = icmp sge ptr [[DST_SUB_3]], [[LOWER]]
75 ; CHECK-NEXT:    [[CMP_DST_SUB_3_UPPER:%.*]] = icmp slt ptr [[DST_SUB_3]], [[UPPER]]
76 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_DST_SUB_3_LOWER]]
77 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_DST_SUB_3_UPPER]]
78 ; CHECK-NEXT:    [[CMP_DST_SUB_4_LOWER:%.*]] = icmp sge ptr [[DST_SUB_4]], [[LOWER]]
79 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[CMP_DST_SUB_4_LOWER]]
80 ; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_4]], true
81 ; CHECK-NEXT:    [[DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5
82 ; CHECK-NEXT:    [[CMP_DST_SUB_5_LOWER:%.*]] = icmp sge ptr [[DST_SUB_5]], [[LOWER]]
83 ; CHECK-NEXT:    [[CMP_DST_SUB_5_UPPER:%.*]] = icmp slt ptr [[DST_SUB_5]], [[UPPER]]
84 ; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], [[CMP_DST_SUB_5_LOWER]]
85 ; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_SUB_5_UPPER]]
86 ; CHECK-NEXT:    ret i1 [[RES_7]]
87 ; CHECK:       else:
88 ; CHECK-NEXT:    [[ELSE_CMP_DST_LOWER:%.*]] = icmp sge ptr [[DST]], [[LOWER]]
89 ; CHECK-NEXT:    [[ELSE_CMP_DST_UPPER:%.*]] = icmp slt ptr [[DST]], [[UPPER]]
90 ; CHECK-NEXT:    [[ELSE_RES_1:%.*]] = xor i1 [[ELSE_CMP_DST_LOWER]], [[ELSE_CMP_DST_UPPER]]
91 ; CHECK-NEXT:    [[ELSE_DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -3
92 ; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_3_LOWER:%.*]] = icmp sge ptr [[ELSE_DST_SUB_3]], [[LOWER]]
93 ; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_3_UPPER:%.*]] = icmp slt ptr [[ELSE_DST_SUB_3]], [[UPPER]]
94 ; CHECK-NEXT:    [[ELSE_RES_2:%.*]] = xor i1 [[ELSE_RES_1]], [[ELSE_CMP_DST_SUB_3_LOWER]]
95 ; CHECK-NEXT:    [[ELSE_RES_3:%.*]] = xor i1 [[ELSE_RES_2]], [[ELSE_CMP_DST_SUB_3_UPPER]]
96 ; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_4_LOWER:%.*]] = icmp sge ptr [[DST_SUB_4]], [[LOWER]]
97 ; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_4_UPPER:%.*]] = icmp slt ptr [[DST_SUB_4]], [[UPPER]]
98 ; CHECK-NEXT:    [[ELSE_RES_4:%.*]] = xor i1 [[ELSE_RES_3]], [[ELSE_CMP_DST_SUB_4_LOWER]]
99 ; CHECK-NEXT:    [[ELSE_RES_5:%.*]] = xor i1 [[ELSE_RES_4]], [[ELSE_CMP_DST_SUB_4_UPPER]]
100 ; CHECK-NEXT:    [[ELSE_DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5
101 ; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_5_LOWER:%.*]] = icmp sge ptr [[ELSE_DST_SUB_5]], [[LOWER]]
102 ; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_5_UPPER:%.*]] = icmp slt ptr [[ELSE_DST_SUB_5]], [[UPPER]]
103 ; CHECK-NEXT:    [[ELSE_RES_6:%.*]] = xor i1 [[ELSE_RES_5]], [[ELSE_CMP_DST_SUB_5_LOWER]]
104 ; CHECK-NEXT:    [[ELSE_RES_7:%.*]] = xor i1 [[ELSE_RES_6]], [[ELSE_CMP_DST_SUB_5_UPPER]]
105 ; CHECK-NEXT:    ret i1 [[ELSE_RES_7]]
107   %dst.sub.4 = getelementptr inbounds i8, ptr %dst, i64 -4
108   %pre.dst.lower = icmp sge ptr %dst, %lower
109   %pre.dst.upper = icmp slt ptr %dst.sub.4, %upper
110   %and = and i1 %pre.dst.lower, %pre.dst.upper
111   br i1 %and, label %then, label %else
113 then:
114   %cmp.dst.lower = icmp sge ptr %dst, %lower
115   %cmp.dst.upper = icmp slt ptr %dst, %upper
116   %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper
117   %dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3
118   %cmp.dst.sub.3.lower = icmp sge ptr %dst.sub.3, %lower
119   %cmp.dst.sub.3.upper = icmp slt ptr %dst.sub.3, %upper
120   %res.2 = xor i1 %res.1, %cmp.dst.sub.3.lower
121   %res.3 = xor i1 %res.2, %cmp.dst.sub.3.upper
122   %cmp.dst.sub.4.lower = icmp sge ptr %dst.sub.4, %lower
123   %cmp.dst.sub.4.upper = icmp slt ptr %dst.sub.4, %upper
124   %res.4 = xor i1 %res.3, %cmp.dst.sub.4.lower
125   %res.5 = xor i1 %res.4, %cmp.dst.sub.4.upper
126   %dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5
127   %cmp.dst.sub.5.lower = icmp sge ptr %dst.sub.5, %lower
128   %cmp.dst.sub.5.upper = icmp slt ptr %dst.sub.5, %upper
129   %res.6 = xor i1 %res.5, %cmp.dst.sub.5.lower
130   %res.7 = xor i1 %res.6, %cmp.dst.sub.5.upper
131   ret i1 %res.7
133 else:
134   %else.cmp.dst.lower = icmp sge ptr %dst, %lower
135   %else.cmp.dst.upper = icmp slt ptr %dst, %upper
136   %else.res.1 = xor i1 %else.cmp.dst.lower, %else.cmp.dst.upper
137   %else.dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3
138   %else.cmp.dst.sub.3.lower = icmp sge ptr %else.dst.sub.3, %lower
139   %else.cmp.dst.sub.3.upper = icmp slt ptr %else.dst.sub.3, %upper
140   %else.res.2 = xor i1 %else.res.1, %else.cmp.dst.sub.3.lower
141   %else.res.3 = xor i1 %else.res.2, %else.cmp.dst.sub.3.upper
142   %else.cmp.dst.sub.4.lower = icmp sge ptr %dst.sub.4, %lower
143   %else.cmp.dst.sub.4.upper = icmp slt ptr %dst.sub.4, %upper
144   %else.res.4 = xor i1 %else.res.3, %else.cmp.dst.sub.4.lower
145   %else.res.5 = xor i1 %else.res.4, %else.cmp.dst.sub.4.upper
146   %else.dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5
147   %else.cmp.dst.sub.5.lower = icmp sge ptr %else.dst.sub.5, %lower
148   %else.cmp.dst.sub.5.upper = icmp slt ptr %else.dst.sub.5, %upper
149   %else.res.6 = xor i1 %else.res.5, %else.cmp.dst.sub.5.lower
150   %else.res.7 = xor i1 %else.res.6, %else.cmp.dst.sub.5.upper
151   ret i1 %else.res.7
154 define i4 @ptr_N_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N) {
155 ; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step(
156 ; CHECK-NEXT:  entry:
157 ; CHECK-NEXT:    [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
158 ; CHECK-NEXT:    br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
159 ; CHECK:       entry.1:
160 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]]
161 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
162 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
163 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
164 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
165 ; CHECK:       trap.bb:
166 ; CHECK-NEXT:    ret i4 2
167 ; CHECK:       step.check:
168 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 1, [[N]]
169 ; CHECK-NEXT:    br i1 [[STEP_SLT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
170 ; CHECK:       ptr.check:
171 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
172 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
173 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
174 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
175 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
176 ; CHECK:       exit:
177 ; CHECK-NEXT:    ret i4 3
179 entry:
180   %N.pos = icmp sge i16 %N, 0
181   br i1 %N.pos, label %entry.1, label %trap.bb
183 entry.1:
184   %src.end = getelementptr inbounds i8, ptr %src, i16 %N
185   %cmp.src.start = icmp slt ptr %src, %lower
186   %cmp.src.end = icmp sge ptr %src.end, %upper
187   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
188   br i1 %or.precond.0, label %trap.bb, label %step.check
190 trap.bb:
191   ret i4 2
193 step.check:
194   %step.slt.N = icmp slt i16 1, %N
195   br i1 %step.slt.N, label %ptr.check, label %exit
197 ptr.check:
198   %src.step = getelementptr inbounds i8, ptr %src, i16 1
199   %cmp.step.start = icmp slt ptr %src.step, %lower
200   %cmp.step.end = icmp sge ptr %src.step, %upper
201   %or.check = or i1 %cmp.step.start, %cmp.step.end
202   br i1 %or.check, label %trap.bb, label %exit
204 exit:
205   ret i4 3
208 ; Same as ptr_N_signed_positive_explicit_check_constant_step, but without inbounds.
209 define i4 @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(ptr %src, ptr %lower, ptr %upper, i16 %N) {
210 ; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(
211 ; CHECK-NEXT:  entry:
212 ; CHECK-NEXT:    [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
213 ; CHECK-NEXT:    br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
214 ; CHECK:       entry.1:
215 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr i8, ptr [[SRC:%.*]], i16 [[N]]
216 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
217 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
218 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
219 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
220 ; CHECK:       trap.bb:
221 ; CHECK-NEXT:    ret i4 2
222 ; CHECK:       step.check:
223 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 1, [[N]]
224 ; CHECK-NEXT:    br i1 [[STEP_SLT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
225 ; CHECK:       ptr.check:
226 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr i8, ptr [[SRC]], i16 1
227 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
228 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
229 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
230 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
231 ; CHECK:       exit:
232 ; CHECK-NEXT:    ret i4 3
234 entry:
235   %N.pos = icmp sge i16 %N, 0
236   br i1 %N.pos, label %entry.1, label %trap.bb
238 entry.1:
239   %src.end = getelementptr i8, ptr %src, i16 %N
240   %cmp.src.start = icmp slt ptr %src, %lower
241   %cmp.src.end = icmp sge ptr %src.end, %upper
242   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
243   br i1 %or.precond.0, label %trap.bb, label %step.check
245 trap.bb:
246   ret i4 2
248 step.check:
249   %step.slt.N = icmp slt i16 1, %N
250   br i1 %step.slt.N, label %ptr.check, label %exit
252 ptr.check:
253   %src.step = getelementptr i8, ptr %src, i16 1
254   %cmp.step.start = icmp slt ptr %src.step, %lower
255   %cmp.step.end = icmp sge ptr %src.step, %upper
256   %or.check = or i1 %cmp.step.start, %cmp.step.end
257   br i1 %or.check, label %trap.bb, label %exit
259 exit:
260   ret i4 3
263 define i4 @ptr_N_and_step_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
264 ; CHECK-LABEL: @ptr_N_and_step_signed_positive_explicit_check_constant_step(
265 ; CHECK-NEXT:  entry:
266 ; CHECK-NEXT:    [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
267 ; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
268 ; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[N_POS]], [[STEP_POS]]
269 ; CHECK-NEXT:    br i1 [[AND_1]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
270 ; CHECK:       entry.1:
271 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]]
272 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
273 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
274 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
275 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
276 ; CHECK:       trap.bb:
277 ; CHECK-NEXT:    ret i4 2
278 ; CHECK:       step.check:
279 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]
280 ; CHECK-NEXT:    [[AND_2:%.*]] = and i1 true, [[STEP_SLT_N]]
281 ; CHECK-NEXT:    br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
282 ; CHECK:       ptr.check:
283 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
284 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
285 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
286 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
287 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
288 ; CHECK:       exit:
289 ; CHECK-NEXT:    ret i4 3
291 entry:
292   %N.pos = icmp sge i16 %N, 0
293   %step.pos = icmp sge i16 %step, 0
294   %and.1 = and i1 %N.pos, %step.pos
295   br i1 %and.1, label %entry.1, label %trap.bb
297 entry.1:
298   %src.end = getelementptr inbounds i8, ptr %src, i16 %N
299   %cmp.src.start = icmp slt ptr %src, %lower
300   %cmp.src.end = icmp sge ptr %src.end, %upper
301   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
302   br i1 %or.precond.0, label %trap.bb, label %step.check
304 trap.bb:
305   ret i4 2
307 step.check:
308   %step.sge.0 = icmp sge i16 %step, 0
309   %step.slt.N = icmp slt i16 %step, %N
310   %and.2 = and i1 %step.sge.0, %step.slt.N
311   br i1 %and.2, label %ptr.check, label %exit
313 ptr.check:
314   %src.step = getelementptr inbounds i8, ptr %src, i16 1
315   %cmp.step.start = icmp slt ptr %src.step, %lower
316   %cmp.step.end = icmp sge ptr %src.step, %upper
317   %or.check = or i1 %cmp.step.start, %cmp.step.end
318   br i1 %or.check, label %trap.bb, label %exit
320 exit:
321   ret i4 3
324 define i4 @ptr_N_and_step_signed_positive_unsigned_checks_only(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
325 ; CHECK-LABEL: @ptr_N_and_step_signed_positive_unsigned_checks_only(
326 ; CHECK-NEXT:  entry:
327 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
328 ; CHECK-NEXT:    [[NO_OVERFLOW:%.*]] = icmp sle ptr [[SRC]], [[SRC_END]]
329 ; CHECK-NEXT:    br i1 [[NO_OVERFLOW]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
330 ; CHECK:       entry.1:
331 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
332 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
333 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
334 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
335 ; CHECK:       trap.bb:
336 ; CHECK-NEXT:    ret i4 2
337 ; CHECK:       step.check:
338 ; CHECK-NEXT:    [[STEP_SGE_0:%.*]] = icmp sge i16 [[STEP:%.*]], 0
339 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]
340 ; CHECK-NEXT:    [[AND_2:%.*]] = and i1 [[STEP_SGE_0]], [[STEP_SLT_N]]
341 ; CHECK-NEXT:    br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
342 ; CHECK:       ptr.check:
343 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
344 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
345 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
346 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
347 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
348 ; CHECK:       exit:
349 ; CHECK-NEXT:    ret i4 3
351 entry:
352   %src.end = getelementptr inbounds i8, ptr %src, i16 %N
353   %no.overflow = icmp sle ptr %src, %src.end
354   br i1 %no.overflow, label %entry.1, label %trap.bb
356 entry.1:
357   %cmp.src.start = icmp slt ptr %src, %lower
358   %cmp.src.end = icmp sge ptr %src.end, %upper
359   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
360   br i1 %or.precond.0, label %trap.bb, label %step.check
362 trap.bb:
363   ret i4 2
365 step.check:
366   %step.sge.0 = icmp sge i16 %step, 0
367   %step.slt.N = icmp slt i16 %step, %N
368   %and.2 = and i1 %step.sge.0, %step.slt.N
369   br i1 %and.2, label %ptr.check, label %exit
371 ptr.check:
372   %src.step = getelementptr inbounds i8, ptr %src, i16 1
373   %cmp.step.start = icmp slt ptr %src.step, %lower
374   %cmp.step.end = icmp sge 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 i4 @ptr_N_signed_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
383 ; CHECK-LABEL: @ptr_N_signed_positive(
384 ; CHECK-NEXT:  entry:
385 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
386 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
387 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
388 ; CHECK-NEXT:    [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
389 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
390 ; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[N_NEG]]
391 ; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
392 ; CHECK:       trap.bb:
393 ; CHECK-NEXT:    ret i4 2
394 ; CHECK:       step.check:
395 ; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
396 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]
397 ; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
398 ; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
399 ; CHECK:       ptr.check:
400 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
401 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
402 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
403 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
404 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
405 ; CHECK:       exit:
406 ; CHECK-NEXT:    ret i4 3
408 entry:
409   %src.end = getelementptr inbounds i8, ptr %src, i16 %N
410   %cmp.src.start = icmp slt ptr %src, %lower
411   %cmp.src.end = icmp sge ptr %src.end, %upper
412   %N.neg = icmp slt i16 %N, 0
413   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
414   %or.precond.1 = or i1 %or.precond.0, %N.neg
415   br i1 %or.precond.1, label %trap.bb, label %step.check
417 trap.bb:
418   ret i4 2
420 step.check:
421   %step.pos = icmp sge i16 %step, 0
422   %step.slt.N = icmp slt i16 %step, %N
423   %and.step = and i1 %step.pos, %step.slt.N
424   br i1 %and.step, label %ptr.check, label %exit
426 ptr.check:
427   %src.step = getelementptr inbounds i8, ptr %src, i16 %step
428   %cmp.step.start = icmp slt ptr %src.step, %lower
429   %cmp.step.end = icmp sge ptr %src.step, %upper
430   %or.check = or i1 %cmp.step.start, %cmp.step.end
431   br i1 %or.check, label %trap.bb, label %exit
433 exit:
434   ret i4 3
437 define i4 @ptr_N_could_be_negative(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
438 ; CHECK-LABEL: @ptr_N_could_be_negative(
439 ; CHECK-NEXT:  entry:
440 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
441 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
442 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
443 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
444 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
445 ; CHECK:       trap.bb:
446 ; CHECK-NEXT:    ret i4 2
447 ; CHECK:       step.check:
448 ; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i8 [[STEP:%.*]], 0
449 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i8 [[STEP]], [[N]]
450 ; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
451 ; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
452 ; CHECK:       ptr.check:
453 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
454 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
455 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
456 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
457 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
458 ; CHECK:       exit:
459 ; CHECK-NEXT:    ret i4 3
461 entry:
462   %src.end = getelementptr inbounds i8, ptr %src, i8 %N
463   %cmp.src.start = icmp slt ptr %src, %lower
464   %cmp.src.end = icmp sge ptr %src.end, %upper
465   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
466   br i1 %or.precond.0, label %trap.bb, label %step.check
468 trap.bb:
469   ret i4 2
471 step.check:
472   %step.pos = icmp sge i8 %step, 0
473   %step.slt.N = icmp slt i8 %step, %N
474   %and.step = and i1 %step.pos, %step.slt.N
475   br i1 %and.step, label %ptr.check, label %exit
477 ptr.check:
478   %src.step = getelementptr inbounds i8, ptr %src, i8 %step
479   %cmp.step.start = icmp slt ptr %src.step, %lower
480   %cmp.step.end = icmp sge ptr %src.step, %upper
481   %or.check = or i1 %cmp.step.start, %cmp.step.end
482   br i1 %or.check, label %trap.bb, label %exit
484 exit:
485   ret i4 3
488 define i4 @ptr_src_sge_end(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
489 ; CHECK-LABEL: @ptr_src_sge_end(
490 ; CHECK-NEXT:  entry:
491 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
492 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
493 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
494 ; CHECK-NEXT:    [[CMP_OVERFLOW:%.*]] = icmp sgt ptr [[SRC]], [[SRC_END]]
495 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
496 ; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]]
497 ; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
498 ; CHECK:       trap.bb:
499 ; CHECK-NEXT:    ret i4 2
500 ; CHECK:       step.check:
501 ; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i8 [[STEP:%.*]], 0
502 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i8 [[STEP]], [[N]]
503 ; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
504 ; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
505 ; CHECK:       ptr.check:
506 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
507 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
508 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
509 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
510 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
511 ; CHECK:       exit:
512 ; CHECK-NEXT:    ret i4 3
514 entry:
515   %src.end = getelementptr inbounds i8, ptr %src, i8 %N
516   %cmp.src.start = icmp slt ptr %src, %lower
517   %cmp.src.end = icmp sge ptr %src.end, %upper
518   %cmp.overflow = icmp sgt ptr %src, %src.end
519   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
520   %or.precond.1 = or i1 %or.precond.0, %cmp.overflow
521   br i1 %or.precond.1, label %trap.bb, label %step.check
523 trap.bb:
524   ret i4 2
526 step.check:
527   %step.pos = icmp sge i8 %step, 0
528   %step.slt.N = icmp slt i8 %step, %N
529   %and.step = and i1 %step.pos, %step.slt.N
530   br i1 %and.step, label %ptr.check, label %exit
532 ptr.check:
533   %src.step = getelementptr inbounds i8, ptr %src, i8 %step
534   %cmp.step.start = icmp slt ptr %src.step, %lower
535   %cmp.step.end = icmp sge ptr %src.step, %upper
536   %or.check = or i1 %cmp.step.start, %cmp.step.end
537   br i1 %or.check, label %trap.bb, label %exit
539 exit:
540   ret i4 3
543 ; N might be negative, meaning %src.end could be < %src! Cannot remove checks!
544 define i4 @ptr_N_unsigned_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
545 ; CHECK-LABEL: @ptr_N_unsigned_positive(
546 ; CHECK-NEXT:  entry:
547 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
548 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
549 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
550 ; CHECK-NEXT:    [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
551 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
552 ; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[N_NEG]]
553 ; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
554 ; CHECK:       trap.bb:
555 ; CHECK-NEXT:    ret i4 2
556 ; CHECK:       step.check:
557 ; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
558 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]
559 ; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
560 ; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
561 ; CHECK:       ptr.check:
562 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
563 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
564 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
565 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
566 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
567 ; CHECK:       exit:
568 ; CHECK-NEXT:    ret i4 3
570 entry:
571   %src.end = getelementptr inbounds i8, ptr %src, i16 %N
572   %cmp.src.start = icmp slt ptr %src, %lower
573   %cmp.src.end = icmp sge ptr %src.end, %upper
574   %N.neg = icmp slt i16 %N, 0
575   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
576   %or.precond.1 = or i1 %or.precond.0, %N.neg
577   br i1 %or.precond.1, label %trap.bb, label %step.check
579 trap.bb:
580   ret i4 2
582 step.check:
583   %step.pos = icmp sge i16 %step, 0
584   %step.slt.N = icmp slt i16 %step, %N
585   %and.step = and i1 %step.pos, %step.slt.N
586   br i1 %and.step, label %ptr.check, label %exit
588 ptr.check:
589   %src.step = getelementptr inbounds i8, ptr %src, i16 %step
590   %cmp.step.start = icmp slt ptr %src.step, %lower
591   %cmp.step.end = icmp sge ptr %src.step, %upper
592   %or.check = or i1 %cmp.step.start, %cmp.step.end
593   br i1 %or.check, label %trap.bb, label %exit
595 exit:
596   ret i4 3
599 define i4 @ptr_N_signed_positive_assume(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
600 ; CHECK-LABEL: @ptr_N_signed_positive_assume(
601 ; CHECK-NEXT:  entry:
602 ; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
603 ; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
604 ; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
605 ; CHECK-NEXT:    [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
606 ; CHECK-NEXT:    call void @llvm.assume(i1 [[N_NEG]])
607 ; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
608 ; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
609 ; CHECK:       trap.bb:
610 ; CHECK-NEXT:    ret i4 2
611 ; CHECK:       step.check:
612 ; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
613 ; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]
614 ; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 false, [[STEP_SLT_N]]
615 ; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
616 ; CHECK:       ptr.check:
617 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
618 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
619 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
620 ; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 true, [[CMP_STEP_END]]
621 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
622 ; CHECK:       exit:
623 ; CHECK-NEXT:    ret i4 3
625 entry:
626   %src.end = getelementptr inbounds i8, ptr %src, i16 %N
627   %cmp.src.start = icmp slt ptr %src, %lower
628   %cmp.src.end = icmp sge ptr %src.end, %upper
629   %N.neg = icmp slt i16 %N, 0
630   call void @llvm.assume(i1 %N.neg)
631   %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
632   br i1 %or.precond.0, label %trap.bb, label %step.check
634 trap.bb:
635   ret i4 2
637 step.check:
638   %step.pos = icmp sge i16 %step, 0
639   %step.slt.N = icmp slt i16 %step, %N
640   %and.step = and i1 %step.pos, %step.slt.N
641   br i1 %and.step, label %ptr.check, label %exit
643 ptr.check:
644   %src.step = getelementptr inbounds i8, ptr %src, i16 %step
645   %cmp.step.start = icmp slt ptr %src.step, %lower
646   %cmp.step.end = icmp sge ptr %src.step, %upper
647   %or.check = or i1 %cmp.step.start, %cmp.step.end
648   br i1 %or.check, label %trap.bb, label %exit
650 exit:
651   ret i4 3