1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
3 ; RUN: opt -passes=instcombine -S %s | FileCheck %s
5 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
7 define i32 @test1(i32 %a, i32 %b) {
9 ; CHECK-NEXT: [[COND_NOT:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
10 ; CHECK-NEXT: br i1 [[COND_NOT]], label [[BB3:%.*]], label [[BB1:%.*]]
12 ; CHECK-NEXT: br i1 false, label [[BB2:%.*]], label [[BB3]]
14 ; CHECK-NEXT: ret i32 poison
16 ; CHECK-NEXT: ret i32 0
18 %cond = icmp uge i32 %a, %b
19 br i1 %cond, label %bb1, label %bb3
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
34 define 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:%.*]]
39 ; CHECK-NEXT: br i1 false, label [[BB3]], label [[BB2:%.*]]
41 ; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
42 ; CHECK-NEXT: ret i32 [[SUB1]]
44 ; CHECK-NEXT: ret i32 0
46 %cond = icmp uge i32 %a, %b
47 br i1 %cond, label %bb1, label %bb3
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
63 define 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:%.*]]
68 ; CHECK-NEXT: br i1 false, label [[BB2:%.*]], label [[BB3]]
70 ; CHECK-NEXT: ret i32 poison
72 ; CHECK-NEXT: ret i32 0
74 %cond = icmp ugt i32 %a, %b
75 br i1 %cond, label %bb1, label %bb3
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
90 define 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:%.*]]
95 ; CHECK-NEXT: br i1 false, label [[BB3]], label [[BB2:%.*]]
97 ; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
98 ; CHECK-NEXT: ret i32 [[SUB1]]
100 ; CHECK-NEXT: ret i32 0
102 %cond = icmp ugt i32 %a, %b
103 br i1 %cond, label %bb1, label %bb3
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
119 define 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:%.*]]
124 ; CHECK-NEXT: br i1 false, label [[BB3]], label [[BB2:%.*]]
126 ; CHECK-NEXT: ret i32 0
128 ; CHECK-NEXT: ret i32 0
130 %cond = icmp eq i32 %a, %b
131 br i1 %cond, label %bb1, label %bb3
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
146 define 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:%.*]]
151 ; CHECK-NEXT: br i1 true, label [[BB3]], label [[BB2:%.*]]
153 ; CHECK-NEXT: ret i32 poison
155 ; CHECK-NEXT: ret i32 0
157 %cond = icmp ult i32 %a, %b
158 br i1 %cond, label %bb1, label %bb3
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
173 define 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:%.*]]
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:%.*]]
182 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
183 ; CHECK-NEXT: ret i32 [[R1]]
185 ; CHECK-NEXT: ret i32 0
187 %cond = icmp slt i32 %a, %b
188 br i1 %cond, label %bb1, label %bb3
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
203 define 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:%.*]]
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:%.*]]
212 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
213 ; CHECK-NEXT: ret i32 [[R1]]
215 ; CHECK-NEXT: ret i32 0
217 %cond = icmp ne i32 %a, %b
218 br i1 %cond, label %bb1, label %bb3
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
233 define 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:%.*]]
239 ; CHECK-NEXT: br i1 false, label [[BB3]], label [[BB2:%.*]]
241 ; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
242 ; CHECK-NEXT: ret i32 [[SUB1]]
244 ; CHECK-NEXT: ret i32 0
246 %cond = icmp ugt i32 %a, %b
247 %and = and i1 %cond, %cond2
248 br i1 %and, label %bb1, label %bb3
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
263 define 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:%.*]]
269 ; CHECK-NEXT: br i1 false, label [[BB3]], label [[BB2:%.*]]
271 ; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
272 ; CHECK-NEXT: ret i32 [[SUB1]]
274 ; CHECK-NEXT: ret i32 0
276 %cond = icmp ugt i32 %a, %b
277 %and = select i1 %cond, i1 %cond2, i1 false
278 br i1 %and, label %bb1, label %bb3
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
293 define 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:%.*]]
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:%.*]]
303 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
304 ; CHECK-NEXT: ret i32 [[R1]]
306 ; CHECK-NEXT: ret i32 0
308 %cond = icmp ugt i32 %a, %b
309 %and = and i1 %cond, %cond2
310 br i1 %and, label %bb3, label %bb1
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
325 define 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:%.*]]
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:%.*]]
335 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
336 ; CHECK-NEXT: ret i32 [[R1]]
338 ; CHECK-NEXT: ret i32 0
340 %cond = icmp ugt i32 %a, %b
341 %and = select i1 %cond, i1 %cond2, i1 false
342 br i1 %and, label %bb3, label %bb1
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
357 define 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:%.*]]
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:%.*]]
367 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
368 ; CHECK-NEXT: ret i32 [[R1]]
370 ; CHECK-NEXT: ret i32 0
372 %cond = icmp ugt i32 %a, %b
373 %or = or i1 %cond, %cond2
374 br i1 %or, label %bb1, label %bb3
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
389 define 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:%.*]]
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:%.*]]
399 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
400 ; CHECK-NEXT: ret i32 [[R1]]
402 ; CHECK-NEXT: ret i32 0
404 %cond = icmp ugt i32 %a, %b
405 %or = select i1 %cond, i1 true, i1 %cond2
406 br i1 %or, label %bb1, label %bb3
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
421 define 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:%.*]]
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:%.*]]
431 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
432 ; CHECK-NEXT: ret i32 [[R1]]
434 ; CHECK-NEXT: ret i32 0
436 %cond = icmp ugt i32 %a, %b
437 %or = or i1 %cond, %cond2
438 br i1 %or, label %bb3, label %bb1
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
453 define 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:%.*]]
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:%.*]]
463 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
464 ; CHECK-NEXT: ret i32 [[R1]]
466 ; CHECK-NEXT: ret i32 0
468 %cond = icmp ugt i32 %a, %b
469 %or = select i1 %cond, i1 true, i1 %cond2
470 br i1 %or, label %bb3, label %bb1
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