From 027535e24a3cad4bc1516ad880313579ccddcea4 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 2 Mar 2018 23:06:45 +0000 Subject: [PATCH] [InstCombine] rearrange visitFMul; NFCI Put the simplest non-FMF folds first, so it's easier to see what's left to fix/group/add with the FMF folds. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326632 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineMulDivRem.cpp | 142 ++++++++++----------- 1 file changed, 69 insertions(+), 73 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 799493c6550..47d5d5f0c0a 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -522,72 +522,84 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) { SQ.getWithInstruction(&I))) return replaceInstUsesWith(I, V); - bool AllowReassociate = I.isFast(); - if (Instruction *FoldedMul = foldBinOpIntoSelectOrPhi(I)) return FoldedMul; - // Simplify mul instructions with a constant RHS. - if (auto *C = dyn_cast(Op1)) { - // -X * C --> X * -C - Value *X; - if (match(Op0, m_FNeg(m_Value(X)))) - return BinaryOperator::CreateFMulFMF(X, ConstantExpr::getFNeg(C), &I); - - // X * -1.0 --> -X - if (match(C, m_SpecificFP(-1.0))) - return BinaryOperator::CreateFNegFMF(Op0, &I); - - 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. - // - // Try to simplify "MDC * Constant" - if (isFMulOrFDivWithConstant(Op0)) - if (Value *V = foldFMulConst(cast(Op0), C, &I)) - return replaceInstUsesWith(I, V); - - // (MDC +/- C1) * C => (MDC * C) +/- (C1 * C) - Instruction *FAddSub = dyn_cast(Op0); - if (FAddSub && - (FAddSub->getOpcode() == Instruction::FAdd || - FAddSub->getOpcode() == Instruction::FSub)) { - Value *Opnd0 = FAddSub->getOperand(0); - Value *Opnd1 = FAddSub->getOperand(1); - Constant *C0 = dyn_cast(Opnd0); - Constant *C1 = dyn_cast(Opnd1); - bool Swap = false; - if (C0) { - std::swap(C0, C1); - std::swap(Opnd0, Opnd1); - Swap = true; - } + // X * -1.0 --> -X + if (match(Op1, m_SpecificFP(-1.0))) + return BinaryOperator::CreateFNegFMF(Op0, &I); - if (C1 && C1->isFiniteNonZeroFP() && isFMulOrFDivWithConstant(Opnd0)) { - Value *M1 = ConstantExpr::getFMul(C1, C); - Value *M0 = cast(M1)->isNormalFP() ? - foldFMulConst(cast(Opnd0), C, &I) : - nullptr; - if (M0 && M1) { - if (Swap && FAddSub->getOpcode() == Instruction::FSub) - std::swap(M0, M1); - - Instruction *RI = (FAddSub->getOpcode() == Instruction::FAdd) - ? BinaryOperator::CreateFAdd(M0, M1) - : BinaryOperator::CreateFSub(M0, M1); - RI->copyFastMathFlags(&I); - return RI; - } - } - } - } - } + // -X * -Y --> X * Y + Value *X, *Y; + if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y)))) + return BinaryOperator::CreateFMulFMF(X, Y, &I); + + // -X * C --> X * -C + Constant *C; + if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_Constant(C))) + return BinaryOperator::CreateFMulFMF(X, ConstantExpr::getFNeg(C), &I); + + // Sink negation: -X * Y --> -(X * Y) + if (match(Op0, m_OneUse(m_FNeg(m_Value(X))))) + return BinaryOperator::CreateFNegFMF(Builder.CreateFMulFMF(X, Op1, &I), &I); + + // Sink negation: Y * -X --> -(X * Y) + if (match(Op1, m_OneUse(m_FNeg(m_Value(X))))) + return BinaryOperator::CreateFNegFMF(Builder.CreateFMulFMF(X, Op0, &I), &I); // fabs(X) * fabs(X) -> X * X - Value *X, *Y; if (Op0 == Op1 && match(Op0, m_Intrinsic(m_Value(X)))) return BinaryOperator::CreateFMulFMF(X, X, &I); + // (select A, B, C) * (select A, D, E) --> select A, (B*D), (C*E) + if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1)) + return replaceInstUsesWith(I, V); + + // Reassociate constant RHS with another constant to form constant expression. + if (I.isFast() && match(Op1, m_Constant(C)) && C->isFiniteNonZeroFP()) { + // Let MDC denote an expression in one of these forms: + // X * C, C/X, X/C, where C is a constant. + // + // Try to simplify "MDC * Constant" + if (isFMulOrFDivWithConstant(Op0)) + if (Value *V = foldFMulConst(cast(Op0), C, &I)) + return replaceInstUsesWith(I, V); + + // (MDC +/- C1) * C => (MDC * C) +/- (C1 * C) + Instruction *FAddSub = dyn_cast(Op0); + if (FAddSub && + (FAddSub->getOpcode() == Instruction::FAdd || + FAddSub->getOpcode() == Instruction::FSub)) { + Value *Opnd0 = FAddSub->getOperand(0); + Value *Opnd1 = FAddSub->getOperand(1); + Constant *C0 = dyn_cast(Opnd0); + Constant *C1 = dyn_cast(Opnd1); + bool Swap = false; + if (C0) { + std::swap(C0, C1); + std::swap(Opnd0, Opnd1); + Swap = true; + } + + if (C1 && C1->isFiniteNonZeroFP() && isFMulOrFDivWithConstant(Opnd0)) { + Value *M1 = ConstantExpr::getFMul(C1, C); + Value *M0 = cast(M1)->isNormalFP() ? + foldFMulConst(cast(Opnd0), C, &I) : + nullptr; + if (M0 && M1) { + if (Swap && FAddSub->getOpcode() == Instruction::FSub) + std::swap(M0, M1); + + Instruction *RI = (FAddSub->getOpcode() == Instruction::FAdd) + ? BinaryOperator::CreateFAdd(M0, M1) + : BinaryOperator::CreateFSub(M0, M1); + RI->copyFastMathFlags(&I); + return RI; + } + } + } + } + // log2(X * 0.5) * Y = log2(X) * Y - Y if (I.isFast()) { IntrinsicInst *Log2 = nullptr; @@ -618,22 +630,6 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) { return replaceInstUsesWith(I, Sqrt); } - // -X * -Y --> X * Y - if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y)))) - return BinaryOperator::CreateFMulFMF(X, Y, &I); - - // Sink negation: -X * Y --> -(X * Y) - if (match(Op0, m_OneUse(m_FNeg(m_Value(X))))) - return BinaryOperator::CreateFNegFMF(Builder.CreateFMulFMF(X, Op1, &I), &I); - - // Sink negation: Y * -X --> -(X * Y) - if (match(Op1, m_OneUse(m_FNeg(m_Value(X))))) - return BinaryOperator::CreateFNegFMF(Builder.CreateFMulFMF(X, Op0, &I), &I); - - // (select A, B, C) * (select A, D, E) --> select A, (B*D), (C*E) - if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1)) - return replaceInstUsesWith(I, V); - // (X*Y) * X => (X*X) * Y where Y != X // The purpose is two-fold: // 1) to form a power expression (of X). -- 2.11.0