1*61bb2e4eSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2*61bb2e4eSFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3*61bb2e4eSFlorian Hahn 4*61bb2e4eSFlorian Hahndeclare { i8, i1 } @llvm.ssub.with.overflow.i8(i8, i8) 5*61bb2e4eSFlorian Hahn 6*61bb2e4eSFlorian Hahndefine i8 @ssub_no_overflow_due_to_or_conds(i8 %a, i8 %b) { 7*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_or_conds( 8*61bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 9*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sle i8 [[B:%.*]], [[A:%.*]] 10*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp slt i8 [[A]], 0 11*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_2]], [[C_1]] 12*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] 13*61bb2e4eSFlorian Hahn; CHECK: math: 14*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]]) 15*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 16*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 17*61bb2e4eSFlorian Hahn; CHECK: exit.ok: 18*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 19*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 20*61bb2e4eSFlorian Hahn; CHECK: exit.fail: 21*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 22*61bb2e4eSFlorian Hahn; 23*61bb2e4eSFlorian Hahnentry: 24*61bb2e4eSFlorian Hahn %c.1 = icmp sle i8 %b, %a 25*61bb2e4eSFlorian Hahn %c.2 = icmp slt i8 %a, 0 26*61bb2e4eSFlorian Hahn %or.cond = or i1 %c.2, %c.1 27*61bb2e4eSFlorian Hahn br i1 %or.cond, label %exit.fail, label %math 28*61bb2e4eSFlorian Hahn 29*61bb2e4eSFlorian Hahnmath: 30*61bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 31*61bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 32*61bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 33*61bb2e4eSFlorian Hahn 34*61bb2e4eSFlorian Hahnexit.ok: 35*61bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 36*61bb2e4eSFlorian Hahn ret i8 %res 37*61bb2e4eSFlorian Hahn 38*61bb2e4eSFlorian Hahnexit.fail: 39*61bb2e4eSFlorian Hahn ret i8 0 40*61bb2e4eSFlorian Hahn} 41*61bb2e4eSFlorian Hahn 42*61bb2e4eSFlorian Hahndefine i8 @ssub_no_overflow_due_to_and_conds(i8 %a, i8 %b) { 43*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_and_conds( 44*61bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 45*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]] 46*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[A]], 0 47*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_1]] 48*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 49*61bb2e4eSFlorian Hahn; CHECK: math: 50*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]]) 51*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 52*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 53*61bb2e4eSFlorian Hahn; CHECK: exit.ok: 54*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 55*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 56*61bb2e4eSFlorian Hahn; CHECK: exit.fail: 57*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 58*61bb2e4eSFlorian Hahn; 59*61bb2e4eSFlorian Hahnentry: 60*61bb2e4eSFlorian Hahn %c.1 = icmp sge i8 %b, %a 61*61bb2e4eSFlorian Hahn %c.2 = icmp sge i8 %a, 0 62*61bb2e4eSFlorian Hahn %and = and i1 %c.2, %c.1 63*61bb2e4eSFlorian Hahn br i1 %and, label %math, label %exit.fail 64*61bb2e4eSFlorian Hahn 65*61bb2e4eSFlorian Hahnmath: 66*61bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 67*61bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 68*61bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 69*61bb2e4eSFlorian Hahn 70*61bb2e4eSFlorian Hahnexit.ok: 71*61bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 72*61bb2e4eSFlorian Hahn ret i8 %res 73*61bb2e4eSFlorian Hahn 74*61bb2e4eSFlorian Hahnexit.fail: 75*61bb2e4eSFlorian Hahn ret i8 0 76*61bb2e4eSFlorian Hahn} 77*61bb2e4eSFlorian Hahn 78*61bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow1(i8 %a, i8 %b) { 79*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow1( 80*61bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 81*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]] 82*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 83*61bb2e4eSFlorian Hahn; CHECK: math: 84*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]]) 85*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 86*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 87*61bb2e4eSFlorian Hahn; CHECK: exit.ok: 88*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 89*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 90*61bb2e4eSFlorian Hahn; CHECK: exit.fail: 91*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 92*61bb2e4eSFlorian Hahn; 93*61bb2e4eSFlorian Hahnentry: 94*61bb2e4eSFlorian Hahn %c.1 = icmp sge i8 %b, %a 95*61bb2e4eSFlorian Hahn br i1 %c.1, label %math, label %exit.fail 96*61bb2e4eSFlorian Hahn 97*61bb2e4eSFlorian Hahnmath: 98*61bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 99*61bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 100*61bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 101*61bb2e4eSFlorian Hahn 102*61bb2e4eSFlorian Hahnexit.ok: 103*61bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 104*61bb2e4eSFlorian Hahn ret i8 %res 105*61bb2e4eSFlorian Hahn 106*61bb2e4eSFlorian Hahnexit.fail: 107*61bb2e4eSFlorian Hahn ret i8 0 108*61bb2e4eSFlorian Hahn} 109*61bb2e4eSFlorian Hahn 110*61bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow2(i8 %a, i8 %b) { 111*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow2( 112*61bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 113*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[A:%.*]], 0 114*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 115*61bb2e4eSFlorian Hahn; CHECK: math: 116*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B:%.*]], i8 [[A]]) 117*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 118*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 119*61bb2e4eSFlorian Hahn; CHECK: exit.ok: 120*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 121*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 122*61bb2e4eSFlorian Hahn; CHECK: exit.fail: 123*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 124*61bb2e4eSFlorian Hahn; 125*61bb2e4eSFlorian Hahnentry: 126*61bb2e4eSFlorian Hahn %c.1 = icmp sge i8 %a, 0 127*61bb2e4eSFlorian Hahn br i1 %c.1, label %math, label %exit.fail 128*61bb2e4eSFlorian Hahn 129*61bb2e4eSFlorian Hahnmath: 130*61bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 131*61bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 132*61bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 133*61bb2e4eSFlorian Hahn 134*61bb2e4eSFlorian Hahnexit.ok: 135*61bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 136*61bb2e4eSFlorian Hahn ret i8 %res 137*61bb2e4eSFlorian Hahn 138*61bb2e4eSFlorian Hahnexit.fail: 139*61bb2e4eSFlorian Hahn ret i8 0 140*61bb2e4eSFlorian Hahn} 141*61bb2e4eSFlorian Hahn 142*61bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow3(i8 %a, i8 %b) { 143*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow3( 144*61bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 145*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]] 146*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[A]], -1 147*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_1]] 148*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 149*61bb2e4eSFlorian Hahn; CHECK: math: 150*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]]) 151*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 152*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 153*61bb2e4eSFlorian Hahn; CHECK: exit.ok: 154*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 155*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 156*61bb2e4eSFlorian Hahn; CHECK: exit.fail: 157*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 158*61bb2e4eSFlorian Hahn; 159*61bb2e4eSFlorian Hahnentry: 160*61bb2e4eSFlorian Hahn %c.1 = icmp sge i8 %b, %a 161*61bb2e4eSFlorian Hahn %c.2 = icmp sge i8 %a, -1 162*61bb2e4eSFlorian Hahn %and = and i1 %c.2, %c.1 163*61bb2e4eSFlorian Hahn br i1 %and, label %math, label %exit.fail 164*61bb2e4eSFlorian Hahn 165*61bb2e4eSFlorian Hahnmath: 166*61bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 167*61bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 168*61bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 169*61bb2e4eSFlorian Hahn 170*61bb2e4eSFlorian Hahnexit.ok: 171*61bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 172*61bb2e4eSFlorian Hahn ret i8 %res 173*61bb2e4eSFlorian Hahn 174*61bb2e4eSFlorian Hahnexit.fail: 175*61bb2e4eSFlorian Hahn ret i8 0 176*61bb2e4eSFlorian Hahn} 177*61bb2e4eSFlorian Hahn 178*61bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow4(i8 %a, i8 %b) { 179*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow4( 180*61bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 181*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]] 182*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[A]], 0 183*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_1]] 184*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 185*61bb2e4eSFlorian Hahn; CHECK: math: 186*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]]) 187*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 188*61bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 189*61bb2e4eSFlorian Hahn; CHECK: exit.ok: 190*61bb2e4eSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 191*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 192*61bb2e4eSFlorian Hahn; CHECK: exit.fail: 193*61bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 194*61bb2e4eSFlorian Hahn; 195*61bb2e4eSFlorian Hahnentry: 196*61bb2e4eSFlorian Hahn %c.1 = icmp uge i8 %b, %a 197*61bb2e4eSFlorian Hahn %c.2 = icmp sge i8 %a, 0 198*61bb2e4eSFlorian Hahn %and = and i1 %c.2, %c.1 199*61bb2e4eSFlorian Hahn br i1 %and, label %math, label %exit.fail 200*61bb2e4eSFlorian Hahn 201*61bb2e4eSFlorian Hahnmath: 202*61bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 203*61bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 204*61bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 205*61bb2e4eSFlorian Hahn 206*61bb2e4eSFlorian Hahnexit.ok: 207*61bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 208*61bb2e4eSFlorian Hahn ret i8 %res 209*61bb2e4eSFlorian Hahn 210*61bb2e4eSFlorian Hahnexit.fail: 211*61bb2e4eSFlorian Hahn ret i8 0 212*61bb2e4eSFlorian Hahn} 213