1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i64) 5declare { i8, i1 } @llvm.uadd.with.overflow.i8(i8, i8) 6 7define i1 @test_generic(i64 %a, i64 %b) { 8; CHECK-LABEL: @test_generic( 9; CHECK-NEXT: [[RES:%.*]] = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]) 10; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i64, i1 } [[RES]], 1 11; CHECK-NEXT: ret i1 [[OVERFLOW]] 12; 13 %res = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b) 14 %overflow = extractvalue { i64, i1 } %res, 1 15 ret i1 %overflow 16} 17 18define i1 @test_constant0(i8 %a) { 19; CHECK-LABEL: @test_constant0( 20; CHECK-NEXT: ret i1 false 21; 22 %res = tail call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 0) 23 %overflow = extractvalue { i8, i1 } %res, 1 24 ret i1 %overflow 25} 26 27define i1 @test_constant1(i8 %a) { 28; CHECK-LABEL: @test_constant1( 29; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], -1 30; CHECK-NEXT: ret i1 [[OVERFLOW]] 31; 32 %res = tail call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 1) 33 %overflow = extractvalue { i8, i1 } %res, 1 34 ret i1 %overflow 35} 36 37define i1 @test_constant2(i8 %a) { 38; CHECK-LABEL: @test_constant2( 39; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[A:%.*]], -3 40; CHECK-NEXT: ret i1 [[OVERFLOW]] 41; 42 %res = tail call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 2) 43 %overflow = extractvalue { i8, i1 } %res, 1 44 ret i1 %overflow 45} 46 47define i1 @test_constant3(i8 %a) { 48; CHECK-LABEL: @test_constant3( 49; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[A:%.*]], -4 50; CHECK-NEXT: ret i1 [[OVERFLOW]] 51; 52 %res = tail call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 3) 53 %overflow = extractvalue { i8, i1 } %res, 1 54 ret i1 %overflow 55} 56 57define i1 @test_constant4(i8 %a) { 58; CHECK-LABEL: @test_constant4( 59; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[A:%.*]], -5 60; CHECK-NEXT: ret i1 [[OVERFLOW]] 61; 62 %res = tail call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 4) 63 %overflow = extractvalue { i8, i1 } %res, 1 64 ret i1 %overflow 65} 66 67 68define i1 @test_constant127(i8 %a) { 69; CHECK-LABEL: @test_constant127( 70; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[A:%.*]], -128 71; CHECK-NEXT: ret i1 [[OVERFLOW]] 72; 73 %res = tail call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 127) 74 %overflow = extractvalue { i8, i1 } %res, 1 75 ret i1 %overflow 76} 77 78define i1 @test_constant128(i8 %a) { 79; CHECK-LABEL: @test_constant128( 80; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], 0 81; CHECK-NEXT: ret i1 [[OVERFLOW]] 82; 83 %res = tail call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 128) 84 %overflow = extractvalue { i8, i1 } %res, 1 85 ret i1 %overflow 86} 87 88define i1 @test_constant255(i8 %a) { 89; CHECK-LABEL: @test_constant255( 90; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ne i8 [[A:%.*]], 0 91; CHECK-NEXT: ret i1 [[OVERFLOW]] 92; 93 %res = tail call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 255) 94 %overflow = extractvalue { i8, i1 } %res, 1 95 ret i1 %overflow 96} 97 98