From ddb4c9a54ec370419557e44aec9c907978dd8b3c Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 5 Dec 2017 18:14:24 +0000 Subject: [CVP] Remove some {s|u}sub.with.overflow checks. This uses ConstantRange::makeGuaranteedNoWrapRegion's newly-added handling for subtraction to allow CVP to remove some subtraction overflow checks. Differential Revision: https://reviews.llvm.org/D40039 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319807 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/CorrelatedValuePropagation.cpp | 25 +++++++++++++++------- .../CorrelatedValuePropagation/overflows.ll | 13 ++++++----- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 040e0f59c61..d5ab8a5892c 100644 --- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -329,13 +329,15 @@ static bool processSwitch(SwitchInst *SI, LazyValueInfo *LVI) { // See if we can prove that the given overflow intrinsic will not overflow. static bool willNotOverflow(IntrinsicInst *II, LazyValueInfo *LVI) { using OBO = OverflowingBinaryOperator; - auto NoWrapOnAddition = [&] (Value *LHS, Value *RHS, unsigned NoWrapKind) { + auto NoWrap = [&] (Instruction::BinaryOps BinOp, unsigned NoWrapKind) { + Value *RHS = II->getOperand(1); ConstantRange RRange = LVI->getConstantRange(RHS, II->getParent(), II); ConstantRange NWRegion = ConstantRange::makeGuaranteedNoWrapRegion( - BinaryOperator::Add, RRange, NoWrapKind); + BinOp, RRange, NoWrapKind); // As an optimization, do not compute LRange if we do not need it. if (NWRegion.isEmptySet()) return false; + Value *LHS = II->getOperand(0); ConstantRange LRange = LVI->getConstantRange(LHS, II->getParent(), II); return NWRegion.contains(LRange); }; @@ -343,11 +345,13 @@ static bool willNotOverflow(IntrinsicInst *II, LazyValueInfo *LVI) { default: break; case Intrinsic::uadd_with_overflow: - return NoWrapOnAddition(II->getOperand(0), II->getOperand(1), - OBO::NoUnsignedWrap); + return NoWrap(Instruction::Add, OBO::NoUnsignedWrap); case Intrinsic::sadd_with_overflow: - return NoWrapOnAddition(II->getOperand(0), II->getOperand(1), - OBO::NoSignedWrap); + return NoWrap(Instruction::Add, OBO::NoSignedWrap); + case Intrinsic::usub_with_overflow: + return NoWrap(Instruction::Sub, OBO::NoUnsignedWrap); + case Intrinsic::ssub_with_overflow: + return NoWrap(Instruction::Sub, OBO::NoSignedWrap); } return false; } @@ -356,12 +360,17 @@ static void processOverflowIntrinsic(IntrinsicInst *II) { Value *NewOp = nullptr; switch (II->getIntrinsicID()) { default: - llvm_unreachable("Illegal instruction."); + llvm_unreachable("Unexpected instruction."); case Intrinsic::uadd_with_overflow: case Intrinsic::sadd_with_overflow: NewOp = BinaryOperator::CreateAdd(II->getOperand(0), II->getOperand(1), II->getName(), II); break; + case Intrinsic::usub_with_overflow: + case Intrinsic::ssub_with_overflow: + NewOp = BinaryOperator::CreateSub(II->getOperand(0), II->getOperand(1), + II->getName(), II); + break; } ++NumOverflows; IRBuilder<> B(II); @@ -376,7 +385,7 @@ static bool processCallSite(CallSite CS, LazyValueInfo *LVI) { SmallVector ArgNos; unsigned ArgNo = 0; - if (IntrinsicInst *II = dyn_cast(CS.getInstruction())) { + if (auto *II = dyn_cast(CS.getInstruction())) { if (willNotOverflow(II, LVI)) { processOverflowIntrinsic(II); return true; diff --git a/test/Transforms/CorrelatedValuePropagation/overflows.ll b/test/Transforms/CorrelatedValuePropagation/overflows.ll index 5cd6b261be4..a131038b8e0 100644 --- a/test/Transforms/CorrelatedValuePropagation/overflows.ll +++ b/test/Transforms/CorrelatedValuePropagation/overflows.ll @@ -13,8 +13,7 @@ declare void @llvm.trap() define i32 @signed_add(i32 %x, i32 %y) { ; CHECK-LABEL: @signed_add( -; CHECK: @llvm.ssub.with.overflow.i32 -; CHECK: @llvm.ssub.with.overflow.i32 +; CHECK-NOT: @llvm.ssub.with.overflow.i32 ; CHECK: @llvm.sadd.with.overflow.i32 entry: %cmp = icmp sgt i32 %y, 0 @@ -61,7 +60,7 @@ cond.end: ; preds = %cond.false, %cont, define i32 @unsigned_add(i32 %x, i32 %y) { ; CHECK-LABEL: @unsigned_add( -; CHECK: @llvm.usub.with.overflow.i32 +; CHECK-NOT: @llvm.usub.with.overflow.i32 ; CHECK: @llvm.uadd.with.overflow.i32 entry: %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 -1, i32 %y) @@ -203,7 +202,7 @@ cond.end: ; preds = %cond.false, %entry define i32 @signed_sub_r1(i32 %x) { ; CHECK-LABEL: @signed_sub_r1( -; CHECK: @llvm.ssub.with.overflow.i32 +; CHECK-NOT: @llvm.ssub.with.overflow.i32 entry: %cmp = icmp eq i32 %x, -2147483648 br i1 %cmp, label %cond.end, label %cond.false @@ -225,7 +224,7 @@ cond.end: ; preds = %cond.false, %entry define i32 @unsigned_sub_r1(i32 %x) { ; CHECK-LABEL: @unsigned_sub_r1( -; CHECK: @llvm.usub.with.overflow.i32 +; CHECK-NOT: @llvm.usub.with.overflow.i32 entry: %cmp = icmp eq i32 %x, 0 br i1 %cmp, label %cond.end, label %cond.false @@ -269,7 +268,7 @@ cond.end: ; preds = %cond.false, %entry define i32 @signed_sub_rn1(i32 %x) { ; CHECK-LABEL: @signed_sub_rn1( -; CHECK: @llvm.ssub.with.overflow.i32 +; CHECK-NOT: @llvm.ssub.with.overflow.i32 entry: %cmp = icmp eq i32 %x, 2147483647 br i1 %cmp, label %cond.end, label %cond.false @@ -293,7 +292,7 @@ declare i32 @bar(i32) define void @unsigned_loop(i32 %i) { ; CHECK-LABEL: @unsigned_loop( -; CHECK: @llvm.usub.with.overflow.i32 +; CHECK-NOT: @llvm.usub.with.overflow.i32 entry: %cmp3 = icmp eq i32 %i, 0 br i1 %cmp3, label %while.end, label %while.body.preheader -- cgit v1.2.3