xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/add-nuw.ll (revision fbcf8a8cbb2461730bfd0603b396842925a88ef2)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4define 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
24;
25entry:
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
29
30if.then:                                          ; preds = %entry
31  ret void
32
33if.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
49}
50
51define 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
73;
74entry:
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
78
79if.then:                                          ; preds = %entry
80  ret void
81
82if.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)
97
98  %start.5 = add nuw i8 %start, 5
99  %c.5 = icmp ule i8 %start.5, %high
100  call void @use(i1 %c.5)
101
102  ret void
103}
104
105define 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
127;
128entry:
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
132
133if.then:                                          ; preds = %entry
134  ret void
135
136if.end:                                           ; preds = %entry
137  %f.0 = icmp ugt i8 %start, %high
138  call void @use(i1 %f.0)
139
140  %start.1 = add nuw i8 %start, 1
141  %f.1 = icmp ugt i8 %start.1, %high
142  call void @use(i1 %f.1)
143
144  %start.2 = add nuw i8 %start, 2
145  %f.2 = icmp ugt i8 %start.2, %high
146  call void @use(i1 %f.2)
147
148  %start.3 = add nuw i8 %start, 3
149  %f.3 = icmp ugt i8 %start.3, %high
150  call void @use(i1 %f.3)
151
152  %start.4 = add nuw i8 %start, 4
153  %f.4 = icmp ugt i8 %start.4, %high
154  call void @use(i1 %f.4)
155
156  %start.5 = add nuw i8 %start, 5
157  %c.5 = icmp ugt i8 %start.5, %high
158  call void @use(i1 %c.5)
159
160  ret void
161}
162
163define 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
186;
187entry:
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
191
192if.then:                                          ; preds = %entry
193  ret void
194
195if.end:                                           ; preds = %entry
196  %f.0 = icmp ugt i8 %start, %high
197  call void @use(i1 %f.0)
198
199  %start.1 = add nuw i8 %start, 1
200  %f.1 = icmp uge i8 %start.1, %high
201  call void @use(i1 %f.1)
202
203  %start.2 = add nuw i8 %start, 2
204  %f.2 = icmp uge i8 %start.2, %high
205  call void @use(i1 %f.2)
206
207  %start.3 = add nuw i8 %start, 3
208  %f.3 = icmp uge i8 %start.3, %high
209  call void @use(i1 %f.3)
210
211  %start.4 = add nuw i8 %start, 4
212  %c.4 = icmp uge i8 %start.4, %high
213  call void @use(i1 %c.4)
214
215  %start.5 = add nuw i8 %start, 5
216  %c.5 = icmp uge i8 %start.5, %high
217  call void @use(i1 %c.5)
218
219  ret void
220}
221
222define 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
242;
243entry:
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
248
249if.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
254
255if.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
266
267if.end:                                           ; preds = %entry
268  ret void
269}
270
271define 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
288;
289entry:
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
294
295if.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
306
307if.end:                                           ; preds = %entry
308  ret void
309}
310
311
312define 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]]
323;
324entry:
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
329
330if.then:                                          ; preds = %entry
331  %t = icmp ule i8 %n, 1
332  ret i1 %t
333
334if.end:                                           ; preds = %entry
335  %f = icmp ule i8 %n, 1
336  ret i1 %f
337}
338
339
340define 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]]
353;
354entry:
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
359
360if.then:                                          ; preds = %entry
361  %t = icmp ule i8 %n, 1
362  ret i1 %t
363
364if.end:                                           ; preds = %entry
365  %f = icmp ule i8 %n, 1
366  ret i1 %f
367}
368
369define 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]]
380;
381entry:
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
386
387if.then:                                          ; preds = %entry
388  %t = icmp ule i8 %n, 2
389  ret i1 %t
390
391if.end:                                           ; preds = %entry
392  %f = icmp ule i8 %n, 2
393  ret i1 %f
394}
395
396
397define 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]]
410;
411entry:
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
416
417if.then:                                          ; preds = %entry
418  %t = icmp ule i8 %n, 1
419  ret i1 %t
420
421if.end:                                           ; preds = %entry
422  %f = icmp ule i8 %n, 1
423  ret i1 %f
424}
425
426declare void @use(i1)
427
428define 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]]
438;
439entry:
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
443
444exit.1:
445  %c.2 = icmp ugt i16 %a, 0
446  ret i1 %c.2
447
448exit.2:
449  %c.3 = icmp ugt i16 %a, 0
450  ret i1 %c.3
451}
452
453define 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]]
464;
465entry:
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
469
470exit.1:
471  %c.2 = icmp ugt i64 %a, 0
472  ret i1 %c.2
473
474exit.2:
475  %c.3 = icmp ugt i64 %a, 0
476  ret i1 %c.3
477}
478
479define 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]]
493;
494entry:
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
498
499exit.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
504
505exit.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
510}
511
512define 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]]
528;
529entry:
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
533
534exit.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
539
540exit.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
545}
546
547define 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]]
559;
560entry:
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
571}
572
573define 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]]
586;
587entry:
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
599}
600
601define 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]]
614;
615entry:
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
627}
628
629define 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]]
642;
643entry:
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
655}
656
657define 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]]
671;
672entry:
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
684}
685
686define 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]]
700;
701entry:
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
713}
714
715define 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]]
729;
730entry:
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
742}
743
744declare void @llvm.assume(i1)
745