xref: /llvm-project/llvm/test/Transforms/InstCombine/usub-overflow-known-by-implied-cond.ll (revision b400dde4739f1868e1d4eb2b6c782e2dca235aba)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2
3; RUN: opt -passes=instcombine -S %s | FileCheck %s
4
5declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
6
7define i32 @test1(i32 %a, i32 %b) {
8; CHECK-LABEL: @test1(
9; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
10; CHECK-NEXT:    br i1 [[COND_NOT]], label [[BB3:%.*]], label [[BB1:%.*]]
11; CHECK:       bb1:
12; CHECK-NEXT:    br i1 false, label [[BB2:%.*]], label [[BB3]]
13; CHECK:       bb2:
14; CHECK-NEXT:    ret i32 poison
15; CHECK:       bb3:
16; CHECK-NEXT:    ret i32 0
17;
18  %cond = icmp uge i32 %a, %b
19  br i1 %cond, label %bb1, label %bb3
20
21bb1:
22  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
23  %r1 = extractvalue { i32, i1 } %sub1, 0
24  %c1 = extractvalue { i32, i1 } %sub1, 1
25  br i1 %c1, label %bb2, label %bb3
26
27bb2:
28  ret i32 %r1
29
30bb3:
31  ret i32 0
32}
33
34define i32 @test2(i32 %a, i32 %b) {
35; CHECK-LABEL: @test2(
36; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
37; CHECK-NEXT:    br i1 [[COND_NOT]], label [[BB3:%.*]], label [[BB1:%.*]]
38; CHECK:       bb1:
39; CHECK-NEXT:    br i1 false, label [[BB3]], label [[BB2:%.*]]
40; CHECK:       bb2:
41; CHECK-NEXT:    [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
42; CHECK-NEXT:    ret i32 [[SUB1]]
43; CHECK:       bb3:
44; CHECK-NEXT:    ret i32 0
45;
46  %cond = icmp uge i32 %a, %b
47  br i1 %cond, label %bb1, label %bb3
48
49bb1:
50  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
51  %r1 = extractvalue { i32, i1 } %sub1, 0
52  %c1 = extractvalue { i32, i1 } %sub1, 1
53  br i1 %c1, label %bb3, label %bb2
54
55bb2:
56  ret i32 %r1
57
58bb3:
59  ret i32 0
60}
61
62
63define i32 @test3(i32 %a, i32 %b) {
64; CHECK-LABEL: @test3(
65; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
66; CHECK-NEXT:    br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]]
67; CHECK:       bb1:
68; CHECK-NEXT:    br i1 false, label [[BB2:%.*]], label [[BB3]]
69; CHECK:       bb2:
70; CHECK-NEXT:    ret i32 poison
71; CHECK:       bb3:
72; CHECK-NEXT:    ret i32 0
73;
74  %cond = icmp ugt i32 %a, %b
75  br i1 %cond, label %bb1, label %bb3
76
77bb1:
78  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
79  %r1 = extractvalue { i32, i1 } %sub1, 0
80  %c1 = extractvalue { i32, i1 } %sub1, 1
81  br i1 %c1, label %bb2, label %bb3
82
83bb2:
84  ret i32 %r1
85
86bb3:
87  ret i32 0
88}
89
90define i32 @test4(i32 %a, i32 %b) {
91; CHECK-LABEL: @test4(
92; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
93; CHECK-NEXT:    br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]]
94; CHECK:       bb1:
95; CHECK-NEXT:    br i1 false, label [[BB3]], label [[BB2:%.*]]
96; CHECK:       bb2:
97; CHECK-NEXT:    [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
98; CHECK-NEXT:    ret i32 [[SUB1]]
99; CHECK:       bb3:
100; CHECK-NEXT:    ret i32 0
101;
102  %cond = icmp ugt i32 %a, %b
103  br i1 %cond, label %bb1, label %bb3
104
105bb1:
106  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
107  %r1 = extractvalue { i32, i1 } %sub1, 0
108  %c1 = extractvalue { i32, i1 } %sub1, 1
109  br i1 %c1, label %bb3, label %bb2
110
111bb2:
112  ret i32 %r1
113
114bb3:
115  ret i32 0
116}
117
118
119define i32 @test5(i32 %a, i32 %b) {
120; CHECK-LABEL: @test5(
121; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
122; CHECK-NEXT:    br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]]
123; CHECK:       bb1:
124; CHECK-NEXT:    br i1 false, label [[BB3]], label [[BB2:%.*]]
125; CHECK:       bb2:
126; CHECK-NEXT:    ret i32 0
127; CHECK:       bb3:
128; CHECK-NEXT:    ret i32 0
129;
130  %cond = icmp eq i32 %a, %b
131  br i1 %cond, label %bb1, label %bb3
132
133bb1:
134  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
135  %r1 = extractvalue { i32, i1 } %sub1, 0
136  %c1 = extractvalue { i32, i1 } %sub1, 1
137  br i1 %c1, label %bb3, label %bb2
138
139bb2:
140  ret i32 %r1
141
142bb3:
143  ret i32 0
144}
145
146define i32 @test6(i32 %a, i32 %b) {
147; CHECK-LABEL: @test6(
148; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
149; CHECK-NEXT:    br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]]
150; CHECK:       bb1:
151; CHECK-NEXT:    br i1 true, label [[BB3]], label [[BB2:%.*]]
152; CHECK:       bb2:
153; CHECK-NEXT:    ret i32 poison
154; CHECK:       bb3:
155; CHECK-NEXT:    ret i32 0
156;
157  %cond = icmp ult i32 %a, %b
158  br i1 %cond, label %bb1, label %bb3
159
160bb1:
161  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
162  %r1 = extractvalue { i32, i1 } %sub1, 0
163  %c1 = extractvalue { i32, i1 } %sub1, 1
164  br i1 %c1, label %bb3, label %bb2
165
166bb2:
167  ret i32 %r1
168
169bb3:
170  ret i32 0
171}
172
173define i32 @test7(i32 %a, i32 %b) {
174; CHECK-LABEL: @test7(
175; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
176; CHECK-NEXT:    br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]]
177; CHECK:       bb1:
178; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
179; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
180; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
181; CHECK:       bb2:
182; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
183; CHECK-NEXT:    ret i32 [[R1]]
184; CHECK:       bb3:
185; CHECK-NEXT:    ret i32 0
186;
187  %cond = icmp slt i32 %a, %b
188  br i1 %cond, label %bb1, label %bb3
189
190bb1:
191  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
192  %r1 = extractvalue { i32, i1 } %sub1, 0
193  %c1 = extractvalue { i32, i1 } %sub1, 1
194  br i1 %c1, label %bb3, label %bb2
195
196bb2:
197  ret i32 %r1
198
199bb3:
200  ret i32 0
201}
202
203define i32 @test8(i32 %a, i32 %b) {
204; CHECK-LABEL: @test8(
205; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
206; CHECK-NEXT:    br i1 [[COND_NOT]], label [[BB3:%.*]], label [[BB1:%.*]]
207; CHECK:       bb1:
208; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
209; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
210; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
211; CHECK:       bb2:
212; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
213; CHECK-NEXT:    ret i32 [[R1]]
214; CHECK:       bb3:
215; CHECK-NEXT:    ret i32 0
216;
217  %cond = icmp ne i32 %a, %b
218  br i1 %cond, label %bb1, label %bb3
219
220bb1:
221  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
222  %r1 = extractvalue { i32, i1 } %sub1, 0
223  %c1 = extractvalue { i32, i1 } %sub1, 1
224  br i1 %c1, label %bb3, label %bb2
225
226bb2:
227  ret i32 %r1
228
229bb3:
230  ret i32 0
231}
232
233define i32 @test9(i32 %a, i32 %b, i1 %cond2) {
234; CHECK-LABEL: @test9(
235; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
236; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND]], [[COND2:%.*]]
237; CHECK-NEXT:    br i1 [[AND]], label [[BB1:%.*]], label [[BB3:%.*]]
238; CHECK:       bb1:
239; CHECK-NEXT:    br i1 false, label [[BB3]], label [[BB2:%.*]]
240; CHECK:       bb2:
241; CHECK-NEXT:    [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
242; CHECK-NEXT:    ret i32 [[SUB1]]
243; CHECK:       bb3:
244; CHECK-NEXT:    ret i32 0
245;
246  %cond = icmp ugt i32 %a, %b
247  %and = and i1 %cond, %cond2
248  br i1 %and, label %bb1, label %bb3
249
250bb1:
251  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
252  %r1 = extractvalue { i32, i1 } %sub1, 0
253  %c1 = extractvalue { i32, i1 } %sub1, 1
254  br i1 %c1, label %bb3, label %bb2
255
256bb2:
257  ret i32 %r1
258
259bb3:
260  ret i32 0
261}
262
263define i32 @test9_logical(i32 %a, i32 %b, i1 %cond2) {
264; CHECK-LABEL: @test9_logical(
265; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
266; CHECK-NEXT:    [[AND:%.*]] = select i1 [[COND]], i1 [[COND2:%.*]], i1 false
267; CHECK-NEXT:    br i1 [[AND]], label [[BB1:%.*]], label [[BB3:%.*]]
268; CHECK:       bb1:
269; CHECK-NEXT:    br i1 false, label [[BB3]], label [[BB2:%.*]]
270; CHECK:       bb2:
271; CHECK-NEXT:    [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
272; CHECK-NEXT:    ret i32 [[SUB1]]
273; CHECK:       bb3:
274; CHECK-NEXT:    ret i32 0
275;
276  %cond = icmp ugt i32 %a, %b
277  %and = select i1 %cond, i1 %cond2, i1 false
278  br i1 %and, label %bb1, label %bb3
279
280bb1:
281  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
282  %r1 = extractvalue { i32, i1 } %sub1, 0
283  %c1 = extractvalue { i32, i1 } %sub1, 1
284  br i1 %c1, label %bb3, label %bb2
285
286bb2:
287  ret i32 %r1
288
289bb3:
290  ret i32 0
291}
292
293define i32 @test10(i32 %a, i32 %b, i1 %cond2) {
294; CHECK-LABEL: @test10(
295; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
296; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND]], [[COND2:%.*]]
297; CHECK-NEXT:    br i1 [[AND]], label [[BB3:%.*]], label [[BB1:%.*]]
298; CHECK:       bb1:
299; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
300; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
301; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
302; CHECK:       bb2:
303; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
304; CHECK-NEXT:    ret i32 [[R1]]
305; CHECK:       bb3:
306; CHECK-NEXT:    ret i32 0
307;
308  %cond = icmp ugt i32 %a, %b
309  %and = and i1 %cond, %cond2
310  br i1 %and, label %bb3, label %bb1
311
312bb1:
313  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
314  %r1 = extractvalue { i32, i1 } %sub1, 0
315  %c1 = extractvalue { i32, i1 } %sub1, 1
316  br i1 %c1, label %bb3, label %bb2
317
318bb2:
319  ret i32 %r1
320
321bb3:
322  ret i32 0
323}
324
325define i32 @test10_logical(i32 %a, i32 %b, i1 %cond2) {
326; CHECK-LABEL: @test10_logical(
327; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
328; CHECK-NEXT:    [[AND:%.*]] = select i1 [[COND]], i1 [[COND2:%.*]], i1 false
329; CHECK-NEXT:    br i1 [[AND]], label [[BB3:%.*]], label [[BB1:%.*]]
330; CHECK:       bb1:
331; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
332; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
333; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
334; CHECK:       bb2:
335; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
336; CHECK-NEXT:    ret i32 [[R1]]
337; CHECK:       bb3:
338; CHECK-NEXT:    ret i32 0
339;
340  %cond = icmp ugt i32 %a, %b
341  %and = select i1 %cond, i1 %cond2, i1 false
342  br i1 %and, label %bb3, label %bb1
343
344bb1:
345  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
346  %r1 = extractvalue { i32, i1 } %sub1, 0
347  %c1 = extractvalue { i32, i1 } %sub1, 1
348  br i1 %c1, label %bb3, label %bb2
349
350bb2:
351  ret i32 %r1
352
353bb3:
354  ret i32 0
355}
356
357define i32 @test11(i32 %a, i32 %b, i1 %cond2) {
358; CHECK-LABEL: @test11(
359; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
360; CHECK-NEXT:    [[OR:%.*]] = or i1 [[COND]], [[COND2:%.*]]
361; CHECK-NEXT:    br i1 [[OR]], label [[BB1:%.*]], label [[BB3:%.*]]
362; CHECK:       bb1:
363; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
364; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
365; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
366; CHECK:       bb2:
367; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
368; CHECK-NEXT:    ret i32 [[R1]]
369; CHECK:       bb3:
370; CHECK-NEXT:    ret i32 0
371;
372  %cond = icmp ugt i32 %a, %b
373  %or = or i1 %cond, %cond2
374  br i1 %or, label %bb1, label %bb3
375
376bb1:
377  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
378  %r1 = extractvalue { i32, i1 } %sub1, 0
379  %c1 = extractvalue { i32, i1 } %sub1, 1
380  br i1 %c1, label %bb3, label %bb2
381
382bb2:
383  ret i32 %r1
384
385bb3:
386  ret i32 0
387}
388
389define i32 @test11_logical(i32 %a, i32 %b, i1 %cond2) {
390; CHECK-LABEL: @test11_logical(
391; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
392; CHECK-NEXT:    [[OR:%.*]] = select i1 [[COND]], i1 true, i1 [[COND2:%.*]]
393; CHECK-NEXT:    br i1 [[OR]], label [[BB1:%.*]], label [[BB3:%.*]]
394; CHECK:       bb1:
395; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
396; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
397; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
398; CHECK:       bb2:
399; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
400; CHECK-NEXT:    ret i32 [[R1]]
401; CHECK:       bb3:
402; CHECK-NEXT:    ret i32 0
403;
404  %cond = icmp ugt i32 %a, %b
405  %or = select i1 %cond, i1 true, i1 %cond2
406  br i1 %or, label %bb1, label %bb3
407
408bb1:
409  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
410  %r1 = extractvalue { i32, i1 } %sub1, 0
411  %c1 = extractvalue { i32, i1 } %sub1, 1
412  br i1 %c1, label %bb3, label %bb2
413
414bb2:
415  ret i32 %r1
416
417bb3:
418  ret i32 0
419}
420
421define i32 @test12(i32 %a, i32 %b, i1 %cond2) {
422; CHECK-LABEL: @test12(
423; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
424; CHECK-NEXT:    [[OR:%.*]] = or i1 [[COND]], [[COND2:%.*]]
425; CHECK-NEXT:    br i1 [[OR]], label [[BB3:%.*]], label [[BB1:%.*]]
426; CHECK:       bb1:
427; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
428; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
429; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
430; CHECK:       bb2:
431; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
432; CHECK-NEXT:    ret i32 [[R1]]
433; CHECK:       bb3:
434; CHECK-NEXT:    ret i32 0
435;
436  %cond = icmp ugt i32 %a, %b
437  %or = or i1 %cond, %cond2
438  br i1 %or, label %bb3, label %bb1
439
440bb1:
441  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
442  %r1 = extractvalue { i32, i1 } %sub1, 0
443  %c1 = extractvalue { i32, i1 } %sub1, 1
444  br i1 %c1, label %bb3, label %bb2
445
446bb2:
447  ret i32 %r1
448
449bb3:
450  ret i32 0
451}
452
453define i32 @test12_logical(i32 %a, i32 %b, i1 %cond2) {
454; CHECK-LABEL: @test12_logical(
455; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
456; CHECK-NEXT:    [[OR:%.*]] = select i1 [[COND]], i1 true, i1 [[COND2:%.*]]
457; CHECK-NEXT:    br i1 [[OR]], label [[BB3:%.*]], label [[BB1:%.*]]
458; CHECK:       bb1:
459; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
460; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
461; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
462; CHECK:       bb2:
463; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
464; CHECK-NEXT:    ret i32 [[R1]]
465; CHECK:       bb3:
466; CHECK-NEXT:    ret i32 0
467;
468  %cond = icmp ugt i32 %a, %b
469  %or = select i1 %cond, i1 true, i1 %cond2
470  br i1 %or, label %bb3, label %bb1
471
472bb1:
473  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
474  %r1 = extractvalue { i32, i1 } %sub1, 0
475  %c1 = extractvalue { i32, i1 } %sub1, 1
476  br i1 %c1, label %bb3, label %bb2
477
478bb2:
479  ret i32 %r1
480
481bb3:
482  ret i32 0
483}
484