diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 2a34edbf6cb8..8cb09cbac86f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -505,20 +505,23 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) { Constant *C1; if (match(Op0, m_OneUse(m_FDiv(m_Constant(C1), m_Value(X))))) { // (C1 / X) * C --> (C * C1) / X - Constant *CC1 = ConstantExpr::getFMul(C, C1); - if (CC1->isNormalFP()) + Constant *CC1 = + ConstantFoldBinaryOpOperands(Instruction::FMul, C, C1, DL); + if (CC1 && CC1->isNormalFP()) return BinaryOperator::CreateFDivFMF(CC1, X, &I); } if (match(Op0, m_FDiv(m_Value(X), m_Constant(C1)))) { // (X / C1) * C --> X * (C / C1) - Constant *CDivC1 = ConstantExpr::getFDiv(C, C1); - if (CDivC1->isNormalFP()) + Constant *CDivC1 = + ConstantFoldBinaryOpOperands(Instruction::FDiv, C, C1, DL); + if (CDivC1 && CDivC1->isNormalFP()) return BinaryOperator::CreateFMulFMF(X, CDivC1, &I); // If the constant was a denormal, try reassociating differently. // (X / C1) * C --> X / (C1 / C) - Constant *C1DivC = ConstantExpr::getFDiv(C1, C); - if (Op0->hasOneUse() && C1DivC->isNormalFP()) + Constant *C1DivC = + ConstantFoldBinaryOpOperands(Instruction::FDiv, C1, C, DL); + if (C1DivC && Op0->hasOneUse() && C1DivC->isNormalFP()) return BinaryOperator::CreateFDivFMF(X, C1DivC, &I); } @@ -527,15 +530,19 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) { // further folds and (X * C) + C2 is 'fma'. if (match(Op0, m_OneUse(m_FAdd(m_Value(X), m_Constant(C1))))) { // (X + C1) * C --> (X * C) + (C * C1) - Constant *CC1 = ConstantExpr::getFMul(C, C1); - Value *XC = Builder.CreateFMulFMF(X, C, &I); - return BinaryOperator::CreateFAddFMF(XC, CC1, &I); + if (Constant *CC1 = ConstantFoldBinaryOpOperands( + Instruction::FMul, C, C1, DL)) { + Value *XC = Builder.CreateFMulFMF(X, C, &I); + return BinaryOperator::CreateFAddFMF(XC, CC1, &I); + } } if (match(Op0, m_OneUse(m_FSub(m_Constant(C1), m_Value(X))))) { // (C1 - X) * C --> (C * C1) - (X * C) - Constant *CC1 = ConstantExpr::getFMul(C, C1); - Value *XC = Builder.CreateFMulFMF(X, C, &I); - return BinaryOperator::CreateFSubFMF(CC1, XC, &I); + if (Constant *CC1 = ConstantFoldBinaryOpOperands( + Instruction::FMul, C, C1, DL)) { + Value *XC = Builder.CreateFMulFMF(X, C, &I); + return BinaryOperator::CreateFSubFMF(CC1, XC, &I); + } } } @@ -1232,8 +1239,10 @@ static Instruction *foldFDivConstantDivisor(BinaryOperator &I) { // on all targets. // TODO: Use Intrinsic::canonicalize or let function attributes tell us that // denorms are flushed? - auto *RecipC = ConstantExpr::getFDiv(ConstantFP::get(I.getType(), 1.0), C); - if (!RecipC->isNormalFP()) + const DataLayout &DL = I.getModule()->getDataLayout(); + auto *RecipC = ConstantFoldBinaryOpOperands( + Instruction::FDiv, ConstantFP::get(I.getType(), 1.0), C, DL); + if (!RecipC || !RecipC->isNormalFP()) return nullptr; // X / C --> X * (1 / C) @@ -1256,12 +1265,13 @@ static Instruction *foldFDivConstantDividend(BinaryOperator &I) { // Try to reassociate C / X expressions where X includes another constant. Constant *C2, *NewC = nullptr; + const DataLayout &DL = I.getModule()->getDataLayout(); if (match(I.getOperand(1), m_FMul(m_Value(X), m_Constant(C2)))) { // C / (X * C2) --> (C / C2) / X - NewC = ConstantExpr::getFDiv(C, C2); + NewC = ConstantFoldBinaryOpOperands(Instruction::FDiv, C, C2, DL); } else if (match(I.getOperand(1), m_FDiv(m_Value(X), m_Constant(C2)))) { // C / (X / C2) --> (C * C2) / X - NewC = ConstantExpr::getFMul(C, C2); + NewC = ConstantFoldBinaryOpOperands(Instruction::FMul, C, C2, DL); } // Disallow denormal constants because we don't know what would happen // on all targets. |