From: Sanjay Patel Date: Fri, 23 Feb 2018 17:14:28 +0000 (+0000) Subject: [InstCombine] refactor fmul with negated op folds; NFCI X-Git-Tag: llvmorg-7.0.0-rc1~12148 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6b9c7a9c83fed425ac6f71d9378c749f3c496045;p=platform%2Fupstream%2Fllvm.git [InstCombine] refactor fmul with negated op folds; NFCI The existing code was inefficiently looking for 'nsz' variants. That's unnecessary because we canonicalize those to the expected form with -0.0. We may also want to adjust or remove the fold that sinks negation. We don't do that for fdiv (or integer ops?). That should be uniform? It may also lead to missed optimization as in PR21914: https://bugs.llvm.org/show_bug.cgi?id=21914 ...or we just have to fix other passes to avoid that problem. llvm-svn: 325924 --- diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 69993ea..cb48b93 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -560,6 +560,11 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) { if (Instruction *FoldedMul = foldOpWithConstantIntoOperand(I)) return FoldedMul; + // -X * C --> X * -C + Value *X; + if (match(Op0, m_FNeg(m_Value(X)))) + return BinaryOperator::CreateFMulFMF(X, ConstantExpr::getFNeg(C), &I); + // (fmul X, -1.0) --> (fsub -0.0, X) if (match(C, m_SpecificFP(-1.0))) { Constant *NegZero = ConstantFP::getNegativeZero(Op1->getType()); @@ -673,34 +678,23 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) { } } + // -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); + + // 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); + // Handle symmetric situation in a 2-iteration loop Value *Opnd0 = Op0; Value *Opnd1 = Op1; for (int i = 0; i < 2; i++) { - bool IgnoreZeroSign = I.hasNoSignedZeros(); - if (BinaryOperator::isFNeg(Opnd0, IgnoreZeroSign)) { - BuilderTy::FastMathFlagGuard Guard(Builder); - Builder.setFastMathFlags(I.getFastMathFlags()); - - Value *N0 = dyn_castFNegVal(Opnd0, IgnoreZeroSign); - Value *N1 = dyn_castFNegVal(Opnd1, IgnoreZeroSign); - - // -X * -Y => X*Y - if (N1) { - Value *FMul = Builder.CreateFMul(N0, N1); - FMul->takeName(&I); - return replaceInstUsesWith(I, FMul); - } - - if (Opnd0->hasOneUse()) { - // -X * Y => -(X*Y) (Promote negation as high as possible) - Value *T = Builder.CreateFMul(N0, Opnd1); - Value *Neg = Builder.CreateFNeg(T); - Neg->takeName(&I); - return replaceInstUsesWith(I, Neg); - } - } - // Handle specials cases for FMul with selects feeding the operation if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1)) return replaceInstUsesWith(I, V);