Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / add-nuw.ll
blobbe3b66af10e0868ab8467435f7c32f6b2ede6231
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(
6 ; CHECK-NEXT:  entry:
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:%.*]]
10 ; CHECK:       if.then:
11 ; CHECK-NEXT:    ret void
12 ; CHECK:       if.end:
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
25 entry:
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
31   ret void
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)
48   ret void
51 define void @test.not.uge.ule(i8 %start, i8 %low, i8 %high) {
52 ; CHECK-LABEL: @test.not.uge.ule(
53 ; CHECK-NEXT:  entry:
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:%.*]]
57 ; CHECK:       if.then:
58 ; CHECK-NEXT:    ret void
59 ; CHECK:       if.end:
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
74 entry:
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
80   ret void
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)
102   ret void
105 define void @test.not.uge.ugt(i8 %start, i8 %low, i8 %high) {
106 ; CHECK-LABEL: @test.not.uge.ugt(
107 ; CHECK-NEXT:  entry:
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:%.*]]
111 ; CHECK:       if.then:
112 ; CHECK-NEXT:    ret void
113 ; CHECK:       if.end:
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
128 entry:
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
134   ret void
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)
160   ret void
163 define void @test.not.uge.uge(i8 %start, i8 %low, i8 %high) {
164 ; CHECK-LABEL: @test.not.uge.uge(
165 ; CHECK-NEXT:  entry:
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:%.*]]
169 ; CHECK:       if.then:
170 ; CHECK-NEXT:    ret void
171 ; CHECK:       if.end:
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
187 entry:
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
193   ret void
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)
219   ret void
222 define void @test.decompose.nonconst(i8 %a, i8 %b, i8 %c, i8 %d) {
223 ; CHECK-LABEL: @test.decompose.nonconst(
224 ; CHECK-NEXT:  entry:
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:%.*]]
229 ; CHECK:       if.then:
230 ; CHECK-NEXT:    [[AND_1:%.*]] = and i1 true, true
231 ; CHECK-NEXT:    br i1 [[AND_1]], label [[IF_THEN_2:%.*]], label [[IF_END]]
232 ; CHECK:       if.then.2:
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
241 ; CHECK:       if.end:
242 ; CHECK-NEXT:    ret void
244 entry:
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
256 if.then.2:
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)
266   ret void
268 if.end:                                           ; preds = %entry
269   ret void
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(
274 ; CHECK-NEXT:  entry:
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:%.*]]
279 ; CHECK:       if.then:
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
290 ; CHECK:       if.end:
291 ; CHECK-NEXT:    ret void
293 entry:
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)
309   ret void
311 if.end:                                           ; preds = %entry
312   ret void
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(
318 ; CHECK-NEXT:  entry:
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:%.*]]
323 ; CHECK:       if.then:
324 ; CHECK-NEXT:    ret i1 true
325 ; CHECK:       if.end:
326 ; CHECK-NEXT:    [[F:%.*]] = icmp ule i8 [[N]], 1
327 ; CHECK-NEXT:    ret i1 [[F]]
329 entry:
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
337   ret i1 %t
339 if.end:                                           ; preds = %entry
340   %f = icmp ule i8 %n, 1
341   ret i1 %f
345 define i1 @test_n_unknown_missing_nuw(i8 %n, i8 %i) {
346 ; CHECK-LABEL: @test_n_unknown_missing_nuw(
347 ; CHECK-NEXT:  entry:
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:%.*]]
352 ; CHECK:       if.then:
353 ; CHECK-NEXT:    [[T:%.*]] = icmp ule i8 [[N]], 1
354 ; CHECK-NEXT:    ret i1 [[T]]
355 ; CHECK:       if.end:
356 ; CHECK-NEXT:    [[F:%.*]] = icmp ule i8 [[N]], 1
357 ; CHECK-NEXT:    ret i1 [[F]]
359 entry:
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
367   ret i1 %t
369 if.end:                                           ; preds = %entry
370   %f = icmp ule i8 %n, 1
371   ret i1 %f
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(
376 ; CHECK-NEXT:  entry:
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:%.*]]
381 ; CHECK:       if.then:
382 ; CHECK-NEXT:    ret i1 true
383 ; CHECK:       if.end:
384 ; CHECK-NEXT:    [[F:%.*]] = icmp ule i8 [[N]], 2
385 ; CHECK-NEXT:    ret i1 [[F]]
387 entry:
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
395   ret i1 %t
397 if.end:                                           ; preds = %entry
398   %f = icmp ule i8 %n, 2
399   ret i1 %f
403 define i1 @test_n_unknown_missing_nuw2(i8 %n, i8 %i) {
404 ; CHECK-LABEL: @test_n_unknown_missing_nuw2(
405 ; CHECK-NEXT:  entry:
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:%.*]]
410 ; CHECK:       if.then:
411 ; CHECK-NEXT:    [[T:%.*]] = icmp ule i8 [[N]], 1
412 ; CHECK-NEXT:    ret i1 [[T]]
413 ; CHECK:       if.end:
414 ; CHECK-NEXT:    [[F:%.*]] = icmp ule i8 [[N]], 1
415 ; CHECK-NEXT:    ret i1 [[F]]
417 entry:
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
425   ret i1 %t
427 if.end:                                           ; preds = %entry
428   %f = icmp ule i8 %n, 1
429   ret i1 %f
432 declare void @use(i1)
434 define i1 @add_nuw_neg_pr54224_i16(i16 %a) {
435 ; CHECK-LABEL: @add_nuw_neg_pr54224_i16(
436 ; CHECK-NEXT:  entry:
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:%.*]]
440 ; CHECK:       exit.1:
441 ; CHECK-NEXT:    ret i1 false
442 ; CHECK:       exit.2:
443 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i16 [[A]], 0
444 ; CHECK-NEXT:    ret i1 [[C_3]]
446 entry:
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
451 exit.1:
452   %c.2 = icmp ugt i16 %a, 0
453   ret i1 %c.2
455 exit.2:
456   %c.3 = icmp ugt i16 %a, 0
457   ret i1 %c.3
460 define i1 @add_nuw_neg_pr54224_i64(i64 %a) {
461 ; CHECK-LABEL: @add_nuw_neg_pr54224_i64(
462 ; CHECK-NEXT:  entry:
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:%.*]]
466 ; CHECK:       exit.1:
467 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i64 [[A]], 0
468 ; CHECK-NEXT:    ret i1 [[C_2]]
469 ; CHECK:       exit.2:
470 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i64 [[A]], 0
471 ; CHECK-NEXT:    ret i1 [[C_3]]
473 entry:
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
478 exit.1:
479   %c.2 = icmp ugt i64 %a, 0
480   ret i1 %c.2
482 exit.2:
483   %c.3 = icmp ugt i64 %a, 0
484   ret i1 %c.3
487 define i1 @add_nuw_neg2_i8(i8 %a) {
488 ; CHECK-LABEL: @add_nuw_neg2_i8(
489 ; CHECK-NEXT:  entry:
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:%.*]]
493 ; CHECK:       exit.1:
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]]
497 ; CHECK:       exit.2:
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]]
502 entry:
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
507 exit.1:
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
511   ret i1 %res.1
513 exit.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
517   ret i1 %res.2
520 define i1 @add_nuw_neg2_i64(i64 %a) {
521 ; CHECK-LABEL: @add_nuw_neg2_i64(
522 ; CHECK-NEXT:  entry:
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:%.*]]
526 ; CHECK:       exit.1:
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]]
531 ; CHECK:       exit.2:
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]]
537 entry:
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
542 exit.1:
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
546   ret i1 %res.1
548 exit.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
552   ret i1 %res.2
555 define i1 @test_chained_adds_nuw_1(i8 %a, i8 %b) {
556 ; CHECK-LABEL: @test_chained_adds_nuw_1(
557 ; CHECK-NEXT:  entry:
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]]
568 entry:
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
578   ret i1 %res.1
581 define i1 @test_chained_adds_nuw_2(i8 %a, i8 %b) {
582 ; CHECK-LABEL: @test_chained_adds_nuw_2(
583 ; CHECK-NEXT:  entry:
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]]
595 entry:
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
606   ret i1 %res.1
609 define i1 @test_chained_adds_nuw_3(i8 %a, i8 %b) {
610 ; CHECK-LABEL: @test_chained_adds_nuw_3(
611 ; CHECK-NEXT:  entry:
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]]
623 entry:
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
634   ret i1 %res.1
637 define i1 @test_chained_adds_nuw_4(i8 %a, i8 %b) {
638 ; CHECK-LABEL: @test_chained_adds_nuw_4(
639 ; CHECK-NEXT:  entry:
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]]
651 entry:
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
662   ret i1 %res.1
665 define i1 @test_chained_adds_missing_nuw_1(i8 %a, i8 %b) {
666 ; CHECK-LABEL: @test_chained_adds_missing_nuw_1(
667 ; CHECK-NEXT:  entry:
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]]
680 entry:
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
691   ret i1 %res.1
694 define i1 @test_chained_adds_missing_nuw_2(i8 %a, i8 %b) {
695 ; CHECK-LABEL: @test_chained_adds_missing_nuw_2(
696 ; CHECK-NEXT:  entry:
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]]
709 entry:
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
720   ret i1 %res.1
723 define i1 @test_chained_adds_missing_nuw_3(i8 %a, i8 %b) {
724 ; CHECK-LABEL: @test_chained_adds_missing_nuw_3(
725 ; CHECK-NEXT:  entry:
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]]
738 entry:
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
749   ret i1 %res.1
752 declare void @llvm.assume(i1)