161bb2e4eSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 261bb2e4eSFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 361bb2e4eSFlorian Hahn 461bb2e4eSFlorian Hahndeclare { i8, i1 } @llvm.ssub.with.overflow.i8(i8, i8) 561bb2e4eSFlorian Hahn 661bb2e4eSFlorian Hahndefine i8 @ssub_no_overflow_due_to_or_conds(i8 %a, i8 %b) { 761bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_or_conds( 861bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 961bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sle i8 [[B:%.*]], [[A:%.*]] 1061bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp slt i8 [[A]], 0 1161bb2e4eSFlorian Hahn; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_2]], [[C_1]] 1261bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] 1361bb2e4eSFlorian Hahn; CHECK: math: 14*8e6d481fSFlorian Hahn; CHECK-NEXT: [[TMP0:%.*]] = sub i8 [[B]], [[A]] 15*8e6d481fSFlorian Hahn; CHECK-NEXT: br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 1661bb2e4eSFlorian Hahn; CHECK: exit.ok: 17*8e6d481fSFlorian Hahn; CHECK-NEXT: ret i8 [[TMP0]] 1861bb2e4eSFlorian Hahn; CHECK: exit.fail: 1961bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 2061bb2e4eSFlorian Hahn; 2161bb2e4eSFlorian Hahnentry: 2261bb2e4eSFlorian Hahn %c.1 = icmp sle i8 %b, %a 2361bb2e4eSFlorian Hahn %c.2 = icmp slt i8 %a, 0 2461bb2e4eSFlorian Hahn %or.cond = or i1 %c.2, %c.1 2561bb2e4eSFlorian Hahn br i1 %or.cond, label %exit.fail, label %math 2661bb2e4eSFlorian Hahn 2761bb2e4eSFlorian Hahnmath: 2861bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 2961bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 3061bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 3161bb2e4eSFlorian Hahn 3261bb2e4eSFlorian Hahnexit.ok: 3361bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 3461bb2e4eSFlorian Hahn ret i8 %res 3561bb2e4eSFlorian Hahn 3661bb2e4eSFlorian Hahnexit.fail: 3761bb2e4eSFlorian Hahn ret i8 0 3861bb2e4eSFlorian Hahn} 3961bb2e4eSFlorian Hahn 40301fe084SFlorian Hahndeclare void @use_res({ i8, i1 }) 41301fe084SFlorian Hahn 42301fe084SFlorian Hahndefine i8 @ssub_no_overflow_due_to_or_conds_result_used(i8 %a, i8 %b) { 43301fe084SFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_or_conds_result_used( 44301fe084SFlorian Hahn; CHECK-NEXT: entry: 45301fe084SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sle i8 [[B:%.*]], [[A:%.*]] 46301fe084SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp slt i8 [[A]], 0 47301fe084SFlorian Hahn; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_2]], [[C_1]] 48301fe084SFlorian Hahn; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] 49301fe084SFlorian Hahn; CHECK: math: 50*8e6d481fSFlorian Hahn; CHECK-NEXT: [[TMP0:%.*]] = sub i8 [[B]], [[A]] 51301fe084SFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]]) 52301fe084SFlorian Hahn; CHECK-NEXT: call void @use_res({ i8, i1 } [[OP]]) 53*8e6d481fSFlorian Hahn; CHECK-NEXT: br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 54301fe084SFlorian Hahn; CHECK: exit.ok: 55*8e6d481fSFlorian Hahn; CHECK-NEXT: ret i8 [[TMP0]] 56301fe084SFlorian Hahn; CHECK: exit.fail: 57301fe084SFlorian Hahn; CHECK-NEXT: ret i8 0 58301fe084SFlorian Hahn; 59301fe084SFlorian Hahnentry: 60301fe084SFlorian Hahn %c.1 = icmp sle i8 %b, %a 61301fe084SFlorian Hahn %c.2 = icmp slt i8 %a, 0 62301fe084SFlorian Hahn %or.cond = or i1 %c.2, %c.1 63301fe084SFlorian Hahn br i1 %or.cond, label %exit.fail, label %math 64301fe084SFlorian Hahn 65301fe084SFlorian Hahnmath: 66301fe084SFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 67301fe084SFlorian Hahn call void @use_res({ i8, i1 } %op) 68301fe084SFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 69301fe084SFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 70301fe084SFlorian Hahn 71301fe084SFlorian Hahnexit.ok: 72301fe084SFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 73301fe084SFlorian Hahn ret i8 %res 74301fe084SFlorian Hahn 75301fe084SFlorian Hahnexit.fail: 76301fe084SFlorian Hahn ret i8 0 77301fe084SFlorian Hahn} 78301fe084SFlorian Hahn 7961bb2e4eSFlorian Hahndefine i8 @ssub_no_overflow_due_to_and_conds(i8 %a, i8 %b) { 8061bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_and_conds( 8161bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 8261bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]] 8361bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[A]], 0 8461bb2e4eSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_1]] 8561bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 8661bb2e4eSFlorian Hahn; CHECK: math: 87*8e6d481fSFlorian Hahn; CHECK-NEXT: [[TMP0:%.*]] = sub i8 [[B]], [[A]] 88*8e6d481fSFlorian Hahn; CHECK-NEXT: br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 8961bb2e4eSFlorian Hahn; CHECK: exit.ok: 90*8e6d481fSFlorian Hahn; CHECK-NEXT: ret i8 [[TMP0]] 9161bb2e4eSFlorian Hahn; CHECK: exit.fail: 9261bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 9361bb2e4eSFlorian Hahn; 9461bb2e4eSFlorian Hahnentry: 9561bb2e4eSFlorian Hahn %c.1 = icmp sge i8 %b, %a 9661bb2e4eSFlorian Hahn %c.2 = icmp sge i8 %a, 0 9761bb2e4eSFlorian Hahn %and = and i1 %c.2, %c.1 9861bb2e4eSFlorian Hahn br i1 %and, label %math, label %exit.fail 9961bb2e4eSFlorian Hahn 10061bb2e4eSFlorian Hahnmath: 10161bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 10261bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 10361bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 10461bb2e4eSFlorian Hahn 10561bb2e4eSFlorian Hahnexit.ok: 10661bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 10761bb2e4eSFlorian Hahn ret i8 %res 10861bb2e4eSFlorian Hahn 10961bb2e4eSFlorian Hahnexit.fail: 11061bb2e4eSFlorian Hahn ret i8 0 11161bb2e4eSFlorian Hahn} 11261bb2e4eSFlorian Hahn 113301fe084SFlorian Hahndefine i8 @ssub_no_overflow_due_to_and_conds_sub_result_not_used(i8 %a, i8 %b) { 114301fe084SFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_and_conds_sub_result_not_used( 115301fe084SFlorian Hahn; CHECK-NEXT: entry: 116301fe084SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]] 117301fe084SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[A]], 0 118301fe084SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_1]] 119301fe084SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 120301fe084SFlorian Hahn; CHECK: math: 121*8e6d481fSFlorian Hahn; CHECK-NEXT: br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 122301fe084SFlorian Hahn; CHECK: exit.ok: 123301fe084SFlorian Hahn; CHECK-NEXT: ret i8 20 124301fe084SFlorian Hahn; CHECK: exit.fail: 125301fe084SFlorian Hahn; CHECK-NEXT: ret i8 0 126301fe084SFlorian Hahn; 127301fe084SFlorian Hahnentry: 128301fe084SFlorian Hahn %c.1 = icmp sge i8 %b, %a 129301fe084SFlorian Hahn %c.2 = icmp sge i8 %a, 0 130301fe084SFlorian Hahn %and = and i1 %c.2, %c.1 131301fe084SFlorian Hahn br i1 %and, label %math, label %exit.fail 132301fe084SFlorian Hahn 133301fe084SFlorian Hahnmath: 134301fe084SFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 135301fe084SFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 136301fe084SFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 137301fe084SFlorian Hahn 138301fe084SFlorian Hahnexit.ok: 139301fe084SFlorian Hahn ret i8 20 140301fe084SFlorian Hahn 141301fe084SFlorian Hahnexit.fail: 142301fe084SFlorian Hahn ret i8 0 143301fe084SFlorian Hahn} 144301fe084SFlorian Hahn 14561bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow1(i8 %a, i8 %b) { 14661bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow1( 14761bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 14861bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]] 14961bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 15061bb2e4eSFlorian Hahn; CHECK: math: 15161bb2e4eSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]]) 15261bb2e4eSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 15361bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 15461bb2e4eSFlorian Hahn; CHECK: exit.ok: 15561bb2e4eSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 15661bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 15761bb2e4eSFlorian Hahn; CHECK: exit.fail: 15861bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 15961bb2e4eSFlorian Hahn; 16061bb2e4eSFlorian Hahnentry: 16161bb2e4eSFlorian Hahn %c.1 = icmp sge i8 %b, %a 16261bb2e4eSFlorian Hahn br i1 %c.1, label %math, label %exit.fail 16361bb2e4eSFlorian Hahn 16461bb2e4eSFlorian Hahnmath: 16561bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 16661bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 16761bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 16861bb2e4eSFlorian Hahn 16961bb2e4eSFlorian Hahnexit.ok: 17061bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 17161bb2e4eSFlorian Hahn ret i8 %res 17261bb2e4eSFlorian Hahn 17361bb2e4eSFlorian Hahnexit.fail: 17461bb2e4eSFlorian Hahn ret i8 0 17561bb2e4eSFlorian Hahn} 17661bb2e4eSFlorian Hahn 17761bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow2(i8 %a, i8 %b) { 17861bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow2( 17961bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 18061bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[A:%.*]], 0 18161bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 18261bb2e4eSFlorian Hahn; CHECK: math: 18361bb2e4eSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B:%.*]], i8 [[A]]) 18461bb2e4eSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 18561bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 18661bb2e4eSFlorian Hahn; CHECK: exit.ok: 18761bb2e4eSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 18861bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 18961bb2e4eSFlorian Hahn; CHECK: exit.fail: 19061bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 19161bb2e4eSFlorian Hahn; 19261bb2e4eSFlorian Hahnentry: 19361bb2e4eSFlorian Hahn %c.1 = icmp sge i8 %a, 0 19461bb2e4eSFlorian Hahn br i1 %c.1, label %math, label %exit.fail 19561bb2e4eSFlorian Hahn 19661bb2e4eSFlorian Hahnmath: 19761bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 19861bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 19961bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 20061bb2e4eSFlorian Hahn 20161bb2e4eSFlorian Hahnexit.ok: 20261bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 20361bb2e4eSFlorian Hahn ret i8 %res 20461bb2e4eSFlorian Hahn 20561bb2e4eSFlorian Hahnexit.fail: 20661bb2e4eSFlorian Hahn ret i8 0 20761bb2e4eSFlorian Hahn} 20861bb2e4eSFlorian Hahn 20961bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow3(i8 %a, i8 %b) { 21061bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow3( 21161bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 21261bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]] 21361bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[A]], -1 21461bb2e4eSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_1]] 21561bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 21661bb2e4eSFlorian Hahn; CHECK: math: 21761bb2e4eSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]]) 21861bb2e4eSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 21961bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 22061bb2e4eSFlorian Hahn; CHECK: exit.ok: 22161bb2e4eSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 22261bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 22361bb2e4eSFlorian Hahn; CHECK: exit.fail: 22461bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 22561bb2e4eSFlorian Hahn; 22661bb2e4eSFlorian Hahnentry: 22761bb2e4eSFlorian Hahn %c.1 = icmp sge i8 %b, %a 22861bb2e4eSFlorian Hahn %c.2 = icmp sge i8 %a, -1 22961bb2e4eSFlorian Hahn %and = and i1 %c.2, %c.1 23061bb2e4eSFlorian Hahn br i1 %and, label %math, label %exit.fail 23161bb2e4eSFlorian Hahn 23261bb2e4eSFlorian Hahnmath: 23361bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 23461bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 23561bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 23661bb2e4eSFlorian Hahn 23761bb2e4eSFlorian Hahnexit.ok: 23861bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 23961bb2e4eSFlorian Hahn ret i8 %res 24061bb2e4eSFlorian Hahn 24161bb2e4eSFlorian Hahnexit.fail: 24261bb2e4eSFlorian Hahn ret i8 0 24361bb2e4eSFlorian Hahn} 24461bb2e4eSFlorian Hahn 24561bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow4(i8 %a, i8 %b) { 24661bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow4( 24761bb2e4eSFlorian Hahn; CHECK-NEXT: entry: 24861bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]] 24961bb2e4eSFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[A]], 0 25061bb2e4eSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_1]] 25161bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 25261bb2e4eSFlorian Hahn; CHECK: math: 25361bb2e4eSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]]) 25461bb2e4eSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 25561bb2e4eSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 25661bb2e4eSFlorian Hahn; CHECK: exit.ok: 25761bb2e4eSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 25861bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 25961bb2e4eSFlorian Hahn; CHECK: exit.fail: 26061bb2e4eSFlorian Hahn; CHECK-NEXT: ret i8 0 26161bb2e4eSFlorian Hahn; 26261bb2e4eSFlorian Hahnentry: 26361bb2e4eSFlorian Hahn %c.1 = icmp uge i8 %b, %a 26461bb2e4eSFlorian Hahn %c.2 = icmp sge i8 %a, 0 26561bb2e4eSFlorian Hahn %and = and i1 %c.2, %c.1 26661bb2e4eSFlorian Hahn br i1 %and, label %math, label %exit.fail 26761bb2e4eSFlorian Hahn 26861bb2e4eSFlorian Hahnmath: 26961bb2e4eSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 27061bb2e4eSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 27161bb2e4eSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 27261bb2e4eSFlorian Hahn 27361bb2e4eSFlorian Hahnexit.ok: 27461bb2e4eSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 27561bb2e4eSFlorian Hahn ret i8 %res 27661bb2e4eSFlorian Hahn 27761bb2e4eSFlorian Hahnexit.fail: 27861bb2e4eSFlorian Hahn ret i8 0 27961bb2e4eSFlorian Hahn} 2801911843cSFlorian Hahn 2811911843cSFlorian Hahndefine i8 @ssub_may_overflow5(i8 %a, i8 %b) { 2821911843cSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow5( 2831911843cSFlorian Hahn; CHECK-NEXT: entry: 2841911843cSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]] 2851911843cSFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[B]], 0 2861911843cSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_1]] 2871911843cSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] 2881911843cSFlorian Hahn; CHECK: math: 2891911843cSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]]) 2901911843cSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 2911911843cSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 2921911843cSFlorian Hahn; CHECK: exit.ok: 2931911843cSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 2941911843cSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 2951911843cSFlorian Hahn; CHECK: exit.fail: 2961911843cSFlorian Hahn; CHECK-NEXT: ret i8 0 2971911843cSFlorian Hahn; 2981911843cSFlorian Hahnentry: 2991911843cSFlorian Hahn %c.1 = icmp sge i8 %b, %a 3001911843cSFlorian Hahn %c.2 = icmp sge i8 %b, 0 3011911843cSFlorian Hahn %and = and i1 %c.2, %c.1 3021911843cSFlorian Hahn br i1 %and, label %math, label %exit.fail 3031911843cSFlorian Hahn 3041911843cSFlorian Hahnmath: 3051911843cSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 3061911843cSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 3071911843cSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 3081911843cSFlorian Hahn 3091911843cSFlorian Hahnexit.ok: 3101911843cSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 3111911843cSFlorian Hahn ret i8 %res 3121911843cSFlorian Hahn 3131911843cSFlorian Hahnexit.fail: 3141911843cSFlorian Hahn ret i8 0 3151911843cSFlorian Hahn} 3161911843cSFlorian Hahn 3171911843cSFlorian Hahndefine i8 @ssub_may_overflow6(i8 %a, i8 %b) { 3181911843cSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow6( 3191911843cSFlorian Hahn; CHECK-NEXT: entry: 3201911843cSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp sle i8 [[B:%.*]], [[A:%.*]] 3211911843cSFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp slt i8 [[B]], 0 3221911843cSFlorian Hahn; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_2]], [[C_1]] 3231911843cSFlorian Hahn; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] 3241911843cSFlorian Hahn; CHECK: math: 3251911843cSFlorian Hahn; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]]) 3261911843cSFlorian Hahn; CHECK-NEXT: [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 3271911843cSFlorian Hahn; CHECK-NEXT: br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] 3281911843cSFlorian Hahn; CHECK: exit.ok: 3291911843cSFlorian Hahn; CHECK-NEXT: [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 3301911843cSFlorian Hahn; CHECK-NEXT: ret i8 [[RES]] 3311911843cSFlorian Hahn; CHECK: exit.fail: 3321911843cSFlorian Hahn; CHECK-NEXT: ret i8 0 3331911843cSFlorian Hahn; 3341911843cSFlorian Hahnentry: 3351911843cSFlorian Hahn %c.1 = icmp sle i8 %b, %a 3361911843cSFlorian Hahn %c.2 = icmp slt i8 %b, 0 3371911843cSFlorian Hahn %or.cond = or i1 %c.2, %c.1 3381911843cSFlorian Hahn br i1 %or.cond, label %exit.fail, label %math 3391911843cSFlorian Hahn 3401911843cSFlorian Hahnmath: 3411911843cSFlorian Hahn %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a) 3421911843cSFlorian Hahn %status = extractvalue { i8, i1 } %op, 1 3431911843cSFlorian Hahn br i1 %status, label %exit.fail, label %exit.ok 3441911843cSFlorian Hahn 3451911843cSFlorian Hahnexit.ok: 3461911843cSFlorian Hahn %res = extractvalue { i8, i1 } %op, 0 3471911843cSFlorian Hahn ret i8 %res 3481911843cSFlorian Hahn 3491911843cSFlorian Hahnexit.fail: 3501911843cSFlorian Hahn ret i8 0 3511911843cSFlorian Hahn} 352