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 undef
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 undef
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: [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
127 ; CHECK-NEXT: ret i32 [[SUB1]]
129 ; CHECK-NEXT: ret i32 0
131 %cond = icmp eq i32 %a, %b
132 br i1 %cond, label %bb1, label %bb3
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
147 define 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:%.*]]
152 ; CHECK-NEXT: br i1 true, label [[BB3]], label [[BB2:%.*]]
154 ; CHECK-NEXT: ret i32 undef
156 ; CHECK-NEXT: ret i32 0
158 %cond = icmp ult i32 %a, %b
159 br i1 %cond, label %bb1, label %bb3
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
174 define 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:%.*]]
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:%.*]]
183 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
184 ; CHECK-NEXT: ret i32 [[R1]]
186 ; CHECK-NEXT: ret i32 0
188 %cond = icmp slt i32 %a, %b
189 br i1 %cond, label %bb1, label %bb3
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
204 define i32 @test8(i32 %a, i32 %b) {
205 ; CHECK-LABEL: @test8(
206 ; CHECK-NEXT: [[COND_NOT:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
207 ; CHECK-NEXT: br i1 [[COND_NOT]], label [[BB3:%.*]], label [[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:%.*]]
213 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
214 ; CHECK-NEXT: ret i32 [[R1]]
216 ; CHECK-NEXT: ret i32 0
218 %cond = icmp ne i32 %a, %b
219 br i1 %cond, label %bb1, label %bb3
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
234 define 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:%.*]]
240 ; CHECK-NEXT: br i1 false, label [[BB3]], label [[BB2:%.*]]
242 ; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
243 ; CHECK-NEXT: ret i32 [[SUB1]]
245 ; CHECK-NEXT: ret i32 0
247 %cond = icmp ugt i32 %a, %b
248 %and = and i1 %cond, %cond2
249 br i1 %and, label %bb1, label %bb3
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
264 define i32 @test9_logical(i32 %a, i32 %b, i1 %cond2) {
265 ; CHECK-LABEL: @test9_logical(
266 ; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
267 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[COND]], i1 [[COND2:%.*]], i1 false
268 ; CHECK-NEXT: br i1 [[AND]], label [[BB1:%.*]], label [[BB3:%.*]]
270 ; CHECK-NEXT: br i1 false, label [[BB3]], label [[BB2:%.*]]
272 ; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
273 ; CHECK-NEXT: ret i32 [[SUB1]]
275 ; CHECK-NEXT: ret i32 0
277 %cond = icmp ugt i32 %a, %b
278 %and = select i1 %cond, i1 %cond2, i1 false
279 br i1 %and, label %bb1, label %bb3
282 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
283 %r1 = extractvalue { i32, i1 } %sub1, 0
284 %c1 = extractvalue { i32, i1 } %sub1, 1
285 br i1 %c1, label %bb3, label %bb2
294 define i32 @test10(i32 %a, i32 %b, i1 %cond2) {
295 ; CHECK-LABEL: @test10(
296 ; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
297 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND]], [[COND2:%.*]]
298 ; CHECK-NEXT: br i1 [[AND]], label [[BB3:%.*]], label [[BB1:%.*]]
300 ; CHECK-NEXT: [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
301 ; CHECK-NEXT: [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
302 ; CHECK-NEXT: br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
304 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
305 ; CHECK-NEXT: ret i32 [[R1]]
307 ; CHECK-NEXT: ret i32 0
309 %cond = icmp ugt i32 %a, %b
310 %and = and i1 %cond, %cond2
311 br i1 %and, label %bb3, label %bb1
314 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
315 %r1 = extractvalue { i32, i1 } %sub1, 0
316 %c1 = extractvalue { i32, i1 } %sub1, 1
317 br i1 %c1, label %bb3, label %bb2
326 define i32 @test10_logical(i32 %a, i32 %b, i1 %cond2) {
327 ; CHECK-LABEL: @test10_logical(
328 ; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
329 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[COND]], i1 [[COND2:%.*]], i1 false
330 ; CHECK-NEXT: br i1 [[AND]], label [[BB3:%.*]], label [[BB1:%.*]]
332 ; CHECK-NEXT: [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
333 ; CHECK-NEXT: [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
334 ; CHECK-NEXT: br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
336 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
337 ; CHECK-NEXT: ret i32 [[R1]]
339 ; CHECK-NEXT: ret i32 0
341 %cond = icmp ugt i32 %a, %b
342 %and = select i1 %cond, i1 %cond2, i1 false
343 br i1 %and, label %bb3, label %bb1
346 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
347 %r1 = extractvalue { i32, i1 } %sub1, 0
348 %c1 = extractvalue { i32, i1 } %sub1, 1
349 br i1 %c1, label %bb3, label %bb2
358 define i32 @test11(i32 %a, i32 %b, i1 %cond2) {
359 ; CHECK-LABEL: @test11(
360 ; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
361 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[COND]], [[COND2:%.*]]
362 ; CHECK-NEXT: br i1 [[OR]], label [[BB1:%.*]], label [[BB3:%.*]]
364 ; CHECK-NEXT: [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
365 ; CHECK-NEXT: [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
366 ; CHECK-NEXT: br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
368 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
369 ; CHECK-NEXT: ret i32 [[R1]]
371 ; CHECK-NEXT: ret i32 0
373 %cond = icmp ugt i32 %a, %b
374 %or = or i1 %cond, %cond2
375 br i1 %or, label %bb1, label %bb3
378 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
379 %r1 = extractvalue { i32, i1 } %sub1, 0
380 %c1 = extractvalue { i32, i1 } %sub1, 1
381 br i1 %c1, label %bb3, label %bb2
390 define i32 @test11_logical(i32 %a, i32 %b, i1 %cond2) {
391 ; CHECK-LABEL: @test11_logical(
392 ; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
393 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[COND]], i1 true, i1 [[COND2:%.*]]
394 ; CHECK-NEXT: br i1 [[OR]], label [[BB1:%.*]], label [[BB3:%.*]]
396 ; CHECK-NEXT: [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
397 ; CHECK-NEXT: [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
398 ; CHECK-NEXT: br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
400 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
401 ; CHECK-NEXT: ret i32 [[R1]]
403 ; CHECK-NEXT: ret i32 0
405 %cond = icmp ugt i32 %a, %b
406 %or = select i1 %cond, i1 true, i1 %cond2
407 br i1 %or, label %bb1, label %bb3
410 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
411 %r1 = extractvalue { i32, i1 } %sub1, 0
412 %c1 = extractvalue { i32, i1 } %sub1, 1
413 br i1 %c1, label %bb3, label %bb2
422 define i32 @test12(i32 %a, i32 %b, i1 %cond2) {
423 ; CHECK-LABEL: @test12(
424 ; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
425 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[COND]], [[COND2:%.*]]
426 ; CHECK-NEXT: br i1 [[OR]], label [[BB3:%.*]], label [[BB1:%.*]]
428 ; CHECK-NEXT: [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
429 ; CHECK-NEXT: [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
430 ; CHECK-NEXT: br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
432 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
433 ; CHECK-NEXT: ret i32 [[R1]]
435 ; CHECK-NEXT: ret i32 0
437 %cond = icmp ugt i32 %a, %b
438 %or = or i1 %cond, %cond2
439 br i1 %or, label %bb3, label %bb1
442 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
443 %r1 = extractvalue { i32, i1 } %sub1, 0
444 %c1 = extractvalue { i32, i1 } %sub1, 1
445 br i1 %c1, label %bb3, label %bb2
454 define i32 @test12_logical(i32 %a, i32 %b, i1 %cond2) {
455 ; CHECK-LABEL: @test12_logical(
456 ; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
457 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[COND]], i1 true, i1 [[COND2:%.*]]
458 ; CHECK-NEXT: br i1 [[OR]], label [[BB3:%.*]], label [[BB1:%.*]]
460 ; CHECK-NEXT: [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
461 ; CHECK-NEXT: [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
462 ; CHECK-NEXT: br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
464 ; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
465 ; CHECK-NEXT: ret i32 [[R1]]
467 ; CHECK-NEXT: ret i32 0
469 %cond = icmp ugt i32 %a, %b
470 %or = select i1 %cond, i1 true, i1 %cond2
471 br i1 %or, label %bb3, label %bb1
474 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
475 %r1 = extractvalue { i32, i1 } %sub1, 0
476 %c1 = extractvalue { i32, i1 } %sub1, 1
477 br i1 %c1, label %bb3, label %bb2