mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[instcombine] Fold overflow check using overflow intrinsic to comparison
This follows up to D104665 (which added umulo handling alongside the existing uaddo case), and generalizes for the remaining overflow intrinsics. I went to add analogous handling to LVI, and discovered that LVI already had a more general implementation. Instead, we can port was LVI does to instcombine. (For context, LVI uses makeExactNoWrapRegion to constrain the value 'x' in blocks reached after a branch on the condition `op.with.overflow(x, C).overflow`.) Differential Revision: https://reviews.llvm.org/D104932
This commit is contained in:
parent
6203a57d08
commit
ade0ec7fb0
@ -3089,33 +3089,32 @@ Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
|
||||
assert(*EV.idx_begin() == 1 &&
|
||||
"unexpected extract index for overflow inst");
|
||||
|
||||
// If the normal result of the computation is dead, and the RHS is a
|
||||
// constant, we can transform this into a range comparison for many cases.
|
||||
// TODO: We can generalize these for non-constant rhs when the newly
|
||||
// formed expressions are known to simplify. Constants are merely one
|
||||
// such case.
|
||||
// TODO: Handle vector splats.
|
||||
switch (WO->getIntrinsicID()) {
|
||||
default:
|
||||
break;
|
||||
case Intrinsic::uadd_with_overflow:
|
||||
// overflow = uadd a, -4 --> overflow = icmp ugt a, 3
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(WO->getRHS()))
|
||||
return new ICmpInst(ICmpInst::ICMP_UGT, WO->getLHS(),
|
||||
ConstantExpr::getNot(CI));
|
||||
break;
|
||||
case Intrinsic::umul_with_overflow:
|
||||
// overflow for umul a, C --> a > UINT_MAX udiv C
|
||||
// (unless C == 0, in which case no overflow ever occurs)
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(WO->getRHS())) {
|
||||
assert(!CI->isZero() && "handled by instruction simplify");
|
||||
auto UMax = APInt::getMaxValue(CI->getType()->getBitWidth());
|
||||
auto *Op =
|
||||
ConstantExpr::getUDiv(ConstantInt::get(CI->getType(), UMax), CI);
|
||||
return new ICmpInst(ICmpInst::ICMP_UGT, WO->getLHS(), Op);
|
||||
// If only the overflow result is used, and the right hand side is a
|
||||
// constant (or constant splat), we can remove the intrinsic by directly
|
||||
// checking for overflow.
|
||||
const APInt *C;
|
||||
if (match(WO->getRHS(), m_APInt(C))) {
|
||||
// Compute the no-wrap range [X,Y) for LHS given RHS=C, then
|
||||
// check for the inverted range using range offset trick (i.e.
|
||||
// use a subtract to shift the range to bottom of either the
|
||||
// signed or unsigned domain and then use a single compare to
|
||||
// check range membership).
|
||||
ConstantRange NWR =
|
||||
ConstantRange::makeExactNoWrapRegion(WO->getBinaryOp(), *C,
|
||||
WO->getNoWrapKind());
|
||||
APInt Min = WO->isSigned() ? NWR.getSignedMin() : NWR.getUnsignedMin();
|
||||
NWR = NWR.subtract(Min);
|
||||
|
||||
CmpInst::Predicate Pred;
|
||||
APInt NewRHSC;
|
||||
if (NWR.getEquivalentICmp(Pred, NewRHSC)) {
|
||||
auto *OpTy = WO->getRHS()->getType();
|
||||
auto *NewLHS = Builder.CreateSub(WO->getLHS(),
|
||||
ConstantInt::get(OpTy, Min));
|
||||
return new ICmpInst(ICmpInst::getInversePredicate(Pred), NewLHS,
|
||||
ConstantInt::get(OpTy, NewRHSC));
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (LoadInst *L = dyn_cast<LoadInst>(Agg))
|
||||
|
@ -26,8 +26,7 @@ define i1 @test_constant0(i8 %a) {
|
||||
|
||||
define i1 @test_constant1(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant1(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 1)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], 127
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 1)
|
||||
@ -37,8 +36,7 @@ define i1 @test_constant1(i8 %a) {
|
||||
|
||||
define i1 @test_constant2(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant2(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 2)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], 125
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 2)
|
||||
@ -48,8 +46,7 @@ define i1 @test_constant2(i8 %a) {
|
||||
|
||||
define i1 @test_constant3(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant3(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 3)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], 124
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 3)
|
||||
@ -59,8 +56,7 @@ define i1 @test_constant3(i8 %a) {
|
||||
|
||||
define i1 @test_constant4(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant4(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 4)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], 123
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 4)
|
||||
@ -70,8 +66,7 @@ define i1 @test_constant4(i8 %a) {
|
||||
|
||||
define i1 @test_constant127(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant127(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 127)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], 0
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 127)
|
||||
@ -81,8 +76,7 @@ define i1 @test_constant127(i8 %a) {
|
||||
|
||||
define i1 @test_constant128(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant128(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -128)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], 0
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 128)
|
||||
@ -92,8 +86,7 @@ define i1 @test_constant128(i8 %a) {
|
||||
|
||||
define i1 @test_constant255(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant255(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -1)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], -128
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 255)
|
||||
|
@ -35,8 +35,8 @@ define i1 @test_constant1(i8 %a) {
|
||||
|
||||
define i1 @test_constant2(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant2(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 2)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 64
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[TMP1]], 0
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 2)
|
||||
@ -46,8 +46,8 @@ define i1 @test_constant2(i8 %a) {
|
||||
|
||||
define i1 @test_constant3(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant3(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 3)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 42
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[TMP1]], 84
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 3)
|
||||
@ -57,8 +57,8 @@ define i1 @test_constant3(i8 %a) {
|
||||
|
||||
define i1 @test_constant4(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant4(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 4)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 32
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[TMP1]], 63
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 4)
|
||||
@ -69,8 +69,8 @@ define i1 @test_constant4(i8 %a) {
|
||||
|
||||
define i1 @test_constant127(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant127(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 127)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[TMP1]], 2
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 127)
|
||||
@ -80,8 +80,7 @@ define i1 @test_constant127(i8 %a) {
|
||||
|
||||
define i1 @test_constant128(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant128(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 -128)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[A:%.*]], 1
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 128)
|
||||
@ -91,8 +90,7 @@ define i1 @test_constant128(i8 %a) {
|
||||
|
||||
define i1 @test_constant255(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant255(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 -1)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], -128
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 255)
|
||||
|
@ -26,8 +26,7 @@ define i1 @test_constant0(i8 %a) {
|
||||
|
||||
define i1 @test_constant1(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant1(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -1)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], -128
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 1)
|
||||
@ -37,8 +36,7 @@ define i1 @test_constant1(i8 %a) {
|
||||
|
||||
define i1 @test_constant2(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant2(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -2)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -126
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 2)
|
||||
@ -48,8 +46,7 @@ define i1 @test_constant2(i8 %a) {
|
||||
|
||||
define i1 @test_constant3(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant3(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -3)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -125
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 3)
|
||||
@ -59,8 +56,7 @@ define i1 @test_constant3(i8 %a) {
|
||||
|
||||
define i1 @test_constant4(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant4(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -4)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -124
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 4)
|
||||
@ -71,8 +67,7 @@ define i1 @test_constant4(i8 %a) {
|
||||
|
||||
define i1 @test_constant127(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant127(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -127)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -1
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 127)
|
||||
@ -82,8 +77,7 @@ define i1 @test_constant127(i8 %a) {
|
||||
|
||||
define i1 @test_constant128(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant128(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[A:%.*]], i8 -128)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], -1
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 128)
|
||||
@ -93,8 +87,7 @@ define i1 @test_constant128(i8 %a) {
|
||||
|
||||
define i1 @test_constant255(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant255(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 1)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], 127
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 255)
|
||||
|
@ -26,8 +26,7 @@ define i1 @test_constant0(i8 %a) {
|
||||
|
||||
define i1 @test_constant1(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant1(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 1)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], 0
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 1)
|
||||
@ -37,8 +36,7 @@ define i1 @test_constant1(i8 %a) {
|
||||
|
||||
define i1 @test_constant2(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant2(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 2)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 2
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 2)
|
||||
@ -48,8 +46,7 @@ define i1 @test_constant2(i8 %a) {
|
||||
|
||||
define i1 @test_constant3(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant3(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 3)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 3
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 3)
|
||||
@ -59,8 +56,7 @@ define i1 @test_constant3(i8 %a) {
|
||||
|
||||
define i1 @test_constant4(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant4(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 4)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 4
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 4)
|
||||
@ -71,8 +67,7 @@ define i1 @test_constant4(i8 %a) {
|
||||
|
||||
define i1 @test_constant127(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant127(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 127)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 127
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 127)
|
||||
@ -82,8 +77,7 @@ define i1 @test_constant127(i8 %a) {
|
||||
|
||||
define i1 @test_constant128(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant128(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 -128)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], -1
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 128)
|
||||
@ -93,8 +87,7 @@ define i1 @test_constant128(i8 %a) {
|
||||
|
||||
define i1 @test_constant255(i8 %a) {
|
||||
; CHECK-LABEL: @test_constant255(
|
||||
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 -1)
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
|
||||
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ne i8 [[A:%.*]], -1
|
||||
; CHECK-NEXT: ret i1 [[OVERFLOW]]
|
||||
;
|
||||
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 255)
|
||||
|
Loading…
Reference in New Issue
Block a user