1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2
3; RUN: opt -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:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
10; CHECK-NEXT:    br i1 [[COND]], 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 undef
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:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
37; CHECK-NEXT:    br i1 [[COND]], 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 undef
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:    [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
127; CHECK-NEXT:    ret i32 [[SUB1]]
128; CHECK:       bb3:
129; CHECK-NEXT:    ret i32 0
130;
131  %cond = icmp eq i32 %a, %b
132  br i1 %cond, label %bb1, label %bb3
133
134bb1:
135  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
136  %r1 = extractvalue { i32, i1 } %sub1, 0
137  %c1 = extractvalue { i32, i1 } %sub1, 1
138  br i1 %c1, label %bb3, label %bb2
139
140bb2:
141  ret i32 %r1
142
143bb3:
144  ret i32 0
145}
146
147define i32 @test6(i32 %a, i32 %b) {
148; CHECK-LABEL: @test6(
149; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
150; CHECK-NEXT:    br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]]
151; CHECK:       bb1:
152; CHECK-NEXT:    br i1 true, label [[BB3]], label [[BB2:%.*]]
153; CHECK:       bb2:
154; CHECK-NEXT:    ret i32 undef
155; CHECK:       bb3:
156; CHECK-NEXT:    ret i32 0
157;
158  %cond = icmp ult i32 %a, %b
159  br i1 %cond, label %bb1, label %bb3
160
161bb1:
162  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
163  %r1 = extractvalue { i32, i1 } %sub1, 0
164  %c1 = extractvalue { i32, i1 } %sub1, 1
165  br i1 %c1, label %bb3, label %bb2
166
167bb2:
168  ret i32 %r1
169
170bb3:
171  ret i32 0
172}
173
174define i32 @test7(i32 %a, i32 %b) {
175; CHECK-LABEL: @test7(
176; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
177; CHECK-NEXT:    br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]]
178; CHECK:       bb1:
179; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
180; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
181; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
182; CHECK:       bb2:
183; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
184; CHECK-NEXT:    ret i32 [[R1]]
185; CHECK:       bb3:
186; CHECK-NEXT:    ret i32 0
187;
188  %cond = icmp slt i32 %a, %b
189  br i1 %cond, label %bb1, label %bb3
190
191bb1:
192  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
193  %r1 = extractvalue { i32, i1 } %sub1, 0
194  %c1 = extractvalue { i32, i1 } %sub1, 1
195  br i1 %c1, label %bb3, label %bb2
196
197bb2:
198  ret i32 %r1
199
200bb3:
201  ret i32 0
202}
203
204define i32 @test8(i32 %a, i32 %b) {
205; CHECK-LABEL: @test8(
206; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
207; CHECK-NEXT:    br i1 [[COND]], label [[BB3:%.*]], label [[BB1:%.*]]
208; CHECK:       bb1:
209; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
210; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
211; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
212; CHECK:       bb2:
213; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
214; CHECK-NEXT:    ret i32 [[R1]]
215; CHECK:       bb3:
216; CHECK-NEXT:    ret i32 0
217;
218  %cond = icmp ne i32 %a, %b
219  br i1 %cond, label %bb1, label %bb3
220
221bb1:
222  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
223  %r1 = extractvalue { i32, i1 } %sub1, 0
224  %c1 = extractvalue { i32, i1 } %sub1, 1
225  br i1 %c1, label %bb3, label %bb2
226
227bb2:
228  ret i32 %r1
229
230bb3:
231  ret i32 0
232}
233
234define i32 @test9(i32 %a, i32 %b, i1 %cond2) {
235; CHECK-LABEL: @test9(
236; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
237; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND]], [[COND2:%.*]]
238; CHECK-NEXT:    br i1 [[AND]], label [[BB1:%.*]], label [[BB3:%.*]]
239; CHECK:       bb1:
240; CHECK-NEXT:    br i1 false, label [[BB3]], label [[BB2:%.*]]
241; CHECK:       bb2:
242; CHECK-NEXT:    [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
243; CHECK-NEXT:    ret i32 [[SUB1]]
244; CHECK:       bb3:
245; CHECK-NEXT:    ret i32 0
246;
247  %cond = icmp ugt i32 %a, %b
248  %and = and i1 %cond, %cond2
249  br i1 %and, label %bb1, label %bb3
250
251bb1:
252  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
253  %r1 = extractvalue { i32, i1 } %sub1, 0
254  %c1 = extractvalue { i32, i1 } %sub1, 1
255  br i1 %c1, label %bb3, label %bb2
256
257bb2:
258  ret i32 %r1
259
260bb3:
261  ret i32 0
262}
263
264define i32 @test10(i32 %a, i32 %b, i1 %cond2) {
265; CHECK-LABEL: @test10(
266; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
267; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND]], [[COND2:%.*]]
268; CHECK-NEXT:    br i1 [[AND]], label [[BB3:%.*]], label [[BB1:%.*]]
269; CHECK:       bb1:
270; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
271; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
272; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
273; CHECK:       bb2:
274; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
275; CHECK-NEXT:    ret i32 [[R1]]
276; CHECK:       bb3:
277; CHECK-NEXT:    ret i32 0
278;
279  %cond = icmp ugt i32 %a, %b
280  %and = and i1 %cond, %cond2
281  br i1 %and, label %bb3, label %bb1
282
283bb1:
284  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
285  %r1 = extractvalue { i32, i1 } %sub1, 0
286  %c1 = extractvalue { i32, i1 } %sub1, 1
287  br i1 %c1, label %bb3, label %bb2
288
289bb2:
290  ret i32 %r1
291
292bb3:
293  ret i32 0
294}
295
296define i32 @test11(i32 %a, i32 %b, i1 %cond2) {
297; CHECK-LABEL: @test11(
298; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
299; CHECK-NEXT:    [[OR:%.*]] = or i1 [[COND]], [[COND2:%.*]]
300; CHECK-NEXT:    br i1 [[OR]], label [[BB1:%.*]], label [[BB3:%.*]]
301; CHECK:       bb1:
302; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
303; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
304; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
305; CHECK:       bb2:
306; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
307; CHECK-NEXT:    ret i32 [[R1]]
308; CHECK:       bb3:
309; CHECK-NEXT:    ret i32 0
310;
311  %cond = icmp ugt i32 %a, %b
312  %or = or i1 %cond, %cond2
313  br i1 %or, label %bb1, label %bb3
314
315bb1:
316  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
317  %r1 = extractvalue { i32, i1 } %sub1, 0
318  %c1 = extractvalue { i32, i1 } %sub1, 1
319  br i1 %c1, label %bb3, label %bb2
320
321bb2:
322  ret i32 %r1
323
324bb3:
325  ret i32 0
326}
327
328define i32 @test12(i32 %a, i32 %b, i1 %cond2) {
329; CHECK-LABEL: @test12(
330; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
331; CHECK-NEXT:    [[OR:%.*]] = or i1 [[COND]], [[COND2:%.*]]
332; CHECK-NEXT:    br i1 [[OR]], label [[BB3:%.*]], label [[BB1:%.*]]
333; CHECK:       bb1:
334; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
335; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
336; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
337; CHECK:       bb2:
338; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
339; CHECK-NEXT:    ret i32 [[R1]]
340; CHECK:       bb3:
341; CHECK-NEXT:    ret i32 0
342;
343  %cond = icmp ugt i32 %a, %b
344  %or = or i1 %cond, %cond2
345  br i1 %or, label %bb3, label %bb1
346
347bb1:
348  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
349  %r1 = extractvalue { i32, i1 } %sub1, 0
350  %c1 = extractvalue { i32, i1 } %sub1, 1
351  br i1 %c1, label %bb3, label %bb2
352
353bb2:
354  ret i32 %r1
355
356bb3:
357  ret i32 0
358}
359