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 uge ptr [[DST]], [[LOWER:%.*]]
10 ; CHECK-NEXT: [[PRE_DST_UPPER:%.*]] = icmp ult 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:%.*]]
14 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
15 ; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
16 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], true
17 ; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], true
18 ; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], true
19 ; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true
20 ; CHECK-NEXT: [[DST_ADD_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5
21 ; CHECK-NEXT: [[CMP_DST_ADD_5_UPPER:%.*]] = icmp ult ptr [[DST_ADD_5]], [[UPPER]]
22 ; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], true
23 ; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_ADD_5_UPPER]]
24 ; CHECK-NEXT: ret i1 [[RES_7]]
26 ; CHECK-NEXT: ret i1 false
28 %dst.add.4 = getelementptr inbounds i8, ptr %dst, i64 4
29 %pre.dst.lower = icmp uge ptr %dst, %lower
30 %pre.dst.upper = icmp ult ptr %dst.add.4, %upper
31 %and = and i1 %pre.dst.lower, %pre.dst.upper
32 br i1 %and, label %then, label %else
35 %cmp.dst.lower = icmp uge ptr %dst, %lower
36 %cmp.dst.upper = icmp ult ptr %dst, %upper
37 %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper
38 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
39 %cmp.dst.add.3.lower = icmp uge ptr %dst.add.3, %lower
40 %cmp.dst.add.3.upper = icmp ult ptr %dst.add.3, %upper
41 %res.2 = xor i1 %res.1, %cmp.dst.add.3.lower
42 %res.3 = xor i1 %res.2, %cmp.dst.add.3.upper
43 %cmp.dst.add.4.lower = icmp uge ptr %dst.add.4, %lower
44 %cmp.dst.add.4.upper = icmp ult ptr %dst.add.4, %upper
45 %res.4 = xor i1 %res.3, %cmp.dst.add.4.lower
46 %res.5 = xor i1 %res.4, %cmp.dst.add.4.upper
47 %dst.add.5 = getelementptr inbounds i8, ptr %dst, i64 5
48 %cmp.dst.add.5.lower = icmp uge ptr %dst.add.5, %lower
49 %cmp.dst.add.5.upper = icmp ult ptr %dst.add.5, %upper
50 %res.6 = xor i1 %res.5, %cmp.dst.add.5.lower
51 %res.7 = xor i1 %res.6, %cmp.dst.add.5.upper
58 define i1 @gep_constant_negative_index(ptr %dst, ptr %lower, ptr %upper) {
59 ; CHECK-LABEL: @gep_constant_negative_index(
60 ; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 -4
61 ; CHECK-NEXT: [[PRE_DST_LOWER:%.*]] = icmp uge ptr [[DST]], [[LOWER:%.*]]
62 ; CHECK-NEXT: [[PRE_DST_UPPER:%.*]] = icmp ult ptr [[DST_SUB_4]], [[UPPER:%.*]]
63 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]]
64 ; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
66 ; CHECK-NEXT: [[CMP_DST_UPPER:%.*]] = icmp ult ptr [[DST]], [[UPPER]]
67 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[CMP_DST_UPPER]]
68 ; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -3
69 ; CHECK-NEXT: [[CMP_DST_SUB_3_LOWER:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]
70 ; CHECK-NEXT: [[CMP_DST_SUB_3_UPPER:%.*]] = icmp ult ptr [[DST_SUB_3]], [[UPPER]]
71 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_DST_SUB_3_LOWER]]
72 ; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_DST_SUB_3_UPPER]]
73 ; CHECK-NEXT: [[CMP_DST_SUB_4_LOWER:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
74 ; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[CMP_DST_SUB_4_LOWER]]
75 ; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true
76 ; CHECK-NEXT: [[DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5
77 ; CHECK-NEXT: [[CMP_DST_SUB_5_LOWER:%.*]] = icmp uge ptr [[DST_SUB_5]], [[LOWER]]
78 ; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[CMP_DST_SUB_5_LOWER]]
79 ; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], true
80 ; CHECK-NEXT: ret i1 [[RES_7]]
82 ; CHECK-NEXT: [[ELSE_CMP_DST_LOWER:%.*]] = icmp uge ptr [[DST]], [[LOWER]]
83 ; CHECK-NEXT: [[ELSE_CMP_DST_UPPER:%.*]] = icmp ult ptr [[DST]], [[UPPER]]
84 ; CHECK-NEXT: [[ELSE_RES_1:%.*]] = xor i1 [[ELSE_CMP_DST_LOWER]], [[ELSE_CMP_DST_UPPER]]
85 ; CHECK-NEXT: [[ELSE_DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -3
86 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_3_LOWER:%.*]] = icmp uge ptr [[ELSE_DST_SUB_3]], [[LOWER]]
87 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_3_UPPER:%.*]] = icmp ult ptr [[ELSE_DST_SUB_3]], [[UPPER]]
88 ; CHECK-NEXT: [[ELSE_RES_2:%.*]] = xor i1 [[ELSE_RES_1]], [[ELSE_CMP_DST_SUB_3_LOWER]]
89 ; CHECK-NEXT: [[ELSE_RES_3:%.*]] = xor i1 [[ELSE_RES_2]], [[ELSE_CMP_DST_SUB_3_UPPER]]
90 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_4_LOWER:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
91 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_4_UPPER:%.*]] = icmp ult ptr [[DST_SUB_4]], [[UPPER]]
92 ; CHECK-NEXT: [[ELSE_RES_4:%.*]] = xor i1 [[ELSE_RES_3]], [[ELSE_CMP_DST_SUB_4_LOWER]]
93 ; CHECK-NEXT: [[ELSE_RES_5:%.*]] = xor i1 [[ELSE_RES_4]], [[ELSE_CMP_DST_SUB_4_UPPER]]
94 ; CHECK-NEXT: [[ELSE_DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5
95 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_5_LOWER:%.*]] = icmp uge ptr [[ELSE_DST_SUB_5]], [[LOWER]]
96 ; CHECK-NEXT: [[ELSE_CMP_DST_SUB_5_UPPER:%.*]] = icmp ult ptr [[ELSE_DST_SUB_5]], [[UPPER]]
97 ; CHECK-NEXT: [[ELSE_RES_6:%.*]] = xor i1 [[ELSE_RES_5]], [[ELSE_CMP_DST_SUB_5_LOWER]]
98 ; CHECK-NEXT: [[ELSE_RES_7:%.*]] = xor i1 [[ELSE_RES_6]], [[ELSE_CMP_DST_SUB_5_UPPER]]
99 ; CHECK-NEXT: ret i1 [[ELSE_RES_7]]
101 %dst.sub.4 = getelementptr inbounds i8, ptr %dst, i64 -4
102 %pre.dst.lower = icmp uge ptr %dst, %lower
103 %pre.dst.upper = icmp ult ptr %dst.sub.4, %upper
104 %and = and i1 %pre.dst.lower, %pre.dst.upper
105 br i1 %and, label %then, label %else
108 %cmp.dst.lower = icmp uge ptr %dst, %lower
109 %cmp.dst.upper = icmp ult ptr %dst, %upper
110 %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper
111 %dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3
112 %cmp.dst.sub.3.lower = icmp uge ptr %dst.sub.3, %lower
113 %cmp.dst.sub.3.upper = icmp ult ptr %dst.sub.3, %upper
114 %res.2 = xor i1 %res.1, %cmp.dst.sub.3.lower
115 %res.3 = xor i1 %res.2, %cmp.dst.sub.3.upper
116 %cmp.dst.sub.4.lower = icmp uge ptr %dst.sub.4, %lower
117 %cmp.dst.sub.4.upper = icmp ult ptr %dst.sub.4, %upper
118 %res.4 = xor i1 %res.3, %cmp.dst.sub.4.lower
119 %res.5 = xor i1 %res.4, %cmp.dst.sub.4.upper
120 %dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5
121 %cmp.dst.sub.5.lower = icmp uge ptr %dst.sub.5, %lower
122 %cmp.dst.sub.5.upper = icmp ult ptr %dst.sub.5, %upper
123 %res.6 = xor i1 %res.5, %cmp.dst.sub.5.lower
124 %res.7 = xor i1 %res.6, %cmp.dst.sub.5.upper
128 %else.cmp.dst.lower = icmp uge ptr %dst, %lower
129 %else.cmp.dst.upper = icmp ult ptr %dst, %upper
130 %else.res.1 = xor i1 %else.cmp.dst.lower, %else.cmp.dst.upper
131 %else.dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3
132 %else.cmp.dst.sub.3.lower = icmp uge ptr %else.dst.sub.3, %lower
133 %else.cmp.dst.sub.3.upper = icmp ult ptr %else.dst.sub.3, %upper
134 %else.res.2 = xor i1 %else.res.1, %else.cmp.dst.sub.3.lower
135 %else.res.3 = xor i1 %else.res.2, %else.cmp.dst.sub.3.upper
136 %else.cmp.dst.sub.4.lower = icmp uge ptr %dst.sub.4, %lower
137 %else.cmp.dst.sub.4.upper = icmp ult ptr %dst.sub.4, %upper
138 %else.res.4 = xor i1 %else.res.3, %else.cmp.dst.sub.4.lower
139 %else.res.5 = xor i1 %else.res.4, %else.cmp.dst.sub.4.upper
140 %else.dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5
141 %else.cmp.dst.sub.5.lower = icmp uge ptr %else.dst.sub.5, %lower
142 %else.cmp.dst.sub.5.upper = icmp ult ptr %else.dst.sub.5, %upper
143 %else.res.6 = xor i1 %else.res.5, %else.cmp.dst.sub.5.lower
144 %else.res.7 = xor i1 %else.res.6, %else.cmp.dst.sub.5.upper
148 define i4 @ptr_N_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N) {
149 ; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step(
151 ; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
152 ; CHECK-NEXT: br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
154 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]]
155 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
156 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
157 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
158 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
160 ; CHECK-NEXT: ret i4 2
162 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 1, [[N]]
163 ; CHECK-NEXT: br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
165 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
166 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false
167 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
169 ; CHECK-NEXT: ret i4 3
172 %N.pos = icmp sge i16 %N, 0
173 br i1 %N.pos, label %entry.1, label %trap.bb
176 %src.end = getelementptr inbounds i8, ptr %src, i16 %N
177 %cmp.src.start = icmp ult ptr %src, %lower
178 %cmp.src.end = icmp uge ptr %src.end, %upper
179 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
180 br i1 %or.precond.0, label %trap.bb, label %step.check
186 %step.ult.N = icmp ult i16 1, %N
187 br i1 %step.ult.N, label %ptr.check, label %exit
190 %src.step = getelementptr inbounds i8, ptr %src, i16 1
191 %cmp.step.start = icmp ult ptr %src.step, %lower
192 %cmp.step.end = icmp uge ptr %src.step, %upper
193 %or.check = or i1 %cmp.step.start, %cmp.step.end
194 br i1 %or.check, label %trap.bb, label %exit
200 ; Same as ptr_N_signed_positive_explicit_check_constant_step, but without inbounds.
201 define i4 @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(ptr %src, ptr %lower, ptr %upper, i16 %N) {
202 ; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(
204 ; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
205 ; CHECK-NEXT: br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
207 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr i8, ptr [[SRC:%.*]], i16 [[N]]
208 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
209 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
210 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
211 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
213 ; CHECK-NEXT: ret i4 2
215 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 1, [[N]]
216 ; CHECK-NEXT: br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
218 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr i8, ptr [[SRC]], i16 1
219 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
220 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
221 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
222 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
224 ; CHECK-NEXT: ret i4 3
227 %N.pos = icmp sge i16 %N, 0
228 br i1 %N.pos, label %entry.1, label %trap.bb
231 %src.end = getelementptr i8, ptr %src, i16 %N
232 %cmp.src.start = icmp ult ptr %src, %lower
233 %cmp.src.end = icmp uge ptr %src.end, %upper
234 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
235 br i1 %or.precond.0, label %trap.bb, label %step.check
241 %step.ult.N = icmp ult i16 1, %N
242 br i1 %step.ult.N, label %ptr.check, label %exit
245 %src.step = getelementptr i8, ptr %src, i16 1
246 %cmp.step.start = icmp ult ptr %src.step, %lower
247 %cmp.step.end = icmp uge ptr %src.step, %upper
248 %or.check = or i1 %cmp.step.start, %cmp.step.end
249 br i1 %or.check, label %trap.bb, label %exit
255 define i4 @ptr_N_and_step_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
256 ; CHECK-LABEL: @ptr_N_and_step_signed_positive_explicit_check_constant_step(
258 ; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
259 ; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
260 ; CHECK-NEXT: [[AND_1:%.*]] = and i1 [[N_POS]], [[STEP_POS]]
261 ; CHECK-NEXT: br i1 [[AND_1]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
263 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]]
264 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
265 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
266 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
267 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
269 ; CHECK-NEXT: ret i4 2
271 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP]], [[N]]
272 ; CHECK-NEXT: [[AND_2:%.*]] = and i1 true, [[STEP_ULT_N]]
273 ; CHECK-NEXT: br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
275 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
276 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false
277 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
279 ; CHECK-NEXT: ret i4 3
282 %N.pos = icmp sge i16 %N, 0
283 %step.pos = icmp sge i16 %step, 0
284 %and.1 = and i1 %N.pos, %step.pos
285 br i1 %and.1, label %entry.1, label %trap.bb
288 %src.end = getelementptr inbounds i8, ptr %src, i16 %N
289 %cmp.src.start = icmp ult ptr %src, %lower
290 %cmp.src.end = icmp uge ptr %src.end, %upper
291 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
292 br i1 %or.precond.0, label %trap.bb, label %step.check
298 %step.uge.0 = icmp uge i16 %step, 0
299 %step.ult.N = icmp ult i16 %step, %N
300 %and.2 = and i1 %step.uge.0, %step.ult.N
301 br i1 %and.2, label %ptr.check, label %exit
304 %src.step = getelementptr inbounds i8, ptr %src, i16 1
305 %cmp.step.start = icmp ult ptr %src.step, %lower
306 %cmp.step.end = icmp uge ptr %src.step, %upper
307 %or.check = or i1 %cmp.step.start, %cmp.step.end
308 br i1 %or.check, label %trap.bb, label %exit
314 define i4 @ptr_N_and_step_signed_positive_unsigned_checks_only(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
315 ; CHECK-LABEL: @ptr_N_and_step_signed_positive_unsigned_checks_only(
317 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
318 ; CHECK-NEXT: [[NO_OVERFLOW:%.*]] = icmp ule ptr [[SRC]], [[SRC_END]]
319 ; CHECK-NEXT: br i1 [[NO_OVERFLOW]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
321 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
322 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
323 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
324 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
326 ; CHECK-NEXT: ret i4 2
328 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]]
329 ; CHECK-NEXT: [[AND_2:%.*]] = and i1 true, [[STEP_ULT_N]]
330 ; CHECK-NEXT: br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
332 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
333 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
334 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, [[CMP_STEP_END]]
335 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
337 ; CHECK-NEXT: ret i4 3
340 %src.end = getelementptr inbounds i8, ptr %src, i16 %N
341 %no.overflow = icmp ule ptr %src, %src.end
342 br i1 %no.overflow, label %entry.1, label %trap.bb
345 %cmp.src.start = icmp ult ptr %src, %lower
346 %cmp.src.end = icmp uge ptr %src.end, %upper
347 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
348 br i1 %or.precond.0, label %trap.bb, label %step.check
354 %step.uge.0 = icmp uge i16 %step, 0
355 %step.ult.N = icmp ult i16 %step, %N
356 %and.2 = and i1 %step.uge.0, %step.ult.N
357 br i1 %and.2, label %ptr.check, label %exit
360 %src.step = getelementptr inbounds i8, ptr %src, i16 1
361 %cmp.step.start = icmp ult ptr %src.step, %lower
362 %cmp.step.end = icmp uge ptr %src.step, %upper
363 %or.check = or i1 %cmp.step.start, %cmp.step.end
364 br i1 %or.check, label %trap.bb, label %exit
370 define i4 @ptr_N_signed_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
371 ; CHECK-LABEL: @ptr_N_signed_positive(
373 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
374 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
375 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
376 ; CHECK-NEXT: [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
377 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
378 ; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[N_NEG]]
379 ; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
381 ; CHECK-NEXT: ret i4 2
383 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]]
384 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
385 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
387 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
388 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false
389 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
391 ; CHECK-NEXT: ret i4 3
394 %src.end = getelementptr inbounds i8, ptr %src, i16 %N
395 %cmp.src.start = icmp ult ptr %src, %lower
396 %cmp.src.end = icmp uge ptr %src.end, %upper
397 %N.neg = icmp slt i16 %N, 0
398 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
399 %or.precond.1 = or i1 %or.precond.0, %N.neg
400 br i1 %or.precond.1, label %trap.bb, label %step.check
406 %step.pos = icmp uge i16 %step, 0
407 %step.ult.N = icmp ult i16 %step, %N
408 %and.step = and i1 %step.pos, %step.ult.N
409 br i1 %and.step, label %ptr.check, label %exit
412 %src.step = getelementptr inbounds i8, ptr %src, i16 %step
413 %cmp.step.start = icmp ult ptr %src.step, %lower
414 %cmp.step.end = icmp uge ptr %src.step, %upper
415 %or.check = or i1 %cmp.step.start, %cmp.step.end
416 br i1 %or.check, label %trap.bb, label %exit
422 define i4 @ptr_N_could_be_negative(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
423 ; CHECK-LABEL: @ptr_N_could_be_negative(
425 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
426 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
427 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
428 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
429 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
431 ; CHECK-NEXT: ret i4 2
433 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i8 [[STEP:%.*]], [[N]]
434 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
435 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
437 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
438 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
439 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
440 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
441 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
443 ; CHECK-NEXT: ret i4 3
446 %src.end = getelementptr inbounds i8, ptr %src, i8 %N
447 %cmp.src.start = icmp ult ptr %src, %lower
448 %cmp.src.end = icmp uge ptr %src.end, %upper
449 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
450 br i1 %or.precond.0, label %trap.bb, label %step.check
456 %step.pos = icmp uge i8 %step, 0
457 %step.ult.N = icmp ult i8 %step, %N
458 %and.step = and i1 %step.pos, %step.ult.N
459 br i1 %and.step, label %ptr.check, label %exit
462 %src.step = getelementptr inbounds i8, ptr %src, i8 %step
463 %cmp.step.start = icmp ult ptr %src.step, %lower
464 %cmp.step.end = icmp uge ptr %src.step, %upper
465 %or.check = or i1 %cmp.step.start, %cmp.step.end
466 br i1 %or.check, label %trap.bb, label %exit
472 define i4 @ptr_src_uge_end(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
473 ; CHECK-LABEL: @ptr_src_uge_end(
475 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
476 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
477 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
478 ; CHECK-NEXT: [[CMP_OVERFLOW:%.*]] = icmp ugt ptr [[SRC]], [[SRC_END]]
479 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
480 ; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]]
481 ; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
483 ; CHECK-NEXT: ret i4 2
485 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i8 [[STEP:%.*]], [[N]]
486 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
487 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
489 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
490 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
491 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
492 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
493 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
495 ; CHECK-NEXT: ret i4 3
498 %src.end = getelementptr inbounds i8, ptr %src, i8 %N
499 %cmp.src.start = icmp ult ptr %src, %lower
500 %cmp.src.end = icmp uge ptr %src.end, %upper
501 %cmp.overflow = icmp ugt ptr %src, %src.end
502 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
503 %or.precond.1 = or i1 %or.precond.0, %cmp.overflow
504 br i1 %or.precond.1, label %trap.bb, label %step.check
510 %step.pos = icmp uge i8 %step, 0
511 %step.ult.N = icmp ult i8 %step, %N
512 %and.step = and i1 %step.pos, %step.ult.N
513 br i1 %and.step, label %ptr.check, label %exit
516 %src.step = getelementptr inbounds i8, ptr %src, i8 %step
517 %cmp.step.start = icmp ult ptr %src.step, %lower
518 %cmp.step.end = icmp uge ptr %src.step, %upper
519 %or.check = or i1 %cmp.step.start, %cmp.step.end
520 br i1 %or.check, label %trap.bb, label %exit
526 ; N might be negative, meaning %src.end could be < %src! Cannot remove checks!
527 define i4 @ptr_N_unsigned_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
528 ; CHECK-LABEL: @ptr_N_unsigned_positive(
530 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
531 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
532 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
533 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
534 ; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], false
535 ; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
537 ; CHECK-NEXT: ret i4 2
539 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]]
540 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
541 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
543 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
544 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
545 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
546 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
547 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
549 ; CHECK-NEXT: ret i4 3
552 %src.end = getelementptr inbounds i8, ptr %src, i16 %N
553 %cmp.src.start = icmp ult ptr %src, %lower
554 %cmp.src.end = icmp uge ptr %src.end, %upper
555 %N.neg = icmp ult i16 %N, 0
556 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
557 %or.precond.1 = or i1 %or.precond.0, %N.neg
558 br i1 %or.precond.1, label %trap.bb, label %step.check
564 %step.pos = icmp uge i16 %step, 0
565 %step.ult.N = icmp ult i16 %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, ptr %src, i16 %step
571 %cmp.step.start = icmp ult ptr %src.step, %lower
572 %cmp.step.end = icmp uge ptr %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_N_signed_positive_assume(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
581 ; CHECK-LABEL: @ptr_N_signed_positive_assume(
583 ; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
584 ; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
585 ; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
586 ; CHECK-NEXT: [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
587 ; CHECK-NEXT: call void @llvm.assume(i1 [[N_NEG]])
588 ; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
589 ; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
591 ; CHECK-NEXT: ret i4 2
593 ; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]]
594 ; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
595 ; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
597 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
598 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
599 ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
600 ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
601 ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
603 ; CHECK-NEXT: ret i4 3
606 %src.end = getelementptr inbounds i8, ptr %src, i16 %N
607 %cmp.src.start = icmp ult ptr %src, %lower
608 %cmp.src.end = icmp uge ptr %src.end, %upper
609 %N.neg = icmp slt i16 %N, 0
610 call void @llvm.assume(i1 %N.neg)
611 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
612 br i1 %or.precond.0, label %trap.bb, label %step.check
618 %step.pos = icmp uge i16 %step, 0
619 %step.ult.N = icmp ult i16 %step, %N
620 %and.step = and i1 %step.pos, %step.ult.N
621 br i1 %and.step, label %ptr.check, label %exit
624 %src.step = getelementptr inbounds i8, ptr %src, i16 %step
625 %cmp.step.start = icmp ult ptr %src.step, %lower
626 %cmp.step.end = icmp uge ptr %src.step, %upper
627 %or.check = or i1 %cmp.step.start, %cmp.step.end
628 br i1 %or.check, label %trap.bb, label %exit
634 define i1 @test_nusw(ptr %p, i32 %x, i32 %y) {
635 ; CHECK-LABEL: @test_nusw(
636 ; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X:%.*]] to i64
637 ; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y:%.*]] to i64
638 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X_EXT]], [[Y_EXT]]
639 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]])
640 ; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[X_EXT]]
641 ; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nusw i8, ptr [[P]], i64 [[Y_EXT]]
642 ; CHECK-NEXT: ret i1 true
644 %x.ext = zext i32 %x to i64
645 %y.ext = zext i32 %y to i64
646 %cmp1 = icmp ugt i64 %x.ext, %y.ext
647 call void @llvm.assume(i1 %cmp1)
648 %gep.x = getelementptr nusw i8, ptr %p, i64 %x.ext
649 %gep.y = getelementptr nusw i8, ptr %p, i64 %y.ext
650 %cmp2 = icmp ugt ptr %gep.x, %gep.y
654 define i1 @test_nusw_nested(ptr %p, i32 %x, i32 %y) {
655 ; CHECK-LABEL: @test_nusw_nested(
656 ; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X:%.*]] to i64
657 ; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y:%.*]] to i64
658 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X_EXT]], [[Y_EXT]]
659 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]])
660 ; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[X_EXT]]
661 ; CHECK-NEXT: [[GEP_X1:%.*]] = getelementptr nusw i8, ptr [[GEP_X]], i64 1
662 ; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nusw i8, ptr [[P]], i64 [[Y_EXT]]
663 ; CHECK-NEXT: ret i1 true
665 %x.ext = zext i32 %x to i64
666 %y.ext = zext i32 %y to i64
667 %cmp1 = icmp ugt i64 %x.ext, %y.ext
668 call void @llvm.assume(i1 %cmp1)
669 %gep.x = getelementptr nusw i8, ptr %p, i64 %x.ext
670 %gep.x1 = getelementptr nusw i8, ptr %gep.x, i64 1
671 %gep.y = getelementptr nusw i8, ptr %p, i64 %y.ext
672 %cmp2 = icmp ugt ptr %gep.x1, %gep.y
676 define i1 @test_missing_nusw(ptr %p, i32 %x, i32 %y) {
677 ; CHECK-LABEL: @test_missing_nusw(
678 ; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X:%.*]] to i64
679 ; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y:%.*]] to i64
680 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X_EXT]], [[Y_EXT]]
681 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]])
682 ; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[X_EXT]]
683 ; CHECK-NEXT: [[GEP_X1:%.*]] = getelementptr i8, ptr [[GEP_X]], i64 1
684 ; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nusw i8, ptr [[P]], i64 [[Y_EXT]]
685 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt ptr [[GEP_X1]], [[GEP_Y]]
686 ; CHECK-NEXT: ret i1 [[CMP2]]
688 %x.ext = zext i32 %x to i64
689 %y.ext = zext i32 %y to i64
690 %cmp1 = icmp ugt i64 %x.ext, %y.ext
691 call void @llvm.assume(i1 %cmp1)
692 %gep.x = getelementptr nusw i8, ptr %p, i64 %x.ext
693 %gep.x1 = getelementptr i8, ptr %gep.x, i64 1
694 %gep.y = getelementptr nusw i8, ptr %p, i64 %y.ext
695 %cmp2 = icmp ugt ptr %gep.x1, %gep.y
699 define i1 @test_nuw(ptr %p, i64 %x, i64 %y) {
700 ; CHECK-LABEL: @test_nuw(
701 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]
702 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]])
703 ; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[X]]
704 ; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]]
705 ; CHECK-NEXT: ret i1 true
707 %cmp1 = icmp ugt i64 %x, %y
708 call void @llvm.assume(i1 %cmp1)
709 %gep.x = getelementptr nuw i8, ptr %p, i64 %x
710 %gep.y = getelementptr nuw i8, ptr %p, i64 %y
711 %cmp2 = icmp ugt ptr %gep.x, %gep.y
715 define i1 @test_nuw_nested(ptr %p, i64 %x, i64 %y) {
716 ; CHECK-LABEL: @test_nuw_nested(
717 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]
718 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]])
719 ; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[X]]
720 ; CHECK-NEXT: [[GEP_X1:%.*]] = getelementptr nuw i8, ptr [[GEP_X]], i64 1
721 ; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]]
722 ; CHECK-NEXT: ret i1 true
724 %cmp1 = icmp ugt i64 %x, %y
725 call void @llvm.assume(i1 %cmp1)
726 %gep.x = getelementptr nuw i8, ptr %p, i64 %x
727 %gep.x1 = getelementptr nuw i8, ptr %gep.x, i64 1
728 %gep.y = getelementptr nuw i8, ptr %p, i64 %y
729 %cmp2 = icmp ugt ptr %gep.x1, %gep.y
733 define i1 @test_nuw_nested_missing_nuw(ptr %p, i64 %x, i64 %y) {
734 ; CHECK-LABEL: @test_nuw_nested_missing_nuw(
735 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]
736 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]])
737 ; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[X]]
738 ; CHECK-NEXT: [[GEP_X1:%.*]] = getelementptr nuw i8, ptr [[GEP_X]], i64 1
739 ; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]]
740 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt ptr [[GEP_X1]], [[GEP_Y]]
741 ; CHECK-NEXT: ret i1 [[CMP2]]
743 %cmp1 = icmp ugt i64 %x, %y
744 call void @llvm.assume(i1 %cmp1)
745 %gep.x = getelementptr i8, ptr %p, i64 %x
746 %gep.x1 = getelementptr nuw i8, ptr %gep.x, i64 1
747 %gep.y = getelementptr nuw i8, ptr %p, i64 %y
748 %cmp2 = icmp ugt ptr %gep.x1, %gep.y
752 define i1 @test_nuw_incorrect_precondition(ptr %p, i64 %x, i64 %y) {
753 ; CHECK-LABEL: @test_nuw_incorrect_precondition(
754 ; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i64 [[X:%.*]], [[Y:%.*]]
755 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]])
756 ; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[X]]
757 ; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]]
758 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt ptr [[GEP_X]], [[GEP_Y]]
759 ; CHECK-NEXT: ret i1 [[CMP2]]
761 %cmp1 = icmp uge i64 %x, %y
762 call void @llvm.assume(i1 %cmp1)
763 %gep.x = getelementptr nuw i8, ptr %p, i64 %x
764 %gep.y = getelementptr nuw i8, ptr %p, i64 %y
765 %cmp2 = icmp ugt ptr %gep.x, %gep.y