diff options
-rw-r--r-- | llvm/include/llvm/IR/Constant.h | 8 | ||||
-rw-r--r-- | llvm/lib/IR/Constants.cpp | 26 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 55 |
3 files changed, 47 insertions, 42 deletions
diff --git a/llvm/include/llvm/IR/Constant.h b/llvm/include/llvm/IR/Constant.h index 0c94b58a311..362c2d9c66f 100644 --- a/llvm/include/llvm/IR/Constant.h +++ b/llvm/include/llvm/IR/Constant.h @@ -71,6 +71,14 @@ public: /// Return true if the value is the smallest signed value. bool isMinSignedValue() const; + /// Return true if this is a finite and non-zero floating-point scalar + /// constant or a vector constant with all finite and non-zero elements. + bool isFiniteNonZeroFP() const; + + /// Return true if this is a normal (as opposed to denormal) floating-point + /// scalar constant or a vector constant with all normal elements. + bool isNormalFP() const; + /// Return true if evaluation of this constant could trap. This is true for /// things like constant expressions that could divide by zero. bool canTrap() const; diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index a601f54a359..6aaf90c8f84 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -202,6 +202,32 @@ bool Constant::isNotMinSignedValue() const { return false; } +bool Constant::isFiniteNonZeroFP() const { + if (auto *CFP = dyn_cast<ConstantFP>(this)) + return CFP->getValueAPF().isFiniteNonZero(); + if (!getType()->isVectorTy()) + return false; + for (unsigned i = 0, e = getType()->getVectorNumElements(); i != e; ++i) { + auto *CFP = dyn_cast_or_null<ConstantFP>(this->getAggregateElement(i)); + if (!CFP || !CFP->getValueAPF().isFiniteNonZero()) + return false; + } + return true; +} + +bool Constant::isNormalFP() const { + if (auto *CFP = dyn_cast<ConstantFP>(this)) + return CFP->getValueAPF().isNormal(); + if (!getType()->isVectorTy()) + return false; + for (unsigned i = 0, e = getType()->getVectorNumElements(); i != e; ++i) { + auto *CFP = dyn_cast_or_null<ConstantFP>(this->getAggregateElement(i)); + if (!CFP || !CFP->getValueAPF().isNormal()) + return false; + } + return true; +} + /// Constructor to create a '0' constant of arbitrary type. Constant *Constant::getNullValue(Type *Ty) { switch (Ty->getTypeID()) { diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 08d83a1e4d0..cccde0cc81c 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -478,35 +478,6 @@ static void detectLog2OfHalf(Value *&Op, Value *&Y, IntrinsicInst *&Log2) { Y = I->getOperand(0); } -static bool isFiniteNonZeroFp(Constant *C) { - if (C->getType()->isVectorTy()) { - for (unsigned I = 0, E = C->getType()->getVectorNumElements(); I != E; - ++I) { - ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(C->getAggregateElement(I)); - if (!CFP || !CFP->getValueAPF().isFiniteNonZero()) - return false; - } - return true; - } - - return isa<ConstantFP>(C) && - cast<ConstantFP>(C)->getValueAPF().isFiniteNonZero(); -} - -static bool isNormalFp(Constant *C) { - if (C->getType()->isVectorTy()) { - for (unsigned I = 0, E = C->getType()->getVectorNumElements(); I != E; - ++I) { - ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(C->getAggregateElement(I)); - if (!CFP || !CFP->getValueAPF().isNormal()) - return false; - } - return true; - } - - return isa<ConstantFP>(C) && cast<ConstantFP>(C)->getValueAPF().isNormal(); -} - /// Helper function of InstCombiner::visitFMul(). Return true iff the given /// value is FMul or FDiv with one and only one operand being a finite-non-zero /// constant (i.e. not Zero/NaN/Infinity). @@ -514,7 +485,7 @@ static bool isFMulOrFDivWithConstant(Value *V) { Constant *C; return (match(V, m_FMul(m_Value(), m_Constant(C))) || match(V, m_FDiv(m_Value(), m_Constant(C))) || - match(V, m_FDiv(m_Constant(C), m_Value()))) && isFiniteNonZeroFp(C); + match(V, m_FDiv(m_Constant(C), m_Value()))) && C->isFiniteNonZeroFP(); } /// foldFMulConst() is a helper routine of InstCombiner::visitFMul(). @@ -538,7 +509,7 @@ Value *InstCombiner::foldFMulConst(Instruction *FMulOrDiv, Constant *C, // (X * C0) * C => X * (C0*C) if (FMulOrDiv->getOpcode() == Instruction::FMul) { Constant *F = ConstantExpr::getFMul(C1 ? C1 : C0, C); - if (isNormalFp(F)) + if (F->isNormalFP()) R = BinaryOperator::CreateFMul(C1 ? Opnd0 : Opnd1, F); } else { if (C0) { @@ -546,18 +517,18 @@ Value *InstCombiner::foldFMulConst(Instruction *FMulOrDiv, Constant *C, if (FMulOrDiv->hasOneUse()) { // It would otherwise introduce another div. Constant *F = ConstantExpr::getFMul(C0, C); - if (isNormalFp(F)) + if (F->isNormalFP()) R = BinaryOperator::CreateFDiv(F, Opnd1); } } else { // (X / C1) * C => X * (C/C1) if C/C1 is not a denormal Constant *F = ConstantExpr::getFDiv(C, C1); - if (isNormalFp(F)) { + if (F->isNormalFP()) { R = BinaryOperator::CreateFMul(Opnd0, F); } else { // (X / C1) * C => X / (C1/C) Constant *F = ConstantExpr::getFDiv(C1, C); - if (isNormalFp(F)) + if (F->isNormalFP()) R = BinaryOperator::CreateFDiv(Opnd0, F); } } @@ -600,7 +571,7 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) { return RI; } - if (AllowReassociate && isFiniteNonZeroFp(C)) { + if (AllowReassociate && C->isFiniteNonZeroFP()) { // Let MDC denote an expression in one of these forms: // X * C, C/X, X/C, where C is a constant. // @@ -625,11 +596,11 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) { Swap = true; } - if (C1 && isFiniteNonZeroFp(C1) && isFMulOrFDivWithConstant(Opnd0)) { + if (C1 && C1->isFiniteNonZeroFP() && isFMulOrFDivWithConstant(Opnd0)) { Value *M1 = ConstantExpr::getFMul(C1, C); - Value *M0 = isNormalFp(cast<Constant>(M1)) ? - foldFMulConst(cast<Instruction>(Opnd0), C, &I) : - nullptr; + Value *M0 = cast<Constant>(M1)->isNormalFP() ? + foldFMulConst(cast<Instruction>(Opnd0), C, &I) : + nullptr; if (M0 && M1) { if (Swap && FAddSub->getOpcode() == Instruction::FSub) std::swap(M0, M1); @@ -1380,12 +1351,12 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) { if (match(Op0, m_FMul(m_Value(X), m_Constant(C1)))) { // (X*C1)/C2 => X * (C1/C2) Constant *C = ConstantExpr::getFDiv(C1, C2); - if (isNormalFp(C)) + if (C->isNormalFP()) Res = BinaryOperator::CreateFMul(X, C); } else if (match(Op0, m_FDiv(m_Value(X), m_Constant(C1)))) { // (X/C1)/C2 => X /(C2*C1) Constant *C = ConstantExpr::getFMul(C1, C2); - if (isNormalFp(C)) + if (C->isNormalFP()) Res = BinaryOperator::CreateFDiv(X, C); } @@ -1415,7 +1386,7 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) { CreateDiv = false; } - if (Fold && isNormalFp(Fold)) { + if (Fold && Fold->isNormalFP()) { Instruction *R = CreateDiv ? BinaryOperator::CreateFDiv(Fold, X) : BinaryOperator::CreateFMul(X, Fold); R->setFastMathFlags(I.getFastMathFlags()); |