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)
6 define i1 @gep_constant_positive_index(i8* %dst, i8* %lower, i8* %upper) {
7 ; CHECK-LABEL: @gep_constant_positive_index(
8 ; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr inbounds i8, i8* [[DST:%.*]], i64 4
9 ; CHECK-NEXT: [[PRE_DST_LOWER:%.*]] = icmp uge i8* [[DST]], [[LOWER:%.*]]
10 ; CHECK-NEXT: [[PRE_DST_UPPER:%.*]] = icmp ult i8* [[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:%.*]]
14 ; CHECK-NEXT: [[CMP_DST_LOWER:%.*]] = icmp uge i8* [[DST]], [[LOWER]]
15 ; CHECK-NEXT: [[CMP_DST_UPPER:%.*]] = icmp ult i8* [[DST]], [[UPPER]]
16 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
17 ; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 3
18 ; CHECK-NEXT: [[CMP_DST_ADD_3_LOWER:%.*]] = icmp uge i8* [[DST_ADD_3]], [[LOWER]]
19 ; CHECK-NEXT: [[CMP_DST_ADD_3_UPPER:%.*]] = icmp ult i8* [[DST_ADD_3]], [[UPPER]]
20 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], true
21 ; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], true
22 ; CHECK-NEXT: [[CMP_DST_ADD_4_LOWER:%.*]] = icmp uge i8* [[DST_ADD_4]], [[LOWER]]
23 ; CHECK-NEXT: [[CMP_DST_ADD_4_UPPER:%.*]] = icmp ult i8* [[DST_ADD_4]], [[UPPER]]
24 ; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], true
25 ; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true
26 ; CHECK-NEXT: [[DST_ADD_5:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 5
27 ; CHECK-NEXT: [[CMP_DST_ADD_5_LOWER:%.*]] = icmp uge i8* [[DST_ADD_5]], [[LOWER]]
28 ; CHECK-NEXT: [[CMP_DST_ADD_5_UPPER:%.*]] = icmp ult i8* [[DST_ADD_5]], [[UPPER]]
29 ; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], true
30 ; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_ADD_5_UPPER]]
31 ; CHECK-NEXT: ret i1 [[RES_7]]
33 ; CHECK-NEXT: ret i1 false
35 %dst.add.4 = getelementptr inbounds i8, i8* %dst, i64 4
36 %pre.dst.lower = icmp uge i8* %dst, %lower
37 %pre.dst.upper = icmp ult i8* %dst.add.4, %upper
38 %and = and i1 %pre.dst.lower, %pre.dst.upper
39 br i1 %and, label %then, label %else
42 %cmp.dst.lower = icmp uge i8* %dst, %lower
43 %cmp.dst.upper = icmp ult i8* %dst, %upper
44 %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper
46 %dst.add.3 = getelementptr inbounds i8, i8* %dst, i64 3
47 %cmp.dst.add.3.lower = icmp uge i8* %dst.add.3, %lower
48 %cmp.dst.add.3.upper = icmp ult i8* %dst.add.3, %upper
49 %res.2 = xor i1 %res.1, %cmp.dst.add.3.lower
50 %res.3 = xor i1 %res.2, %cmp.dst.add.3.upper
52 %cmp.dst.add.4.lower = icmp uge i8* %dst.add.4, %lower
53 %cmp.dst.add.4.upper = icmp ult i8* %dst.add.4, %upper
54 %res.4 = xor i1 %res.3, %cmp.dst.add.4.lower
55 %res.5 = xor i1 %res.4, %cmp.dst.add.4.upper
57 %dst.add.5 = getelementptr inbounds i8, i8* %dst, i64 5
58 %cmp.dst.add.5.lower = icmp uge i8* %dst.add.5, %lower
59 %cmp.dst.add.5.upper = icmp ult i8* %dst.add.5, %upper
60 %res.6 = xor i1 %res.5, %cmp.dst.add.5.lower
61 %res.7 = xor i1 %res.6, %cmp.dst.add.5.upper
69 define i1 @gep_constant_negative_index(i8* %dst, i8* %lower, i8* %upper) {
70 ; CHECK-LABEL: @gep_constant_negative_index(
71 ; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr inbounds i8, i8* [[DST:%.*]], i64 -4
72 ; CHECK-NEXT: [[PRE_DST_LOWER:%.*]] = icmp uge i8* [[DST]], [[LOWER:%.*]]
73 ; CHECK-NEXT: [[PRE_DST_UPPER:%.*]] = icmp ult i8* [[DST_SUB_4]], [[UPPER:%.*]]
74 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]]
75 ; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
77 ; CHECK-NEXT: [[CMP_DST_LOWER:%.*]] = icmp uge i8* [[DST]], [[LOWER]]
78 ; CHECK-NEXT: [[CMP_DST_UPPER:%.*]] = icmp ult i8* [[DST]], [[UPPER]]
79 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[CMP_DST_UPPER]]
80 ; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 -3
81 ; CHECK-NEXT: [[CMP_DST_SUB_3_LOWER:%.*]] = icmp uge i8* [[DST_SUB_3]], [[LOWER]]
82 ; CHECK-NEXT: [[CMP_DST_SUB_3_UPPER:%.*]] = icmp ult i8* [[DST_SUB_3]], [[UPPER]]
83 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_DST_SUB_3_LOWER]]
84 ; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_DST_SUB_3_UPPER]]
85 ; CHECK-NEXT: [[CMP_DST_SUB_4_LOWER:%.*]] = icmp uge i8* [[DST_SUB_4]], [[LOWER]]
86 ; CHECK-NEXT: [[CMP_DST_SUB_4_UPPER:%.*]] = icmp ult i8* [[DST_SUB_4]], [[UPPER]]
87 ; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[CMP_DST_SUB_4_LOWER]]
88 ; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], [[CMP_DST_SUB_4_UPPER]]
89 ; CHECK-NEXT: [[DST_SUB_5:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 -5
90 ; CHECK-NEXT: [[CMP_DST_SUB_5_LOWER:%.*]] = icmp uge i8* [[DST_SUB_5]], [[LOWER]]
91 ; CHECK-NEXT: [[CMP_DST_SUB_5_UPPER:%.*]] = icmp ult i8* [[DST_SUB_5]], [[UPPER]]
92 ; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[CMP_DST_SUB_5_LOWER]]
93 ; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_SUB_5_UPPER]]
94 ; CHECK-NEXT: ret i1 [[RES_7]]
96 ; CHECK-NEXT: [[ELSE_CMP_DST_LOWER:%.*]] = icmp uge i8* [[DST]], [[LOWER]]
97 ; CHECK-NEXT: [[ELSE_CMP_DST_UPPER:%.*]] = icmp ult i8* [[DST]], [[UPPER]]
98 ; CHECK-NEXT: [[ELSE_RES_1:%.*]] = xor i1 [[ELSE_CMP_DST_LOWER]], [[ELSE_CMP_DST_UPPER]]
99 ; CHECK-NEXT: [[ELSE_DST_SUB_3:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 -3
100 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_3_LOWER:%.*]] = icmp uge i8* [[ELSE_DST_SUB_3]], [[LOWER]]
101 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_3_UPPER:%.*]] = icmp ult i8* [[ELSE_DST_SUB_3]], [[UPPER]]
102 ; CHECK-NEXT: [[ELSE_RES_2:%.*]] = xor i1 [[ELSE_RES_1]], [[ELSE_CMP_DST_SUB_3_LOWER]]
103 ; CHECK-NEXT: [[ELSE_RES_3:%.*]] = xor i1 [[ELSE_RES_2]], [[ELSE_CMP_DST_SUB_3_UPPER]]
104 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_4_LOWER:%.*]] = icmp uge i8* [[DST_SUB_4]], [[LOWER]]
105 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_4_UPPER:%.*]] = icmp ult i8* [[DST_SUB_4]], [[UPPER]]
106 ; CHECK-NEXT: [[ELSE_RES_4:%.*]] = xor i1 [[ELSE_RES_3]], [[ELSE_CMP_DST_SUB_4_LOWER]]
107 ; CHECK-NEXT: [[ELSE_RES_5:%.*]] = xor i1 [[ELSE_RES_4]], [[ELSE_CMP_DST_SUB_4_UPPER]]
108 ; CHECK-NEXT: [[ELSE_DST_SUB_5:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 -5
109 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_5_LOWER:%.*]] = icmp uge i8* [[ELSE_DST_SUB_5]], [[LOWER]]
110 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_5_UPPER:%.*]] = icmp ult i8* [[ELSE_DST_SUB_5]], [[UPPER]]
111 ; CHECK-NEXT: [[ELSE_RES_6:%.*]] = xor i1 [[ELSE_RES_5]], [[ELSE_CMP_DST_SUB_5_LOWER]]
112 ; CHECK-NEXT: [[ELSE_RES_7:%.*]] = xor i1 [[ELSE_RES_6]], [[ELSE_CMP_DST_SUB_5_UPPER]]
113 ; CHECK-NEXT: ret i1 [[ELSE_RES_7]]
115 %dst.sub.4 = getelementptr inbounds i8, i8* %dst, i64 -4
116 %pre.dst.lower = icmp uge i8* %dst, %lower
117 %pre.dst.upper = icmp ult i8* %dst.sub.4, %upper
118 %and = and i1 %pre.dst.lower, %pre.dst.upper
119 br i1 %and, label %then, label %else
122 %cmp.dst.lower = icmp uge i8* %dst, %lower
123 %cmp.dst.upper = icmp ult i8* %dst, %upper
124 %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper
126 %dst.sub.3 = getelementptr inbounds i8, i8* %dst, i64 -3
127 %cmp.dst.sub.3.lower = icmp uge i8* %dst.sub.3, %lower
128 %cmp.dst.sub.3.upper = icmp ult i8* %dst.sub.3, %upper
129 %res.2 = xor i1 %res.1, %cmp.dst.sub.3.lower
130 %res.3 = xor i1 %res.2, %cmp.dst.sub.3.upper
132 %cmp.dst.sub.4.lower = icmp uge i8* %dst.sub.4, %lower
133 %cmp.dst.sub.4.upper = icmp ult i8* %dst.sub.4, %upper
134 %res.4 = xor i1 %res.3, %cmp.dst.sub.4.lower
135 %res.5 = xor i1 %res.4, %cmp.dst.sub.4.upper
137 %dst.sub.5 = getelementptr inbounds i8, i8* %dst, i64 -5
138 %cmp.dst.sub.5.lower = icmp uge i8* %dst.sub.5, %lower
139 %cmp.dst.sub.5.upper = icmp ult i8* %dst.sub.5, %upper
140 %res.6 = xor i1 %res.5, %cmp.dst.sub.5.lower
141 %res.7 = xor i1 %res.6, %cmp.dst.sub.5.upper
146 %else.cmp.dst.lower = icmp uge i8* %dst, %lower
147 %else.cmp.dst.upper = icmp ult i8* %dst, %upper
148 %else.res.1 = xor i1 %else.cmp.dst.lower, %else.cmp.dst.upper
150 %else.dst.sub.3 = getelementptr inbounds i8, i8* %dst, i64 -3
151 %else.cmp.dst.sub.3.lower = icmp uge i8* %else.dst.sub.3, %lower
152 %else.cmp.dst.sub.3.upper = icmp ult i8* %else.dst.sub.3, %upper
153 %else.res.2 = xor i1 %else.res.1, %else.cmp.dst.sub.3.lower
154 %else.res.3 = xor i1 %else.res.2, %else.cmp.dst.sub.3.upper
156 %else.cmp.dst.sub.4.lower = icmp uge i8* %dst.sub.4, %lower
157 %else.cmp.dst.sub.4.upper = icmp ult i8* %dst.sub.4, %upper
158 %else.res.4 = xor i1 %else.res.3, %else.cmp.dst.sub.4.lower
159 %else.res.5 = xor i1 %else.res.4, %else.cmp.dst.sub.4.upper
161 %else.dst.sub.5 = getelementptr inbounds i8, i8* %dst, i64 -5
162 %else.cmp.dst.sub.5.lower = icmp uge i8* %else.dst.sub.5, %lower
163 %else.cmp.dst.sub.5.upper = icmp ult i8* %else.dst.sub.5, %upper
164 %else.res.6 = xor i1 %else.res.5, %else.cmp.dst.sub.5.lower
165 %else.res.7 = xor i1 %else.res.6, %else.cmp.dst.sub.5.upper
170 define i1 @n_unknown(i32* %dst, i32 %n, i32 %i) {
171 ; CHECK-LABEL: @n_unknown(
173 ; CHECK-NEXT: [[SUB:%.*]] = add i32 [[N:%.*]], -1
174 ; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[SUB]] to i64
175 ; CHECK-NEXT: [[PTR_N_SUB_1:%.*]] = getelementptr i32, i32* [[DST:%.*]], i64 [[IDXPROM]]
176 ; CHECK-NEXT: [[CMP_PTR_DST:%.*]] = icmp uge i32* [[PTR_N_SUB_1]], [[DST]]
177 ; CHECK-NEXT: br i1 [[CMP_PTR_DST]], label [[PRE_BB_2:%.*]], label [[EXIT:%.*]]
179 ; CHECK-NEXT: ret i1 false
181 ; CHECK-NEXT: [[PRE_2:%.*]] = icmp uge i32 [[I:%.*]], 0
182 ; CHECK-NEXT: br i1 [[PRE_2]], label [[TGT_BB:%.*]], label [[EXIT]]
184 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[I]], [[N]]
185 ; CHECK-NEXT: ret i1 [[CMP1]]
188 %sub = add i32 %n, -1
189 %idxprom = zext i32 %sub to i64
190 %ptr.n.sub.1 = getelementptr i32, i32* %dst, i64 %idxprom
191 %cmp.ptr.dst = icmp uge i32* %ptr.n.sub.1, %dst
192 br i1 %cmp.ptr.dst, label %pre.bb.2, label %exit
198 %pre.2 = icmp uge i32 %i, 0
199 br i1 %pre.2, label %tgt.bb, label %exit
202 %cmp1 = icmp ult i32 %i, %n
206 define i1 @n_known_zero_due_to_nuw(i32* %dst, i32 %n, i32 %i) {
207 ; CHECK-LABEL: @n_known_zero_due_to_nuw(
209 ; CHECK-NEXT: [[SUB:%.*]] = add i32 [[N:%.*]], -1
210 ; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[SUB]] to i64
211 ; CHECK-NEXT: [[PTR_N_SUB_1:%.*]] = getelementptr i32, i32* [[DST:%.*]], i64 [[IDXPROM]]
212 ; CHECK-NEXT: [[CMP_PTR_DST:%.*]] = icmp uge i32* [[PTR_N_SUB_1]], [[DST]]
213 ; CHECK-NEXT: br i1 [[CMP_PTR_DST]], label [[PRE_BB_2:%.*]], label [[EXIT:%.*]]
215 ; CHECK-NEXT: ret i1 false
217 ; CHECK-NEXT: [[PRE_2:%.*]] = icmp uge i32 [[I:%.*]], 0
218 ; CHECK-NEXT: br i1 [[PRE_2]], label [[TGT_BB:%.*]], label [[EXIT]]
220 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[I]], [[N]]
221 ; CHECK-NEXT: ret i1 [[CMP1]]
224 %sub = add i32 %n, -1
225 %idxprom = zext i32 %sub to i64
226 %ptr.n.sub.1 = getelementptr i32, i32* %dst, i64 %idxprom
227 %cmp.ptr.dst = icmp uge i32* %ptr.n.sub.1, %dst
228 br i1 %cmp.ptr.dst, label %pre.bb.2, label %exit
234 %pre.2 = icmp uge i32 %i, 0
235 br i1 %pre.2, label %tgt.bb, label %exit
238 %cmp1 = icmp ult i32 %i, %n
242 define i4 @ptr_N_signed_positive_explicit_check_constant_step(i8* %src, i8* %lower, i8* %upper, i16 %N) {
243 ; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step(
245 ; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
246 ; CHECK-NEXT: br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
248 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i16 [[N]]
249 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
250 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
251 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
252 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
254 ; CHECK-NEXT: ret i4 2
256 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 1, [[N]]
257 ; CHECK-NEXT: br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
259 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 1
260 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
261 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
262 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false
263 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
265 ; CHECK-NEXT: ret i4 3
269 %N.pos = icmp sge i16 %N, 0
270 br i1 %N.pos, label %entry.1, label %trap.bb
273 %src.end = getelementptr inbounds i8, i8* %src, i16 %N
274 %cmp.src.start = icmp ult i8* %src, %lower
275 %cmp.src.end = icmp uge i8* %src.end, %upper
276 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
277 br i1 %or.precond.0, label %trap.bb, label %step.check
283 %step.ult.N = icmp ult i16 1, %N
284 br i1 %step.ult.N, label %ptr.check, label %exit
287 %src.step = getelementptr inbounds i8, i8* %src, i16 1
288 %cmp.step.start = icmp ult i8* %src.step, %lower
289 %cmp.step.end = icmp uge i8* %src.step, %upper
290 %or.check = or i1 %cmp.step.start, %cmp.step.end
291 br i1 %or.check, label %trap.bb, label %exit
297 ; Same as ptr_N_signed_positive_explicit_check_constant_step, but without inbounds.
298 define i4 @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(i8* %src, i8* %lower, i8* %upper, i16 %N) {
299 ; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(
301 ; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
302 ; CHECK-NEXT: br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
304 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr i8, i8* [[SRC:%.*]], i16 [[N]]
305 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
306 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
307 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
308 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
310 ; CHECK-NEXT: ret i4 2
312 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 1, [[N]]
313 ; CHECK-NEXT: br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
315 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr i8, i8* [[SRC]], i16 1
316 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
317 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
318 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
319 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
321 ; CHECK-NEXT: ret i4 3
325 %N.pos = icmp sge i16 %N, 0
326 br i1 %N.pos, label %entry.1, label %trap.bb
329 %src.end = getelementptr i8, i8* %src, i16 %N
330 %cmp.src.start = icmp ult i8* %src, %lower
331 %cmp.src.end = icmp uge i8* %src.end, %upper
332 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
333 br i1 %or.precond.0, label %trap.bb, label %step.check
339 %step.ult.N = icmp ult i16 1, %N
340 br i1 %step.ult.N, label %ptr.check, label %exit
343 %src.step = getelementptr i8, i8* %src, i16 1
344 %cmp.step.start = icmp ult i8* %src.step, %lower
345 %cmp.step.end = icmp uge i8* %src.step, %upper
346 %or.check = or i1 %cmp.step.start, %cmp.step.end
347 br i1 %or.check, label %trap.bb, label %exit
353 define i4 @ptr_N_and_step_signed_positive_explicit_check_constant_step(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
354 ; CHECK-LABEL: @ptr_N_and_step_signed_positive_explicit_check_constant_step(
356 ; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
357 ; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
358 ; CHECK-NEXT: [[AND_1:%.*]] = and i1 [[N_POS]], [[STEP_POS]]
359 ; CHECK-NEXT: br i1 [[AND_1]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
361 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i16 [[N]]
362 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
363 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
364 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
365 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
367 ; CHECK-NEXT: ret i4 2
369 ; CHECK-NEXT: [[STEP_UGE_0:%.*]] = icmp uge i16 [[STEP]], 0
370 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP]], [[N]]
371 ; CHECK-NEXT: [[AND_2:%.*]] = and i1 [[STEP_UGE_0]], [[STEP_ULT_N]]
372 ; CHECK-NEXT: br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
374 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 1
375 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
376 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
377 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false
378 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
380 ; CHECK-NEXT: ret i4 3
384 %N.pos = icmp sge i16 %N, 0
385 %step.pos = icmp sge i16 %step, 0
386 %and.1 = and i1 %N.pos, %step.pos
387 br i1 %and.1, label %entry.1, label %trap.bb
390 %src.end = getelementptr inbounds i8, i8* %src, i16 %N
391 %cmp.src.start = icmp ult i8* %src, %lower
392 %cmp.src.end = icmp uge i8* %src.end, %upper
393 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
394 br i1 %or.precond.0, label %trap.bb, label %step.check
400 %step.uge.0 = icmp uge i16 %step, 0
401 %step.ult.N = icmp ult i16 %step, %N
402 %and.2 = and i1 %step.uge.0, %step.ult.N
403 br i1 %and.2, label %ptr.check, label %exit
406 %src.step = getelementptr inbounds i8, i8* %src, i16 1
407 %cmp.step.start = icmp ult i8* %src.step, %lower
408 %cmp.step.end = icmp uge i8* %src.step, %upper
409 %or.check = or i1 %cmp.step.start, %cmp.step.end
410 br i1 %or.check, label %trap.bb, label %exit
416 define i4 @ptr_N_and_step_signed_positive_unsigned_checks_only(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
417 ; CHECK-LABEL: @ptr_N_and_step_signed_positive_unsigned_checks_only(
419 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i16 [[N:%.*]]
420 ; CHECK-NEXT: [[NO_OVERFLOW:%.*]] = icmp ule i8* [[SRC]], [[SRC_END]]
421 ; CHECK-NEXT: br i1 [[NO_OVERFLOW]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
423 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
424 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
425 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
426 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
428 ; CHECK-NEXT: ret i4 2
430 ; CHECK-NEXT: [[STEP_UGE_0:%.*]] = icmp uge i16 [[STEP:%.*]], 0
431 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP]], [[N]]
432 ; CHECK-NEXT: [[AND_2:%.*]] = and i1 [[STEP_UGE_0]], [[STEP_ULT_N]]
433 ; CHECK-NEXT: br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
435 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 1
436 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
437 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
438 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, [[CMP_STEP_END]]
439 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
441 ; CHECK-NEXT: ret i4 3
444 %src.end = getelementptr inbounds i8, i8* %src, i16 %N
445 %no.overflow = icmp ule i8* %src, %src.end
446 br i1 %no.overflow, label %entry.1, label %trap.bb
449 %cmp.src.start = icmp ult i8* %src, %lower
450 %cmp.src.end = icmp uge i8* %src.end, %upper
451 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
452 br i1 %or.precond.0, label %trap.bb, label %step.check
458 %step.uge.0 = icmp uge i16 %step, 0
459 %step.ult.N = icmp ult i16 %step, %N
460 %and.2 = and i1 %step.uge.0, %step.ult.N
461 br i1 %and.2, label %ptr.check, label %exit
464 %src.step = getelementptr inbounds i8, i8* %src, i16 1
465 %cmp.step.start = icmp ult i8* %src.step, %lower
466 %cmp.step.end = icmp uge i8* %src.step, %upper
467 %or.check = or i1 %cmp.step.start, %cmp.step.end
468 br i1 %or.check, label %trap.bb, label %exit
474 define i4 @ptr_N_signed_positive(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
475 ; CHECK-LABEL: @ptr_N_signed_positive(
477 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i16 [[N:%.*]]
478 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
479 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
480 ; CHECK-NEXT: [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
481 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
482 ; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[N_NEG]]
483 ; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
485 ; CHECK-NEXT: ret i4 2
487 ; CHECK-NEXT: [[STEP_POS:%.*]] = icmp uge i16 [[STEP:%.*]], 0
488 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP]], [[N]]
489 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_ULT_N]]
490 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
492 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 [[STEP]]
493 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
494 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
495 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
496 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
498 ; CHECK-NEXT: ret i4 3
501 %src.end = getelementptr inbounds i8, i8* %src, i16 %N
502 %cmp.src.start = icmp ult i8* %src, %lower
503 %cmp.src.end = icmp uge i8* %src.end, %upper
504 %N.neg = icmp slt i16 %N, 0
505 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
506 %or.precond.1 = or i1 %or.precond.0, %N.neg
507 br i1 %or.precond.1, label %trap.bb, label %step.check
513 %step.pos = icmp uge i16 %step, 0
514 %step.ult.N = icmp ult i16 %step, %N
515 %and.step = and i1 %step.pos, %step.ult.N
516 br i1 %and.step, label %ptr.check, label %exit
519 %src.step = getelementptr inbounds i8, i8* %src, i16 %step
520 %cmp.step.start = icmp ult i8* %src.step, %lower
521 %cmp.step.end = icmp uge i8* %src.step, %upper
522 %or.check = or i1 %cmp.step.start, %cmp.step.end
523 br i1 %or.check, label %trap.bb, label %exit
529 define i4 @ptr_N_could_be_negative(i8* %src, i8* %lower, i8* %upper, i8 %N, i8 %step) {
530 ; CHECK-LABEL: @ptr_N_could_be_negative(
532 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i8 [[N:%.*]]
533 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
534 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
535 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
536 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
538 ; CHECK-NEXT: ret i4 2
540 ; CHECK-NEXT: [[STEP_POS:%.*]] = icmp uge i8 [[STEP:%.*]], 0
541 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i8 [[STEP]], [[N]]
542 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_ULT_N]]
543 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
545 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i8 [[STEP]]
546 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
547 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
548 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
549 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
551 ; CHECK-NEXT: ret i4 3
554 %src.end = getelementptr inbounds i8, i8* %src, i8 %N
555 %cmp.src.start = icmp ult i8* %src, %lower
556 %cmp.src.end = icmp uge i8* %src.end, %upper
557 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
558 br i1 %or.precond.0, label %trap.bb, label %step.check
564 %step.pos = icmp uge i8 %step, 0
565 %step.ult.N = icmp ult i8 %step, %N
566 %and.step = and i1 %step.pos, %step.ult.N
567 br i1 %and.step, label %ptr.check, label %exit
570 %src.step = getelementptr inbounds i8, i8* %src, i8 %step
571 %cmp.step.start = icmp ult i8* %src.step, %lower
572 %cmp.step.end = icmp uge i8* %src.step, %upper
573 %or.check = or i1 %cmp.step.start, %cmp.step.end
574 br i1 %or.check, label %trap.bb, label %exit
580 define i4 @ptr_src_uge_end(i8* %src, i8* %lower, i8* %upper, i8 %N, i8 %step) {
581 ; CHECK-LABEL: @ptr_src_uge_end(
583 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i8 [[N:%.*]]
584 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
585 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
586 ; CHECK-NEXT: [[CMP_OVERFLOW:%.*]] = icmp ugt i8* [[SRC]], [[SRC_END]]
587 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
588 ; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]]
589 ; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
591 ; CHECK-NEXT: ret i4 2
593 ; CHECK-NEXT: [[STEP_POS:%.*]] = icmp uge i8 [[STEP:%.*]], 0
594 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i8 [[STEP]], [[N]]
595 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_ULT_N]]
596 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
598 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i8 [[STEP]]
599 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
600 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
601 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
602 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
604 ; CHECK-NEXT: ret i4 3
607 %src.end = getelementptr inbounds i8, i8* %src, i8 %N
608 %cmp.src.start = icmp ult i8* %src, %lower
609 %cmp.src.end = icmp uge i8* %src.end, %upper
610 %cmp.overflow = icmp ugt i8* %src, %src.end
611 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
612 %or.precond.1 = or i1 %or.precond.0, %cmp.overflow
613 br i1 %or.precond.1, label %trap.bb, label %step.check
619 %step.pos = icmp uge i8 %step, 0
620 %step.ult.N = icmp ult i8 %step, %N
621 %and.step = and i1 %step.pos, %step.ult.N
622 br i1 %and.step, label %ptr.check, label %exit
625 %src.step = getelementptr inbounds i8, i8* %src, i8 %step
626 %cmp.step.start = icmp ult i8* %src.step, %lower
627 %cmp.step.end = icmp uge i8* %src.step, %upper
628 %or.check = or i1 %cmp.step.start, %cmp.step.end
629 br i1 %or.check, label %trap.bb, label %exit
635 define i4 @inc_ptr_N_could_be_negative(i8* %src, i8* %lower, i8* %upper, i8 %N, i8 %step) {
636 ; CHECK-LABEL: @inc_ptr_N_could_be_negative(
638 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i8 [[N:%.*]]
639 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
640 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
641 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
642 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
644 ; CHECK-NEXT: ret i4 2
646 ; CHECK-NEXT: [[STEP_POS:%.*]] = icmp uge i8 [[STEP:%.*]], 0
647 ; CHECK-NEXT: [[NEXT:%.*]] = add nuw nsw i8 [[STEP]], 2
648 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i8 [[NEXT]], [[N]]
649 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_ULT_N]]
650 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
652 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i8 [[STEP]]
653 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
654 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
655 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
656 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
658 ; CHECK-NEXT: ret i4 3
661 %src.end = getelementptr inbounds i8, i8* %src, i8 %N
662 %cmp.src.start = icmp ult i8* %src, %lower
663 %cmp.src.end = icmp uge i8* %src.end, %upper
664 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
665 br i1 %or.precond.0, label %trap.bb, label %step.check
671 %step.pos = icmp uge i8 %step, 0
672 %next = add nsw nuw i8 %step, 2
673 %step.ult.N = icmp ult i8 %next, %N
674 %and.step = and i1 %step.pos, %step.ult.N
675 br i1 %and.step, label %ptr.check, label %exit
678 %src.step = getelementptr inbounds i8, i8* %src, i8 %step
679 %cmp.step.start = icmp ult i8* %src.step, %lower
680 %cmp.step.end = icmp uge i8* %src.step, %upper
681 %or.check = or i1 %cmp.step.start, %cmp.step.end
682 br i1 %or.check, label %trap.bb, label %exit
688 define i4 @inc_ptr_src_uge_end(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
689 ; CHECK-LABEL: @inc_ptr_src_uge_end(
691 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i16 [[N:%.*]]
692 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
693 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
694 ; CHECK-NEXT: [[CMP_OVERFLOW:%.*]] = icmp ugt i8* [[SRC]], [[SRC_END]]
695 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
696 ; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]]
697 ; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
699 ; CHECK-NEXT: ret i4 2
701 ; CHECK-NEXT: [[STEP_POS:%.*]] = icmp uge i16 [[STEP:%.*]], 0
702 ; CHECK-NEXT: [[NEXT:%.*]] = add nuw nsw i16 [[STEP]], 2
703 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[NEXT]], [[N]]
704 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_ULT_N]]
705 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
707 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 [[STEP]]
708 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
709 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
710 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
711 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
713 ; CHECK-NEXT: ret i4 3
716 %src.end = getelementptr inbounds i8, i8* %src, i16 %N
717 %cmp.src.start = icmp ult i8* %src, %lower
718 %cmp.src.end = icmp uge i8* %src.end, %upper
719 %cmp.overflow = icmp ugt i8* %src, %src.end
720 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
721 %or.precond.1 = or i1 %or.precond.0, %cmp.overflow
722 br i1 %or.precond.1, label %trap.bb, label %step.check
728 %step.pos = icmp uge i16 %step, 0
729 %next = add nsw nuw i16 %step, 2
730 %step.ult.N = icmp ult i16 %next, %N
731 %and.step = and i1 %step.pos, %step.ult.N
732 br i1 %and.step, label %ptr.check, label %exit
735 %src.step = getelementptr inbounds i8, i8* %src, i16 %step
736 %cmp.step.start = icmp ult i8* %src.step, %lower
737 %cmp.step.end = icmp uge i8* %src.step, %upper
738 %or.check = or i1 %cmp.step.start, %cmp.step.end
739 br i1 %or.check, label %trap.bb, label %exit
745 define i4 @inc_ptr_src_uge_end_no_nsw_add(i8* %src, i8* %lower, i8* %upper, i16 %idx, i16 %N, i16 %step) {
746 ; CHECK-LABEL: @inc_ptr_src_uge_end_no_nsw_add(
747 ; CHECK-NEXT: entry.1:
748 ; CHECK-NEXT: [[IDX_POS:%.*]] = icmp sge i16 [[IDX:%.*]], 0
749 ; CHECK-NEXT: br i1 [[IDX_POS]], label [[ENTRY:%.*]], label [[TRAP_BB:%.*]]
751 ; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i16 [[IDX]]
752 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC_IDX]], [[LOWER:%.*]]
753 ; CHECK-NEXT: br i1 [[CMP_SRC_START]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
755 ; CHECK-NEXT: ret i4 2
757 ; CHECK-NEXT: [[NEXT:%.*]] = add i16 [[IDX]], 2
758 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 [[NEXT]]
759 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
760 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER:%.*]]
761 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
762 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT:%.*]]
764 ; CHECK-NEXT: ret i4 3
767 %idx.pos = icmp sge i16 %idx, 0
768 br i1 %idx.pos, label %entry, label %trap.bb
771 %src.idx = getelementptr inbounds i8, i8* %src, i16 %idx
772 %cmp.src.start = icmp ult i8* %src.idx, %lower
773 br i1 %cmp.src.start, label %trap.bb, label %step.check
779 %next = add i16 %idx, 2
780 %src.step = getelementptr inbounds i8, i8* %src, i16 %next
781 %cmp.step.start = icmp ult i8* %src.step, %lower
782 %cmp.step.end = icmp uge i8* %src.step, %upper
783 %or.check = or i1 %cmp.step.start, %cmp.step.end
784 br i1 %or.check, label %trap.bb, label %exit
790 define i4 @inc_ptr_src_uge_end_no_nsw_add_sge_0(i8* %src, i8* %lower, i8* %upper, i16 %idx, i16 %N, i16 %step) {
791 ; CHECK-LABEL: @inc_ptr_src_uge_end_no_nsw_add_sge_0(
792 ; CHECK-NEXT: entry.1:
793 ; CHECK-NEXT: [[IDX_POS:%.*]] = icmp sge i16 [[IDX:%.*]], 0
794 ; CHECK-NEXT: br i1 [[IDX_POS]], label [[ENTRY:%.*]], label [[TRAP_BB:%.*]]
796 ; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i16 [[IDX]]
797 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC_IDX]], [[LOWER:%.*]]
798 ; CHECK-NEXT: br i1 [[CMP_SRC_START]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
800 ; CHECK-NEXT: ret i4 2
802 ; CHECK-NEXT: [[NEXT:%.*]] = add i16 [[IDX]], 2
803 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 [[NEXT]]
804 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
805 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER:%.*]]
806 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
807 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT:%.*]]
809 ; CHECK-NEXT: ret i4 3
812 %idx.pos = icmp sge i16 %idx, 0
813 br i1 %idx.pos, label %entry, label %trap.bb
816 %src.idx = getelementptr inbounds i8, i8* %src, i16 %idx
817 %cmp.src.start = icmp ult i8* %src.idx, %lower
818 br i1 %cmp.src.start, label %trap.bb, label %step.check
824 %next = add i16 %idx, 2
825 %src.step = getelementptr inbounds i8, i8* %src, i16 %next
826 %cmp.step.start = icmp ult i8* %src.step, %lower
827 %cmp.step.end = icmp uge i8* %src.step, %upper
828 %or.check = or i1 %cmp.step.start, %cmp.step.end
829 br i1 %or.check, label %trap.bb, label %exit
838 ; N might be negative, meaning %src.end could be < %src! Cannot remove checks!
839 define i4 @ptr_N_unsigned_positive(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
840 ; CHECK-LABEL: @ptr_N_unsigned_positive(
842 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i16 [[N:%.*]]
843 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
844 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
845 ; CHECK-NEXT: [[N_NEG:%.*]] = icmp ult i16 [[N]], 0
846 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
847 ; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[N_NEG]]
848 ; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
850 ; CHECK-NEXT: ret i4 2
852 ; CHECK-NEXT: [[STEP_POS:%.*]] = icmp uge i16 [[STEP:%.*]], 0
853 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP]], [[N]]
854 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_ULT_N]]
855 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
857 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 [[STEP]]
858 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
859 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
860 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
861 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
863 ; CHECK-NEXT: ret i4 3
866 %src.end = getelementptr inbounds i8, i8* %src, i16 %N
867 %cmp.src.start = icmp ult i8* %src, %lower
868 %cmp.src.end = icmp uge i8* %src.end, %upper
869 %N.neg = icmp ult i16 %N, 0
870 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
871 %or.precond.1 = or i1 %or.precond.0, %N.neg
872 br i1 %or.precond.1, label %trap.bb, label %step.check
878 %step.pos = icmp uge i16 %step, 0
879 %step.ult.N = icmp ult i16 %step, %N
880 %and.step = and i1 %step.pos, %step.ult.N
881 br i1 %and.step, label %ptr.check, label %exit
884 %src.step = getelementptr inbounds i8, i8* %src, i16 %step
885 %cmp.step.start = icmp ult i8* %src.step, %lower
886 %cmp.step.end = icmp uge i8* %src.step, %upper
887 %or.check = or i1 %cmp.step.start, %cmp.step.end
888 br i1 %or.check, label %trap.bb, label %exit
894 define i4 @ptr_N_signed_positive_assume(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
895 ; CHECK-LABEL: @ptr_N_signed_positive_assume(
897 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i16 [[N:%.*]]
898 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
899 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
900 ; CHECK-NEXT: [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
901 ; CHECK-NEXT: call void @llvm.assume(i1 [[N_NEG]])
902 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
903 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
905 ; CHECK-NEXT: ret i4 2
907 ; CHECK-NEXT: [[STEP_POS:%.*]] = icmp uge i16 [[STEP:%.*]], 0
908 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP]], [[N]]
909 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_ULT_N]]
910 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
912 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 [[STEP]]
913 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
914 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
915 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
916 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
918 ; CHECK-NEXT: ret i4 3
921 %src.end = getelementptr inbounds i8, i8* %src, i16 %N
922 %cmp.src.start = icmp ult i8* %src, %lower
923 %cmp.src.end = icmp uge i8* %src.end, %upper
924 %N.neg = icmp slt i16 %N, 0
925 call void @llvm.assume(i1 %N.neg)
926 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
927 br i1 %or.precond.0, label %trap.bb, label %step.check
933 %step.pos = icmp uge i16 %step, 0
934 %step.ult.N = icmp ult i16 %step, %N
935 %and.step = and i1 %step.pos, %step.ult.N
936 br i1 %and.step, label %ptr.check, label %exit
939 %src.step = getelementptr inbounds i8, i8* %src, i16 %step
940 %cmp.step.start = icmp ult i8* %src.step, %lower
941 %cmp.step.end = icmp uge i8* %src.step, %upper
942 %or.check = or i1 %cmp.step.start, %cmp.step.end
943 br i1 %or.check, label %trap.bb, label %exit
949 define i4 @ptr_N_step_zext_n_zext(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
950 ; CHECK-LABEL: @ptr_N_step_zext_n_zext(
952 ; CHECK-NEXT: [[N_ADD_1:%.*]] = add nuw nsw i16 [[N:%.*]], 1
953 ; CHECK-NEXT: [[N_ADD_1_EXT:%.*]] = zext i16 [[N_ADD_1]] to i32
954 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i32 [[N_ADD_1_EXT]]
955 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
956 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
957 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
958 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
960 ; CHECK-NEXT: ret i4 2
962 ; CHECK-NEXT: [[STEP_ADD_1:%.*]] = add nuw nsw i16 [[STEP:%.*]], 1
963 ; CHECK-NEXT: [[STEP_ADD_1_EXT:%.*]] = zext i16 [[STEP_ADD_1]] to i32
964 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i32 [[STEP_ADD_1_EXT]], [[N_ADD_1_EXT]]
965 ; CHECK-NEXT: br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
967 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i32 [[STEP_ADD_1_EXT]]
968 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
969 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
970 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], false
971 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
973 ; CHECK-NEXT: ret i4 3
977 %N.add.1 = add nuw nsw i16 %N, 1
978 %N.add.1.ext = zext i16 %N.add.1 to i32
979 %src.end = getelementptr inbounds i8, i8* %src, i32 %N.add.1.ext
980 %cmp.src.start = icmp ult i8* %src, %lower
981 %cmp.src.end = icmp uge i8* %src.end, %upper
982 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
983 br i1 %or.precond.0, label %trap.bb, label %step.check
989 %step.add.1 = add nuw nsw i16 %step, 1
990 %step.add.1.ext = zext i16 %step.add.1 to i32
991 %step.ult.N = icmp ult i32 %step.add.1.ext, %N.add.1.ext
992 br i1 %step.ult.N, label %ptr.check, label %exit
995 %src.step = getelementptr inbounds i8, i8* %src, i32 %step.add.1.ext
996 %cmp.step.start = icmp ult i8* %src.step, %lower
997 %cmp.step.end = icmp uge i8* %src.step, %upper
998 %or.check = or i1 %cmp.step.start, %cmp.step.end
999 br i1 %or.check, label %trap.bb, label %exit
1005 define i4 @ptr_N_step_zext_n_zext_out_of_bounds(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
1006 ; CHECK-LABEL: @ptr_N_step_zext_n_zext_out_of_bounds(
1007 ; CHECK-NEXT: entry:
1008 ; CHECK-NEXT: [[N_ADD_2:%.*]] = add nuw nsw i16 [[N:%.*]], 2
1009 ; CHECK-NEXT: [[N_ADD_2_EXT:%.*]] = zext i16 [[N_ADD_2]] to i32
1010 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i32 [[N_ADD_2_EXT]]
1011 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
1012 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
1013 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
1014 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
1016 ; CHECK-NEXT: ret i4 2
1017 ; CHECK: step.check:
1018 ; CHECK-NEXT: [[STEP_ADD_2:%.*]] = add nuw nsw i16 [[STEP:%.*]], 2
1019 ; CHECK-NEXT: [[STEP_ADD_2_EXT:%.*]] = zext i16 [[STEP_ADD_2]] to i32
1020 ; CHECK-NEXT: [[STEP_EXT:%.*]] = zext i16 [[STEP]] to i32
1021 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i32 [[STEP_EXT]], [[N_ADD_2_EXT]]
1022 ; CHECK-NEXT: br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
1024 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i32 [[STEP_ADD_2_EXT]]
1025 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
1026 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
1027 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
1028 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
1030 ; CHECK-NEXT: ret i4 3
1034 %N.add.2 = add nuw nsw i16 %N, 2
1035 %N.add.2.ext = zext i16 %N.add.2 to i32
1036 %src.end = getelementptr inbounds i8, i8* %src, i32 %N.add.2.ext
1037 %cmp.src.start = icmp ult i8* %src, %lower
1038 %cmp.src.end = icmp uge i8* %src.end, %upper
1039 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
1040 br i1 %or.precond.0, label %trap.bb, label %step.check
1046 %step.add.2 = add nuw nsw i16 %step, 2
1047 %step.add.2.ext = zext i16 %step.add.2 to i32
1048 %step.ext = zext i16 %step to i32
1049 %step.ult.N = icmp ult i32 %step.ext, %N.add.2.ext
1050 br i1 %step.ult.N, label %ptr.check, label %exit
1053 %src.step = getelementptr inbounds i8, i8* %src, i32 %step.add.2.ext
1054 %cmp.step.start = icmp ult i8* %src.step, %lower
1055 %cmp.step.end = icmp uge i8* %src.step, %upper
1056 %or.check = or i1 %cmp.step.start, %cmp.step.end
1057 br i1 %or.check, label %trap.bb, label %exit