1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 define void @test.not.uge.ult(i8 %start, i8 %low, i8 %high) {
5 ; CHECK-LABEL: @test.not.uge.ult(
7 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nuw i8 [[START:%.*]], 3
8 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_PTR_I]], [[HIGH:%.*]]
9 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
11 ; CHECK-NEXT: ret void
13 ; CHECK-NEXT: call void @use(i1 true)
14 ; CHECK-NEXT: [[START_1:%.*]] = add nuw i8 [[START]], 1
15 ; CHECK-NEXT: call void @use(i1 true)
16 ; CHECK-NEXT: [[START_2:%.*]] = add nuw i8 [[START]], 2
17 ; CHECK-NEXT: call void @use(i1 true)
18 ; CHECK-NEXT: [[START_3:%.*]] = add nuw i8 [[START]], 3
19 ; CHECK-NEXT: call void @use(i1 true)
20 ; CHECK-NEXT: [[START_4:%.*]] = add nuw i8 [[START]], 4
21 ; CHECK-NEXT: [[C_4:%.*]] = icmp ult i8 [[START_4]], [[HIGH]]
22 ; CHECK-NEXT: call void @use(i1 [[C_4]])
23 ; CHECK-NEXT: ret void
26 %add.ptr.i = add nuw i8 %start, 3
27 %c.1 = icmp uge i8 %add.ptr.i, %high
28 br i1 %c.1, label %if.then, label %if.end
30 if.then: ; preds = %entry
33 if.end: ; preds = %entry
34 %t.0 = icmp ult i8 %start, %high
35 call void @use(i1 %t.0)
36 %start.1 = add nuw i8 %start, 1
37 %t.1 = icmp ult i8 %start.1, %high
38 call void @use(i1 %t.1)
39 %start.2 = add nuw i8 %start, 2
40 %t.2 = icmp ult i8 %start.2, %high
41 call void @use(i1 %t.2)
42 %start.3 = add nuw i8 %start, 3
43 %t.3 = icmp ult i8 %start.3, %high
44 call void @use(i1 %t.3)
45 %start.4 = add nuw i8 %start, 4
46 %c.4 = icmp ult i8 %start.4, %high
47 call void @use(i1 %c.4)
51 define void @test.not.uge.ule(i8 %start, i8 %low, i8 %high) {
52 ; CHECK-LABEL: @test.not.uge.ule(
54 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nuw i8 [[START:%.*]], 3
55 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_PTR_I]], [[HIGH:%.*]]
56 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
58 ; CHECK-NEXT: ret void
60 ; CHECK-NEXT: call void @use(i1 true)
61 ; CHECK-NEXT: [[START_1:%.*]] = add nuw i8 [[START]], 1
62 ; CHECK-NEXT: call void @use(i1 true)
63 ; CHECK-NEXT: [[START_2:%.*]] = add nuw i8 [[START]], 2
64 ; CHECK-NEXT: call void @use(i1 true)
65 ; CHECK-NEXT: [[START_3:%.*]] = add nuw i8 [[START]], 3
66 ; CHECK-NEXT: call void @use(i1 true)
67 ; CHECK-NEXT: [[START_4:%.*]] = add nuw i8 [[START]], 4
68 ; CHECK-NEXT: call void @use(i1 true)
69 ; CHECK-NEXT: [[START_5:%.*]] = add nuw i8 [[START]], 5
70 ; CHECK-NEXT: [[C_5:%.*]] = icmp ule i8 [[START_5]], [[HIGH]]
71 ; CHECK-NEXT: call void @use(i1 [[C_5]])
72 ; CHECK-NEXT: ret void
75 %add.ptr.i = add nuw i8 %start, 3
76 %c.1 = icmp uge i8 %add.ptr.i, %high
77 br i1 %c.1, label %if.then, label %if.end
79 if.then: ; preds = %entry
82 if.end: ; preds = %entry
83 %t.0 = icmp ule i8 %start, %high
84 call void @use(i1 %t.0)
85 %start.1 = add nuw i8 %start, 1
86 %t.1 = icmp ule i8 %start.1, %high
87 call void @use(i1 %t.1)
88 %start.2 = add nuw i8 %start, 2
89 %t.2 = icmp ule i8 %start.2, %high
90 call void @use(i1 %t.2)
91 %start.3 = add nuw i8 %start, 3
92 %t.3 = icmp ule i8 %start.3, %high
93 call void @use(i1 %t.3)
94 %start.4 = add nuw i8 %start, 4
95 %t.4 = icmp ule i8 %start.4, %high
96 call void @use(i1 %t.4)
98 %start.5 = add nuw i8 %start, 5
99 %c.5 = icmp ule i8 %start.5, %high
100 call void @use(i1 %c.5)
105 define void @test.not.uge.ugt(i8 %start, i8 %low, i8 %high) {
106 ; CHECK-LABEL: @test.not.uge.ugt(
108 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nuw i8 [[START:%.*]], 3
109 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_PTR_I]], [[HIGH:%.*]]
110 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
112 ; CHECK-NEXT: ret void
114 ; CHECK-NEXT: call void @use(i1 false)
115 ; CHECK-NEXT: [[START_1:%.*]] = add nuw i8 [[START]], 1
116 ; CHECK-NEXT: call void @use(i1 false)
117 ; CHECK-NEXT: [[START_2:%.*]] = add nuw i8 [[START]], 2
118 ; CHECK-NEXT: call void @use(i1 false)
119 ; CHECK-NEXT: [[START_3:%.*]] = add nuw i8 [[START]], 3
120 ; CHECK-NEXT: call void @use(i1 false)
121 ; CHECK-NEXT: [[START_4:%.*]] = add nuw i8 [[START]], 4
122 ; CHECK-NEXT: call void @use(i1 false)
123 ; CHECK-NEXT: [[START_5:%.*]] = add nuw i8 [[START]], 5
124 ; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[START_5]], [[HIGH]]
125 ; CHECK-NEXT: call void @use(i1 [[C_5]])
126 ; CHECK-NEXT: ret void
129 %add.ptr.i = add nuw i8 %start, 3
130 %c.1 = icmp uge i8 %add.ptr.i, %high
131 br i1 %c.1, label %if.then, label %if.end
133 if.then: ; preds = %entry
136 if.end: ; preds = %entry
137 %f.0 = icmp ugt i8 %start, %high
138 call void @use(i1 %f.0)
140 %start.1 = add nuw i8 %start, 1
141 %f.1 = icmp ugt i8 %start.1, %high
142 call void @use(i1 %f.1)
144 %start.2 = add nuw i8 %start, 2
145 %f.2 = icmp ugt i8 %start.2, %high
146 call void @use(i1 %f.2)
148 %start.3 = add nuw i8 %start, 3
149 %f.3 = icmp ugt i8 %start.3, %high
150 call void @use(i1 %f.3)
152 %start.4 = add nuw i8 %start, 4
153 %f.4 = icmp ugt i8 %start.4, %high
154 call void @use(i1 %f.4)
156 %start.5 = add nuw i8 %start, 5
157 %c.5 = icmp ugt i8 %start.5, %high
158 call void @use(i1 %c.5)
163 define void @test.not.uge.uge(i8 %start, i8 %low, i8 %high) {
164 ; CHECK-LABEL: @test.not.uge.uge(
166 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nuw i8 [[START:%.*]], 3
167 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_PTR_I]], [[HIGH:%.*]]
168 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
170 ; CHECK-NEXT: ret void
172 ; CHECK-NEXT: call void @use(i1 false)
173 ; CHECK-NEXT: [[START_1:%.*]] = add nuw i8 [[START]], 1
174 ; CHECK-NEXT: call void @use(i1 false)
175 ; CHECK-NEXT: [[START_2:%.*]] = add nuw i8 [[START]], 2
176 ; CHECK-NEXT: call void @use(i1 false)
177 ; CHECK-NEXT: [[START_3:%.*]] = add nuw i8 [[START]], 3
178 ; CHECK-NEXT: call void @use(i1 false)
179 ; CHECK-NEXT: [[START_4:%.*]] = add nuw i8 [[START]], 4
180 ; CHECK-NEXT: [[C_4:%.*]] = icmp uge i8 [[START_4]], [[HIGH]]
181 ; CHECK-NEXT: call void @use(i1 [[C_4]])
182 ; CHECK-NEXT: [[START_5:%.*]] = add nuw i8 [[START]], 5
183 ; CHECK-NEXT: [[C_5:%.*]] = icmp uge i8 [[START_5]], [[HIGH]]
184 ; CHECK-NEXT: call void @use(i1 [[C_5]])
185 ; CHECK-NEXT: ret void
188 %add.ptr.i = add nuw i8 %start, 3
189 %c.1 = icmp uge i8 %add.ptr.i, %high
190 br i1 %c.1, label %if.then, label %if.end
192 if.then: ; preds = %entry
195 if.end: ; preds = %entry
196 %f.0 = icmp ugt i8 %start, %high
197 call void @use(i1 %f.0)
199 %start.1 = add nuw i8 %start, 1
200 %f.1 = icmp uge i8 %start.1, %high
201 call void @use(i1 %f.1)
203 %start.2 = add nuw i8 %start, 2
204 %f.2 = icmp uge i8 %start.2, %high
205 call void @use(i1 %f.2)
207 %start.3 = add nuw i8 %start, 3
208 %f.3 = icmp uge i8 %start.3, %high
209 call void @use(i1 %f.3)
211 %start.4 = add nuw i8 %start, 4
212 %c.4 = icmp uge i8 %start.4, %high
213 call void @use(i1 %c.4)
215 %start.5 = add nuw i8 %start, 5
216 %c.5 = icmp uge i8 %start.5, %high
217 call void @use(i1 %c.5)
222 define void @test.decompose.nonconst(i8 %a, i8 %b, i8 %c, i8 %d) {
223 ; CHECK-LABEL: @test.decompose.nonconst(
225 ; CHECK-NEXT: [[C_0:%.*]] = icmp uge i8 [[A:%.*]], [[C:%.*]]
226 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[C]]
227 ; CHECK-NEXT: [[AND_0:%.*]] = and i1 [[C_0]], [[C_1]]
228 ; CHECK-NEXT: br i1 [[AND_0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
230 ; CHECK-NEXT: [[AND_1:%.*]] = and i1 true, true
231 ; CHECK-NEXT: br i1 [[AND_1]], label [[IF_THEN_2:%.*]], label [[IF_END]]
233 ; CHECK-NEXT: [[ADD_0:%.*]] = add nuw i8 [[A]], [[B]]
234 ; CHECK-NEXT: call void @use(i1 true)
235 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], [[A]]
236 ; CHECK-NEXT: call void @use(i1 true)
237 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[A]], [[D:%.*]]
238 ; CHECK-NEXT: [[C_4:%.*]] = icmp uge i8 [[ADD_2]], [[C]]
239 ; CHECK-NEXT: call void @use(i1 [[C_4]])
240 ; CHECK-NEXT: ret void
242 ; CHECK-NEXT: ret void
245 %c.0 = icmp uge i8 %a, %c
246 %c.1 = icmp uge i8 %b, %c
247 %and.0 = and i1 %c.0, %c.1
248 br i1 %and.0, label %if.then, label %if.end
250 if.then: ; preds = %entry
251 %c.2 = icmp uge i8 %a, 0
252 %c.3 = icmp uge i8 %b, 0
253 %and.1 = and i1 %c.2, %c.3
254 br i1 %and.1, label %if.then.2, label %if.end
257 %add.0 = add nuw i8 %a, %b
258 %t.0 = icmp uge i8 %add.0, %c
259 call void @use(i1 %t.0)
260 %add.1 = add nuw i8 %a, %a
261 %t.1 = icmp uge i8 %add.0, %c
262 call void @use(i1 %t.1)
263 %add.2 = add nuw i8 %a, %d
264 %c.4 = icmp uge i8 %add.2, %c
265 call void @use(i1 %c.4)
268 if.end: ; preds = %entry
272 define void @test.decompose.nonconst.no.null.check(i8 %a, i8 %b, i8 %c, i8 %d) {
273 ; CHECK-LABEL: @test.decompose.nonconst.no.null.check(
275 ; CHECK-NEXT: [[C_0:%.*]] = icmp uge i8 [[A:%.*]], [[C:%.*]]
276 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[C]]
277 ; CHECK-NEXT: [[AND_0:%.*]] = and i1 [[C_0]], [[C_1]]
278 ; CHECK-NEXT: br i1 [[AND_0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
280 ; CHECK-NEXT: [[ADD_0:%.*]] = add nuw i8 [[A]], [[B]]
281 ; CHECK-NEXT: [[T_0:%.*]] = icmp uge i8 [[ADD_0]], [[C]]
282 ; CHECK-NEXT: call void @use(i1 [[T_0]])
283 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], [[A]]
284 ; CHECK-NEXT: [[T_1:%.*]] = icmp uge i8 [[ADD_0]], [[C]]
285 ; CHECK-NEXT: call void @use(i1 [[T_1]])
286 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[A]], [[D:%.*]]
287 ; CHECK-NEXT: [[C_4:%.*]] = icmp uge i8 [[ADD_2]], [[C]]
288 ; CHECK-NEXT: call void @use(i1 [[C_4]])
289 ; CHECK-NEXT: ret void
291 ; CHECK-NEXT: ret void
294 %c.0 = icmp uge i8 %a, %c
295 %c.1 = icmp uge i8 %b, %c
296 %and.0 = and i1 %c.0, %c.1
297 br i1 %and.0, label %if.then, label %if.end
299 if.then: ; preds = %entry
300 %add.0 = add nuw i8 %a, %b
301 %t.0 = icmp uge i8 %add.0, %c
302 call void @use(i1 %t.0)
303 %add.1 = add nuw i8 %a, %a
304 %t.1 = icmp uge i8 %add.0, %c
305 call void @use(i1 %t.1)
306 %add.2 = add nuw i8 %a, %d
307 %c.4 = icmp uge i8 %add.2, %c
308 call void @use(i1 %c.4)
311 if.end: ; preds = %entry
316 define i1 @test_n_must_ule_1_due_to_nuw(i8 %n, i8 %i) {
317 ; CHECK-LABEL: @test_n_must_ule_1_due_to_nuw(
319 ; CHECK-NEXT: [[SUB_N_1:%.*]] = add nuw i8 [[N:%.*]], -1
320 ; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[I:%.*]], [[SUB_N_1]]
321 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]]
322 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
324 ; CHECK-NEXT: ret i1 true
326 ; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 1
327 ; CHECK-NEXT: ret i1 [[F]]
330 %sub.n.1 = add nuw i8 %n, -1
331 %add = add nuw i8 %i, %sub.n.1
332 %c.1 = icmp uge i8 %i, %add
333 br i1 %c.1, label %if.then, label %if.end
335 if.then: ; preds = %entry
336 %t = icmp ule i8 %n, 1
339 if.end: ; preds = %entry
340 %f = icmp ule i8 %n, 1
345 define i1 @test_n_unknown_missing_nuw(i8 %n, i8 %i) {
346 ; CHECK-LABEL: @test_n_unknown_missing_nuw(
348 ; CHECK-NEXT: [[SUB_N_1:%.*]] = add i8 [[N:%.*]], -1
349 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[I:%.*]], [[SUB_N_1]]
350 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]]
351 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
353 ; CHECK-NEXT: [[T:%.*]] = icmp ule i8 [[N]], 1
354 ; CHECK-NEXT: ret i1 [[T]]
356 ; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 1
357 ; CHECK-NEXT: ret i1 [[F]]
360 %sub.n.1 = add i8 %n, -1
361 %add = add i8 %i, %sub.n.1
362 %c.1 = icmp uge i8 %i, %add
363 br i1 %c.1, label %if.then, label %if.end
365 if.then: ; preds = %entry
366 %t = icmp ule i8 %n, 1
369 if.end: ; preds = %entry
370 %f = icmp ule i8 %n, 1
374 define i1 @test_n_must_ule_2_due_to_nuw(i8 %n, i8 %i) {
375 ; CHECK-LABEL: @test_n_must_ule_2_due_to_nuw(
377 ; CHECK-NEXT: [[SUB_N_1:%.*]] = add nuw i8 [[N:%.*]], -2
378 ; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[I:%.*]], [[SUB_N_1]]
379 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]]
380 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
382 ; CHECK-NEXT: ret i1 true
384 ; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 2
385 ; CHECK-NEXT: ret i1 [[F]]
388 %sub.n.1 = add nuw i8 %n, -2
389 %add = add nuw i8 %i, %sub.n.1
390 %c.1 = icmp uge i8 %i, %add
391 br i1 %c.1, label %if.then, label %if.end
393 if.then: ; preds = %entry
394 %t = icmp ule i8 %n, 2
397 if.end: ; preds = %entry
398 %f = icmp ule i8 %n, 2
403 define i1 @test_n_unknown_missing_nuw2(i8 %n, i8 %i) {
404 ; CHECK-LABEL: @test_n_unknown_missing_nuw2(
406 ; CHECK-NEXT: [[SUB_N_1:%.*]] = add i8 [[N:%.*]], -2
407 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[I:%.*]], [[SUB_N_1]]
408 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]]
409 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
411 ; CHECK-NEXT: [[T:%.*]] = icmp ule i8 [[N]], 1
412 ; CHECK-NEXT: ret i1 [[T]]
414 ; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 1
415 ; CHECK-NEXT: ret i1 [[F]]
418 %sub.n.1 = add i8 %n, -2
419 %add = add i8 %i, %sub.n.1
420 %c.1 = icmp uge i8 %i, %add
421 br i1 %c.1, label %if.then, label %if.end
423 if.then: ; preds = %entry
424 %t = icmp ule i8 %n, 1
427 if.end: ; preds = %entry
428 %f = icmp ule i8 %n, 1
432 declare void @use(i1)
434 define i1 @add_nuw_neg_pr54224_i16(i16 %a) {
435 ; CHECK-LABEL: @add_nuw_neg_pr54224_i16(
437 ; CHECK-NEXT: [[NEG2:%.*]] = add nuw i16 [[A:%.*]], -305
438 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i16 0, [[NEG2]]
439 ; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]
441 ; CHECK-NEXT: ret i1 false
443 ; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i16 [[A]], 0
444 ; CHECK-NEXT: ret i1 [[C_3]]
447 %neg2 = add nuw i16 %a, -305
448 %c.1 = icmp ugt i16 0, %neg2
449 br i1 %c.1, label %exit.1, label %exit.2
452 %c.2 = icmp ugt i16 %a, 0
456 %c.3 = icmp ugt i16 %a, 0
460 define i1 @add_nuw_neg_pr54224_i64(i64 %a) {
461 ; CHECK-LABEL: @add_nuw_neg_pr54224_i64(
463 ; CHECK-NEXT: [[NEG2:%.*]] = add nuw i64 [[A:%.*]], -305
464 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i64 0, [[NEG2]]
465 ; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]
467 ; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i64 [[A]], 0
468 ; CHECK-NEXT: ret i1 [[C_2]]
470 ; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i64 [[A]], 0
471 ; CHECK-NEXT: ret i1 [[C_3]]
474 %neg2 = add nuw i64 %a, -305
475 %c.1 = icmp ugt i64 0, %neg2
476 br i1 %c.1, label %exit.1, label %exit.2
479 %c.2 = icmp ugt i64 %a, 0
483 %c.3 = icmp ugt i64 %a, 0
487 define i1 @add_nuw_neg2_i8(i8 %a) {
488 ; CHECK-LABEL: @add_nuw_neg2_i8(
490 ; CHECK-NEXT: [[NEG2:%.*]] = add nuw i8 [[A:%.*]], -4
491 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[NEG2]], -2
492 ; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]
494 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i8 [[A]], 1
495 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[C_2]]
496 ; CHECK-NEXT: ret i1 [[RES_1]]
498 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i8 [[A]], 3
499 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[C_3]], false
500 ; CHECK-NEXT: ret i1 [[RES_2]]
503 %neg2 = add nuw i8 %a, -4
504 %c.1 = icmp ult i8 %neg2, -2
505 br i1 %c.1, label %exit.1, label %exit.2
508 %t.1 = icmp ult i8 %a, 2
509 %c.2 = icmp ult i8 %a, 1
510 %res.1 = xor i1 %t.1, %c.2
514 %c.3 = icmp ult i8 %a, 3
515 %f.1 = icmp ult i8 %a, 2
516 %res.2 = xor i1 %c.3, %f.1
520 define i1 @add_nuw_neg2_i64(i64 %a) {
521 ; CHECK-LABEL: @add_nuw_neg2_i64(
523 ; CHECK-NEXT: [[NEG2:%.*]] = add nuw i64 [[A:%.*]], -4
524 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i64 [[NEG2]], -2
525 ; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]
527 ; CHECK-NEXT: [[T_1:%.*]] = icmp ult i64 [[A]], 2
528 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i64 [[A]], 1
529 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[T_1]], [[C_2]]
530 ; CHECK-NEXT: ret i1 [[RES_1]]
532 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i64 [[A]], 3
533 ; CHECK-NEXT: [[F_1:%.*]] = icmp ult i64 [[A]], 2
534 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[C_3]], [[F_1]]
535 ; CHECK-NEXT: ret i1 [[RES_2]]
538 %neg2 = add nuw i64 %a, -4
539 %c.1 = icmp ult i64 %neg2, -2
540 br i1 %c.1, label %exit.1, label %exit.2
543 %t.1 = icmp ult i64 %a, 2
544 %c.2 = icmp ult i64 %a, 1
545 %res.1 = xor i1 %t.1, %c.2
549 %c.3 = icmp ult i64 %a, 3
550 %f.1 = icmp ult i64 %a, 2
551 %res.2 = xor i1 %c.3, %f.1
555 define i1 @test_chained_adds_nuw_1(i8 %a, i8 %b) {
556 ; CHECK-LABEL: @test_chained_adds_nuw_1(
558 ; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
559 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]])
560 ; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
561 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]])
562 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], [[B]]
563 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], 2
564 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_2]], 14
565 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[C_1]]
566 ; CHECK-NEXT: ret i1 [[RES_1]]
569 %c.a = icmp uge i8 %a, 5
570 call void @llvm.assume(i1 %c.a)
571 %c.b = icmp uge i8 %b, 6
572 call void @llvm.assume(i1 %c.b)
573 %add.1 = add nuw i8 %a, %b
574 %add.2 = add nuw i8 %add.1, 2
575 %t.1 = icmp uge i8 %add.2, 13
576 %c.1 = icmp uge i8 %add.2, 14
577 %res.1 = xor i1 %t.1, %c.1
581 define i1 @test_chained_adds_nuw_2(i8 %a, i8 %b) {
582 ; CHECK-LABEL: @test_chained_adds_nuw_2(
584 ; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
585 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]])
586 ; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
587 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]])
588 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], [[B]]
589 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], 2
590 ; CHECK-NEXT: [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]]
591 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 19
592 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[C_1]]
593 ; CHECK-NEXT: ret i1 [[RES_1]]
596 %c.a = icmp uge i8 %a, 5
597 call void @llvm.assume(i1 %c.a)
598 %c.b = icmp uge i8 %b, 6
599 call void @llvm.assume(i1 %c.b)
600 %add.1 = add nuw i8 %a, %b
601 %add.2 = add nuw i8 %add.1, 2
602 %add.3 = add nuw i8 %add.2, %a
603 %t.1 = icmp uge i8 %add.3, 18
604 %c.1 = icmp uge i8 %add.3, 19
605 %res.1 = xor i1 %t.1, %c.1
609 define i1 @test_chained_adds_nuw_3(i8 %a, i8 %b) {
610 ; CHECK-LABEL: @test_chained_adds_nuw_3(
612 ; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
613 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]])
614 ; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
615 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]])
616 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], 2
617 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]]
618 ; CHECK-NEXT: [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]]
619 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 19
620 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[C_1]]
621 ; CHECK-NEXT: ret i1 [[RES_1]]
624 %c.a = icmp uge i8 %a, 5
625 call void @llvm.assume(i1 %c.a)
626 %c.b = icmp uge i8 %b, 6
627 call void @llvm.assume(i1 %c.b)
628 %add.1 = add nuw i8 %a, 2
629 %add.2 = add nuw i8 %add.1, %b
630 %add.3 = add nuw i8 %add.2, %a
631 %t.1 = icmp uge i8 %add.3, 18
632 %c.1 = icmp uge i8 %add.3, 19
633 %res.1 = xor i1 %t.1, %c.1
637 define i1 @test_chained_adds_nuw_4(i8 %a, i8 %b) {
638 ; CHECK-LABEL: @test_chained_adds_nuw_4(
640 ; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
641 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]])
642 ; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
643 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]])
644 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], 2
645 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]]
646 ; CHECK-NEXT: [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], 10
647 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 24
648 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[C_1]]
649 ; CHECK-NEXT: ret i1 [[RES_1]]
652 %c.a = icmp uge i8 %a, 5
653 call void @llvm.assume(i1 %c.a)
654 %c.b = icmp uge i8 %b, 6
655 call void @llvm.assume(i1 %c.b)
656 %add.1 = add nuw i8 %a, 2
657 %add.2 = add nuw i8 %add.1, %b
658 %add.3 = add nuw i8 %add.2, 10
659 %t.1 = icmp uge i8 %add.3, 23
660 %c.1 = icmp uge i8 %add.3, 24
661 %res.1 = xor i1 %t.1, %c.1
665 define i1 @test_chained_adds_missing_nuw_1(i8 %a, i8 %b) {
666 ; CHECK-LABEL: @test_chained_adds_missing_nuw_1(
668 ; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
669 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]])
670 ; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
671 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]])
672 ; CHECK-NEXT: [[ADD_1:%.*]] = add i8 [[A]], 2
673 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]]
674 ; CHECK-NEXT: [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]]
675 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 18
676 ; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8 [[ADD_3]], 19
677 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]
678 ; CHECK-NEXT: ret i1 [[RES_1]]
681 %c.a = icmp uge i8 %a, 5
682 call void @llvm.assume(i1 %c.a)
683 %c.b = icmp uge i8 %b, 6
684 call void @llvm.assume(i1 %c.b)
685 %add.1 = add i8 %a, 2
686 %add.2 = add nuw i8 %add.1, %b
687 %add.3 = add nuw i8 %add.2, %a
688 %c.1 = icmp uge i8 %add.3, 18
689 %c.2 = icmp uge i8 %add.3, 19
690 %res.1 = xor i1 %c.1, %c.2
694 define i1 @test_chained_adds_missing_nuw_2(i8 %a, i8 %b) {
695 ; CHECK-LABEL: @test_chained_adds_missing_nuw_2(
697 ; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
698 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]])
699 ; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
700 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]])
701 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], 2
702 ; CHECK-NEXT: [[ADD_2:%.*]] = add i8 [[ADD_1]], [[B]]
703 ; CHECK-NEXT: [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]]
704 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 18
705 ; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8 [[ADD_3]], 19
706 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]
707 ; CHECK-NEXT: ret i1 [[RES_1]]
710 %c.a = icmp uge i8 %a, 5
711 call void @llvm.assume(i1 %c.a)
712 %c.b = icmp uge i8 %b, 6
713 call void @llvm.assume(i1 %c.b)
714 %add.1 = add nuw i8 %a, 2
715 %add.2 = add i8 %add.1, %b
716 %add.3 = add nuw i8 %add.2, %a
717 %c.1 = icmp uge i8 %add.3, 18
718 %c.2 = icmp uge i8 %add.3, 19
719 %res.1 = xor i1 %c.1, %c.2
723 define i1 @test_chained_adds_missing_nuw_3(i8 %a, i8 %b) {
724 ; CHECK-LABEL: @test_chained_adds_missing_nuw_3(
726 ; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
727 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]])
728 ; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
729 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]])
730 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], 2
731 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]]
732 ; CHECK-NEXT: [[ADD_3:%.*]] = add i8 [[ADD_2]], [[A]]
733 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 18
734 ; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8 [[ADD_3]], 19
735 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]
736 ; CHECK-NEXT: ret i1 [[RES_1]]
739 %c.a = icmp uge i8 %a, 5
740 call void @llvm.assume(i1 %c.a)
741 %c.b = icmp uge i8 %b, 6
742 call void @llvm.assume(i1 %c.b)
743 %add.1 = add nuw i8 %a, 2
744 %add.2 = add nuw i8 %add.1, %b
745 %add.3 = add i8 %add.2, %a
746 %c.1 = icmp uge i8 %add.3, 18
747 %c.2 = icmp uge i8 %add.3, 19
748 %res.1 = xor i1 %c.1, %c.2
752 declare void @llvm.assume(i1)