From 0461d73cc94f716ab9bacaa8879626b2516efe33 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 26 May 2019 11:43:31 +0000 Subject: [PATCH] [InstCombine] Remove OverflowCheckFlavor; NFC Instead pass binary op and signedness. The extra enum only makes things more complicated in this case. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361720 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineCalls.cpp | 11 +++---- lib/Transforms/InstCombine/InstCombineCompares.cpp | 31 ++++++++---------- lib/Transforms/InstCombine/InstCombineInternal.h | 37 ++-------------------- 3 files changed, 20 insertions(+), 59 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 8d022617d85..e2813f9d9d4 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1749,15 +1749,12 @@ static Instruction *canonicalizeConstantArg0ToArg1(CallInst &Call) { } Instruction *InstCombiner::foldIntrinsicWithOverflowCommon(IntrinsicInst *II) { - OverflowCheckFlavor OCF = - IntrinsicIDToOverflowCheckFlavor(II->getIntrinsicID()); - assert(OCF != OCF_INVALID && "unexpected!"); - + WithOverflowInst *WO = cast(II); Value *OperationResult = nullptr; Constant *OverflowResult = nullptr; - if (OptimizeOverflowCheck(OCF, II->getArgOperand(0), II->getArgOperand(1), - *II, OperationResult, OverflowResult)) - return CreateOverflowTuple(II, OperationResult, OverflowResult); + if (OptimizeOverflowCheck(WO->getBinaryOp(), WO->isSigned(), WO->getLHS(), + WO->getRHS(), *WO, OperationResult, OverflowResult)) + return CreateOverflowTuple(WO, OperationResult, OverflowResult); return nullptr; } diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index ce6b38c90ca..d848aef2552 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3936,9 +3936,9 @@ Instruction *InstCombiner::foldICmpWithCastAndCast(ICmpInst &ICmp) { return BinaryOperator::CreateNot(Result); } -bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, - Value *RHS, Instruction &OrigI, - Value *&Result, Constant *&Overflow) { +bool InstCombiner::OptimizeOverflowCheck( + Instruction::BinaryOps BinaryOp, bool IsSigned, Value *LHS, Value *RHS, + Instruction &OrigI, Value *&Result, Constant *&Overflow) { if (OrigI.isCommutative() && isa(LHS) && !isa(RHS)) std::swap(LHS, RHS); @@ -3956,18 +3956,17 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, // compare. Builder.SetInsertPoint(&OrigI); - switch (OCF) { - case OCF_INVALID: - llvm_unreachable("bad overflow check kind!"); + switch (BinaryOp) { + default: + llvm_unreachable("unsupported binary op"); - case OCF_UNSIGNED_ADD: - case OCF_SIGNED_ADD: { + case Instruction::Add: { // X + 0 -> {X, false} if (match(RHS, m_Zero())) return SetResult(LHS, Builder.getFalse(), false); OverflowResult OR; - if (OCF == OCF_UNSIGNED_ADD) { + if (!IsSigned) { OR = computeOverflowForUnsignedAdd(LHS, RHS, &OrigI); if (OR == OverflowResult::NeverOverflows) return SetResult(Builder.CreateNUWAdd(LHS, RHS), Builder.getFalse(), @@ -3984,14 +3983,13 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, break; } - case OCF_UNSIGNED_SUB: - case OCF_SIGNED_SUB: { + case Instruction::Sub: { // X - 0 -> {X, false} if (match(RHS, m_Zero())) return SetResult(LHS, Builder.getFalse(), false); OverflowResult OR; - if (OCF == OCF_UNSIGNED_SUB) { + if (!IsSigned) { OR = computeOverflowForUnsignedSub(LHS, RHS, &OrigI); if (OR == OverflowResult::NeverOverflows) return SetResult(Builder.CreateNUWSub(LHS, RHS), Builder.getFalse(), @@ -4008,14 +4006,13 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, break; } - case OCF_UNSIGNED_MUL: - case OCF_SIGNED_MUL: { + case Instruction::Mul: { // X * 1 -> {X, false} if (match(RHS, m_One())) return SetResult(LHS, Builder.getFalse(), false); OverflowResult OR; - if (OCF == OCF_UNSIGNED_MUL) { + if (!IsSigned) { OR = computeOverflowForUnsignedMul(LHS, RHS, &OrigI); if (OR == OverflowResult::NeverOverflows) return SetResult(Builder.CreateNUWMul(LHS, RHS), Builder.getFalse(), @@ -5053,8 +5050,8 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { isa(A->getType())) { Value *Result; Constant *Overflow; - if (OptimizeOverflowCheck(OCF_UNSIGNED_ADD, A, B, *AddI, Result, - Overflow)) { + if (OptimizeOverflowCheck(Instruction::Add, /*Signed*/false, A, B, + *AddI, Result, Overflow)) { replaceInstUsesWith(*AddI, Result); return replaceInstUsesWith(I, Overflow); } diff --git a/lib/Transforms/InstCombine/InstCombineInternal.h b/lib/Transforms/InstCombine/InstCombineInternal.h index c34a71a2251..123025bbccf 100644 --- a/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/lib/Transforms/InstCombine/InstCombineInternal.h @@ -185,40 +185,6 @@ static inline bool IsFreeToInvert(Value *V, bool WillInvertAllUses) { return false; } -/// Specific patterns of overflow check idioms that we match. -enum OverflowCheckFlavor { - OCF_UNSIGNED_ADD, - OCF_SIGNED_ADD, - OCF_UNSIGNED_SUB, - OCF_SIGNED_SUB, - OCF_UNSIGNED_MUL, - OCF_SIGNED_MUL, - - OCF_INVALID -}; - -/// Returns the OverflowCheckFlavor corresponding to a overflow_with_op -/// intrinsic. -static inline OverflowCheckFlavor -IntrinsicIDToOverflowCheckFlavor(unsigned ID) { - switch (ID) { - default: - return OCF_INVALID; - case Intrinsic::uadd_with_overflow: - return OCF_UNSIGNED_ADD; - case Intrinsic::sadd_with_overflow: - return OCF_SIGNED_ADD; - case Intrinsic::usub_with_overflow: - return OCF_UNSIGNED_SUB; - case Intrinsic::ssub_with_overflow: - return OCF_SIGNED_SUB; - case Intrinsic::umul_with_overflow: - return OCF_UNSIGNED_MUL; - case Intrinsic::smul_with_overflow: - return OCF_SIGNED_MUL; - } -} - /// Some binary operators require special handling to avoid poison and undefined /// behavior. If a constant vector has undef elements, replace those undefs with /// identity constants if possible because those are always safe to execute. @@ -469,7 +435,8 @@ private: /// operation in OperationResult and result of the overflow check in /// OverflowResult, and return true. If no simplification is possible, /// returns false. - bool OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, Value *RHS, + bool OptimizeOverflowCheck(Instruction::BinaryOps BinaryOp, bool IsSigned, + Value *LHS, Value *RHS, Instruction &CtxI, Value *&OperationResult, Constant *&OverflowResult); -- 2.11.0