From 17348b5856fd8dcc4ede3efe13398e0c74cbe637 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 19 Feb 2018 21:17:58 +0000 Subject: [PATCH] [InstCombine] refactor fdiv with constant dividend folds; NFC The last fold that used to be here was not necessary. That's a combination of 2 folds (and there's a regression test to show that). The transforms are guarded by isFast(), but that should be loosened. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325531 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineMulDivRem.cpp | 53 +++++++++++----------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index cccde0cc81c..17ca01d4aa9 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -1316,6 +1316,31 @@ static Instruction *foldFDivConstantDivisor(BinaryOperator &FDiv) { return BinaryOperator::CreateFMul(FDiv.getOperand(0), RecipCFP); } +/// Try to strength-reduce C / X expressions where X includes another constant. +static Instruction *foldFDivConstantDividend(BinaryOperator &I) { + Constant *C1; + if (!I.isFast() || !match(I.getOperand(0), m_Constant(C1))) + return nullptr; + + Value *X; + Constant *C2, *NewC = nullptr; + if (match(I.getOperand(1), m_FMul(m_Value(X), m_Constant(C2)))) { + // C1 / (X * C2) --> (C1 / C2) / X + NewC = ConstantExpr::getFDiv(C1, C2); + } else if (match(I.getOperand(1), m_FDiv(m_Value(X), m_Constant(C2)))) { + // C1 / (X / C2) --> (C1 * C2) / X + NewC = ConstantExpr::getFMul(C1, C2); + } + // Disallow denormal constants because we don't know what would happen + // on all targets. + // TODO: Use Intrinsic::canonicalize or let function attributes tell us that + // denorms are flushed? + if (!NewC || !NewC->isNormalFP()) + return nullptr; + + return BinaryOperator::CreateWithCopiedFlags(Instruction::FDiv, NewC, X, &I); +} + Instruction *InstCombiner::visitFDiv(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); @@ -1368,32 +1393,8 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) { return nullptr; } - if (AllowReassociate && isa(Op0)) { - Constant *C1 = cast(Op0), *C2; - Constant *Fold = nullptr; - Value *X; - bool CreateDiv = true; - - // C1 / (X*C2) => (C1/C2) / X - if (match(Op1, m_FMul(m_Value(X), m_Constant(C2)))) - Fold = ConstantExpr::getFDiv(C1, C2); - else if (match(Op1, m_FDiv(m_Value(X), m_Constant(C2)))) { - // C1 / (X/C2) => (C1*C2) / X - Fold = ConstantExpr::getFMul(C1, C2); - } else if (match(Op1, m_FDiv(m_Constant(C2), m_Value(X)))) { - // C1 / (C2/X) => (C1/C2) * X - Fold = ConstantExpr::getFDiv(C1, C2); - CreateDiv = false; - } - - if (Fold && Fold->isNormalFP()) { - Instruction *R = CreateDiv ? BinaryOperator::CreateFDiv(Fold, X) - : BinaryOperator::CreateFMul(X, Fold); - R->setFastMathFlags(I.getFastMathFlags()); - return R; - } - return nullptr; - } + if (Instruction *NewFDiv = foldFDivConstantDividend(I)) + return NewFDiv; if (AllowReassociate) { Value *X, *Y; -- 2.11.0