AMDGPU: Allow f16/bf16 for DS_READ_TR16_B64 gfx950 builtins (#118297)
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / add-nuw.ll
bloba8a474e6d4502a0b3a3accedbb78367f331f258f
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:    call void @use(i1 true)
239 ; CHECK-NEXT:    ret void
240 ; CHECK:       if.end:
241 ; CHECK-NEXT:    ret void
243 entry:
244   %c.0 = icmp uge i8 %a, %c
245   %c.1 = icmp uge i8 %b, %c
246   %and.0 = and i1 %c.0, %c.1
247   br i1 %and.0, label %if.then, label %if.end
249 if.then:                                          ; preds = %entry
250   %c.2 = icmp uge i8 %a, 0
251   %c.3 = icmp uge i8 %b, 0
252   %and.1 = and i1 %c.2, %c.3
253   br i1 %and.1, label %if.then.2, label %if.end
255 if.then.2:
256   %add.0 = add nuw i8 %a, %b
257   %t.0 = icmp uge i8 %add.0, %c
258   call void @use(i1 %t.0)
259   %add.1 = add nuw i8 %a, %a
260   %t.1 = icmp uge i8 %add.0, %c
261   call void @use(i1 %t.1)
262   %add.2 = add nuw i8 %a, %d
263   %c.4 = icmp uge i8 %add.2, %c
264   call void @use(i1 %c.4)
265   ret void
267 if.end:                                           ; preds = %entry
268   ret void
271 define void @test.decompose.nonconst.no.null.check(i8 %a, i8 %b, i8 %c, i8 %d) {
272 ; CHECK-LABEL: @test.decompose.nonconst.no.null.check(
273 ; CHECK-NEXT:  entry:
274 ; CHECK-NEXT:    [[C_0:%.*]] = icmp uge i8 [[A:%.*]], [[C:%.*]]
275 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[C]]
276 ; CHECK-NEXT:    [[AND_0:%.*]] = and i1 [[C_0]], [[C_1]]
277 ; CHECK-NEXT:    br i1 [[AND_0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
278 ; CHECK:       if.then:
279 ; CHECK-NEXT:    [[ADD_0:%.*]] = add nuw i8 [[A]], [[B]]
280 ; CHECK-NEXT:    call void @use(i1 true)
281 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw i8 [[A]], [[A]]
282 ; CHECK-NEXT:    call void @use(i1 true)
283 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw i8 [[A]], [[D:%.*]]
284 ; CHECK-NEXT:    call void @use(i1 true)
285 ; CHECK-NEXT:    ret void
286 ; CHECK:       if.end:
287 ; CHECK-NEXT:    ret void
289 entry:
290   %c.0 = icmp uge i8 %a, %c
291   %c.1 = icmp uge i8 %b, %c
292   %and.0 = and i1 %c.0, %c.1
293   br i1 %and.0, label %if.then, label %if.end
295 if.then:                                          ; preds = %entry
296   %add.0 = add nuw i8 %a, %b
297   %t.0 = icmp uge i8 %add.0, %c
298   call void @use(i1 %t.0)
299   %add.1 = add nuw i8 %a, %a
300   %t.1 = icmp uge i8 %add.0, %c
301   call void @use(i1 %t.1)
302   %add.2 = add nuw i8 %a, %d
303   %c.4 = icmp uge i8 %add.2, %c
304   call void @use(i1 %c.4)
305   ret void
307 if.end:                                           ; preds = %entry
308   ret void
312 define i1 @test_n_must_ule_1_due_to_nuw(i8 %n, i8 %i) {
313 ; CHECK-LABEL: @test_n_must_ule_1_due_to_nuw(
314 ; CHECK-NEXT:  entry:
315 ; CHECK-NEXT:    [[SUB_N_1:%.*]] = add nuw i8 [[N:%.*]], -1
316 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[I:%.*]], [[SUB_N_1]]
317 ; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END:%.*]]
318 ; CHECK:       if.then:
319 ; CHECK-NEXT:    ret i1 true
320 ; CHECK:       if.end:
321 ; CHECK-NEXT:    [[F:%.*]] = icmp ule i8 [[N]], 1
322 ; CHECK-NEXT:    ret i1 [[F]]
324 entry:
325   %sub.n.1 = add nuw i8 %n, -1
326   %add = add nuw i8 %i, %sub.n.1
327   %c.1 = icmp uge i8 %i, %add
328   br i1 %c.1, label %if.then, label %if.end
330 if.then:                                          ; preds = %entry
331   %t = icmp ule i8 %n, 1
332   ret i1 %t
334 if.end:                                           ; preds = %entry
335   %f = icmp ule i8 %n, 1
336   ret i1 %f
340 define i1 @test_n_unknown_missing_nuw(i8 %n, i8 %i) {
341 ; CHECK-LABEL: @test_n_unknown_missing_nuw(
342 ; CHECK-NEXT:  entry:
343 ; CHECK-NEXT:    [[SUB_N_1:%.*]] = add i8 [[N:%.*]], -1
344 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[I:%.*]], [[SUB_N_1]]
345 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]]
346 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
347 ; CHECK:       if.then:
348 ; CHECK-NEXT:    [[T:%.*]] = icmp ule i8 [[N]], 1
349 ; CHECK-NEXT:    ret i1 [[T]]
350 ; CHECK:       if.end:
351 ; CHECK-NEXT:    [[F:%.*]] = icmp ule i8 [[N]], 1
352 ; CHECK-NEXT:    ret i1 [[F]]
354 entry:
355   %sub.n.1 = add i8 %n, -1
356   %add = add i8 %i, %sub.n.1
357   %c.1 = icmp uge i8 %i, %add
358   br i1 %c.1, label %if.then, label %if.end
360 if.then:                                          ; preds = %entry
361   %t = icmp ule i8 %n, 1
362   ret i1 %t
364 if.end:                                           ; preds = %entry
365   %f = icmp ule i8 %n, 1
366   ret i1 %f
369 define i1 @test_n_must_ule_2_due_to_nuw(i8 %n, i8 %i) {
370 ; CHECK-LABEL: @test_n_must_ule_2_due_to_nuw(
371 ; CHECK-NEXT:  entry:
372 ; CHECK-NEXT:    [[SUB_N_1:%.*]] = add nuw i8 [[N:%.*]], -2
373 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[I:%.*]], [[SUB_N_1]]
374 ; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END:%.*]]
375 ; CHECK:       if.then:
376 ; CHECK-NEXT:    ret i1 true
377 ; CHECK:       if.end:
378 ; CHECK-NEXT:    [[F:%.*]] = icmp ule i8 [[N]], 2
379 ; CHECK-NEXT:    ret i1 [[F]]
381 entry:
382   %sub.n.1 = add nuw i8 %n, -2
383   %add = add nuw i8 %i, %sub.n.1
384   %c.1 = icmp uge i8 %i, %add
385   br i1 %c.1, label %if.then, label %if.end
387 if.then:                                          ; preds = %entry
388   %t = icmp ule i8 %n, 2
389   ret i1 %t
391 if.end:                                           ; preds = %entry
392   %f = icmp ule i8 %n, 2
393   ret i1 %f
397 define i1 @test_n_unknown_missing_nuw2(i8 %n, i8 %i) {
398 ; CHECK-LABEL: @test_n_unknown_missing_nuw2(
399 ; CHECK-NEXT:  entry:
400 ; CHECK-NEXT:    [[SUB_N_1:%.*]] = add i8 [[N:%.*]], -2
401 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[I:%.*]], [[SUB_N_1]]
402 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]]
403 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
404 ; CHECK:       if.then:
405 ; CHECK-NEXT:    [[T:%.*]] = icmp ule i8 [[N]], 1
406 ; CHECK-NEXT:    ret i1 [[T]]
407 ; CHECK:       if.end:
408 ; CHECK-NEXT:    [[F:%.*]] = icmp ule i8 [[N]], 1
409 ; CHECK-NEXT:    ret i1 [[F]]
411 entry:
412   %sub.n.1 = add i8 %n, -2
413   %add = add i8 %i, %sub.n.1
414   %c.1 = icmp uge i8 %i, %add
415   br i1 %c.1, label %if.then, label %if.end
417 if.then:                                          ; preds = %entry
418   %t = icmp ule i8 %n, 1
419   ret i1 %t
421 if.end:                                           ; preds = %entry
422   %f = icmp ule i8 %n, 1
423   ret i1 %f
426 declare void @use(i1)
428 define i1 @add_nuw_neg_pr54224_i16(i16 %a) {
429 ; CHECK-LABEL: @add_nuw_neg_pr54224_i16(
430 ; CHECK-NEXT:  entry:
431 ; CHECK-NEXT:    [[NEG2:%.*]] = add nuw i16 [[A:%.*]], -305
432 ; CHECK-NEXT:    br i1 false, label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]
433 ; CHECK:       exit.1:
434 ; CHECK-NEXT:    ret i1 true
435 ; CHECK:       exit.2:
436 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i16 [[A]], 0
437 ; CHECK-NEXT:    ret i1 [[C_3]]
439 entry:
440   %neg2 = add nuw i16 %a, -305
441   %c.1 = icmp ugt i16 0, %neg2
442   br i1 %c.1, label %exit.1, label %exit.2
444 exit.1:
445   %c.2 = icmp ugt i16 %a, 0
446   ret i1 %c.2
448 exit.2:
449   %c.3 = icmp ugt i16 %a, 0
450   ret i1 %c.3
453 define i1 @add_nuw_neg_pr54224_i64(i64 %a) {
454 ; CHECK-LABEL: @add_nuw_neg_pr54224_i64(
455 ; CHECK-NEXT:  entry:
456 ; CHECK-NEXT:    [[NEG2:%.*]] = add nuw i64 [[A:%.*]], -305
457 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i64 0, [[NEG2]]
458 ; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]
459 ; CHECK:       exit.1:
460 ; CHECK-NEXT:    ret i1 true
461 ; CHECK:       exit.2:
462 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i64 [[A]], 0
463 ; CHECK-NEXT:    ret i1 [[C_3]]
465 entry:
466   %neg2 = add nuw i64 %a, -305
467   %c.1 = icmp ugt i64 0, %neg2
468   br i1 %c.1, label %exit.1, label %exit.2
470 exit.1:
471   %c.2 = icmp ugt i64 %a, 0
472   ret i1 %c.2
474 exit.2:
475   %c.3 = icmp ugt i64 %a, 0
476   ret i1 %c.3
479 define i1 @add_nuw_neg2_i8(i8 %a) {
480 ; CHECK-LABEL: @add_nuw_neg2_i8(
481 ; CHECK-NEXT:  entry:
482 ; CHECK-NEXT:    [[NEG2:%.*]] = add nuw i8 [[A:%.*]], -4
483 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[NEG2]], -2
484 ; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]
485 ; CHECK:       exit.1:
486 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ult i8 [[A]], 1
487 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[C_2]]
488 ; CHECK-NEXT:    ret i1 [[RES_1]]
489 ; CHECK:       exit.2:
490 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ult i8 [[A]], 3
491 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[C_3]], false
492 ; CHECK-NEXT:    ret i1 [[RES_2]]
494 entry:
495   %neg2 = add nuw i8 %a, -4
496   %c.1 = icmp ult i8 %neg2, -2
497   br i1 %c.1, label %exit.1, label %exit.2
499 exit.1:
500   %t.1 = icmp ult i8 %a, 2
501   %c.2 = icmp ult i8 %a, 1
502   %res.1 = xor i1 %t.1, %c.2
503   ret i1 %res.1
505 exit.2:
506   %c.3 = icmp ult i8 %a, 3
507   %f.1 = icmp ult i8 %a, 2
508   %res.2 = xor i1 %c.3, %f.1
509   ret i1 %res.2
512 define i1 @add_nuw_neg2_i64(i64 %a) {
513 ; CHECK-LABEL: @add_nuw_neg2_i64(
514 ; CHECK-NEXT:  entry:
515 ; CHECK-NEXT:    [[NEG2:%.*]] = add nuw i64 [[A:%.*]], -4
516 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i64 [[NEG2]], -2
517 ; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]
518 ; CHECK:       exit.1:
519 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ult i64 [[A]], 2
520 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ult i64 [[A]], 1
521 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[T_1]], [[C_2]]
522 ; CHECK-NEXT:    ret i1 [[RES_1]]
523 ; CHECK:       exit.2:
524 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ult i64 [[A]], 3
525 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ult i64 [[A]], 2
526 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[C_3]], [[F_1]]
527 ; CHECK-NEXT:    ret i1 [[RES_2]]
529 entry:
530   %neg2 = add nuw i64 %a, -4
531   %c.1 = icmp ult i64 %neg2, -2
532   br i1 %c.1, label %exit.1, label %exit.2
534 exit.1:
535   %t.1 = icmp ult i64 %a, 2
536   %c.2 = icmp ult i64 %a, 1
537   %res.1 = xor i1 %t.1, %c.2
538   ret i1 %res.1
540 exit.2:
541   %c.3 = icmp ult i64 %a, 3
542   %f.1 = icmp ult i64 %a, 2
543   %res.2 = xor i1 %c.3, %f.1
544   ret i1 %res.2
547 define i1 @test_chained_adds_nuw_1(i8 %a, i8 %b) {
548 ; CHECK-LABEL: @test_chained_adds_nuw_1(
549 ; CHECK-NEXT:  entry:
550 ; CHECK-NEXT:    [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
551 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_A]])
552 ; CHECK-NEXT:    [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
553 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_B]])
554 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw i8 [[A]], [[B]]
555 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], 2
556 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[ADD_2]], 14
557 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[C_1]]
558 ; CHECK-NEXT:    ret i1 [[RES_1]]
560 entry:
561   %c.a = icmp uge i8 %a, 5
562   call void @llvm.assume(i1 %c.a)
563   %c.b = icmp uge i8 %b, 6
564   call void @llvm.assume(i1 %c.b)
565   %add.1 = add nuw i8 %a, %b
566   %add.2 = add nuw i8 %add.1, 2
567   %t.1 = icmp uge i8 %add.2, 13
568   %c.1 = icmp uge i8 %add.2, 14
569   %res.1 = xor i1 %t.1, %c.1
570   ret i1 %res.1
573 define i1 @test_chained_adds_nuw_2(i8 %a, i8 %b) {
574 ; CHECK-LABEL: @test_chained_adds_nuw_2(
575 ; CHECK-NEXT:  entry:
576 ; CHECK-NEXT:    [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
577 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_A]])
578 ; CHECK-NEXT:    [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
579 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_B]])
580 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw i8 [[A]], [[B]]
581 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], 2
582 ; CHECK-NEXT:    [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]]
583 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 19
584 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[C_1]]
585 ; CHECK-NEXT:    ret i1 [[RES_1]]
587 entry:
588   %c.a = icmp uge i8 %a, 5
589   call void @llvm.assume(i1 %c.a)
590   %c.b = icmp uge i8 %b, 6
591   call void @llvm.assume(i1 %c.b)
592   %add.1 = add nuw i8 %a, %b
593   %add.2 = add nuw i8 %add.1, 2
594   %add.3 = add nuw i8 %add.2, %a
595   %t.1 = icmp uge i8 %add.3, 18
596   %c.1 = icmp uge i8 %add.3, 19
597   %res.1 = xor i1 %t.1, %c.1
598   ret i1 %res.1
601 define i1 @test_chained_adds_nuw_3(i8 %a, i8 %b) {
602 ; CHECK-LABEL: @test_chained_adds_nuw_3(
603 ; CHECK-NEXT:  entry:
604 ; CHECK-NEXT:    [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
605 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_A]])
606 ; CHECK-NEXT:    [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
607 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_B]])
608 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw i8 [[A]], 2
609 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]]
610 ; CHECK-NEXT:    [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]]
611 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 19
612 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[C_1]]
613 ; CHECK-NEXT:    ret i1 [[RES_1]]
615 entry:
616   %c.a = icmp uge i8 %a, 5
617   call void @llvm.assume(i1 %c.a)
618   %c.b = icmp uge i8 %b, 6
619   call void @llvm.assume(i1 %c.b)
620   %add.1 = add nuw i8 %a, 2
621   %add.2 = add nuw i8 %add.1, %b
622   %add.3 = add nuw i8 %add.2, %a
623   %t.1 = icmp uge i8 %add.3, 18
624   %c.1 = icmp uge i8 %add.3, 19
625   %res.1 = xor i1 %t.1, %c.1
626   ret i1 %res.1
629 define i1 @test_chained_adds_nuw_4(i8 %a, i8 %b) {
630 ; CHECK-LABEL: @test_chained_adds_nuw_4(
631 ; CHECK-NEXT:  entry:
632 ; CHECK-NEXT:    [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
633 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_A]])
634 ; CHECK-NEXT:    [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
635 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_B]])
636 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw i8 [[A]], 2
637 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]]
638 ; CHECK-NEXT:    [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], 10
639 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 24
640 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[C_1]]
641 ; CHECK-NEXT:    ret i1 [[RES_1]]
643 entry:
644   %c.a = icmp uge i8 %a, 5
645   call void @llvm.assume(i1 %c.a)
646   %c.b = icmp uge i8 %b, 6
647   call void @llvm.assume(i1 %c.b)
648   %add.1 = add nuw i8 %a, 2
649   %add.2 = add nuw i8 %add.1, %b
650   %add.3 = add nuw i8 %add.2, 10
651   %t.1 = icmp uge i8 %add.3, 23
652   %c.1 = icmp uge i8 %add.3, 24
653   %res.1 = xor i1 %t.1, %c.1
654   ret i1 %res.1
657 define i1 @test_chained_adds_missing_nuw_1(i8 %a, i8 %b) {
658 ; CHECK-LABEL: @test_chained_adds_missing_nuw_1(
659 ; CHECK-NEXT:  entry:
660 ; CHECK-NEXT:    [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
661 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_A]])
662 ; CHECK-NEXT:    [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
663 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_B]])
664 ; CHECK-NEXT:    [[ADD_1:%.*]] = add i8 [[A]], 2
665 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]]
666 ; CHECK-NEXT:    [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]]
667 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 18
668 ; CHECK-NEXT:    [[C_2:%.*]] = icmp uge i8 [[ADD_3]], 19
669 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]
670 ; CHECK-NEXT:    ret i1 [[RES_1]]
672 entry:
673   %c.a = icmp uge i8 %a, 5
674   call void @llvm.assume(i1 %c.a)
675   %c.b = icmp uge i8 %b, 6
676   call void @llvm.assume(i1 %c.b)
677   %add.1 = add i8 %a, 2
678   %add.2 = add nuw i8 %add.1, %b
679   %add.3 = add nuw i8 %add.2, %a
680   %c.1 = icmp uge i8 %add.3, 18
681   %c.2 = icmp uge i8 %add.3, 19
682   %res.1 = xor i1 %c.1, %c.2
683   ret i1 %res.1
686 define i1 @test_chained_adds_missing_nuw_2(i8 %a, i8 %b) {
687 ; CHECK-LABEL: @test_chained_adds_missing_nuw_2(
688 ; CHECK-NEXT:  entry:
689 ; CHECK-NEXT:    [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
690 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_A]])
691 ; CHECK-NEXT:    [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
692 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_B]])
693 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw i8 [[A]], 2
694 ; CHECK-NEXT:    [[ADD_2:%.*]] = add i8 [[ADD_1]], [[B]]
695 ; CHECK-NEXT:    [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]]
696 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 18
697 ; CHECK-NEXT:    [[C_2:%.*]] = icmp uge i8 [[ADD_3]], 19
698 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]
699 ; CHECK-NEXT:    ret i1 [[RES_1]]
701 entry:
702   %c.a = icmp uge i8 %a, 5
703   call void @llvm.assume(i1 %c.a)
704   %c.b = icmp uge i8 %b, 6
705   call void @llvm.assume(i1 %c.b)
706   %add.1 = add nuw i8 %a, 2
707   %add.2 = add i8 %add.1, %b
708   %add.3 = add nuw i8 %add.2, %a
709   %c.1 = icmp uge i8 %add.3, 18
710   %c.2 = icmp uge i8 %add.3, 19
711   %res.1 = xor i1 %c.1, %c.2
712   ret i1 %res.1
715 define i1 @test_chained_adds_missing_nuw_3(i8 %a, i8 %b) {
716 ; CHECK-LABEL: @test_chained_adds_missing_nuw_3(
717 ; CHECK-NEXT:  entry:
718 ; CHECK-NEXT:    [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5
719 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_A]])
720 ; CHECK-NEXT:    [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6
721 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_B]])
722 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw i8 [[A]], 2
723 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]]
724 ; CHECK-NEXT:    [[ADD_3:%.*]] = add i8 [[ADD_2]], [[A]]
725 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 18
726 ; CHECK-NEXT:    [[C_2:%.*]] = icmp uge i8 [[ADD_3]], 19
727 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]
728 ; CHECK-NEXT:    ret i1 [[RES_1]]
730 entry:
731   %c.a = icmp uge i8 %a, 5
732   call void @llvm.assume(i1 %c.a)
733   %c.b = icmp uge i8 %b, 6
734   call void @llvm.assume(i1 %c.b)
735   %add.1 = add nuw i8 %a, 2
736   %add.2 = add nuw i8 %add.1, %b
737   %add.3 = add i8 %add.2, %a
738   %c.1 = icmp uge i8 %add.3, 18
739   %c.2 = icmp uge i8 %add.3, 19
740   %res.1 = xor i1 %c.1, %c.2
741   ret i1 %res.1
744 declare void @llvm.assume(i1)