diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-04-08 21:23:50 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-04-08 21:23:50 +0000 |
commit | 773e04c88366b86a4285f296ab6d632597f07db8 (patch) | |
tree | 46747a671f3704d6831098c99c2670928f91eafb /llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | |
parent | 9f74df7d5bcd63302e4b8bfb609ed6cb1f0ae9d7 (diff) | |
download | bcm5719-llvm-773e04c88366b86a4285f296ab6d632597f07db8.tar.gz bcm5719-llvm-773e04c88366b86a4285f296ab6d632597f07db8.zip |
[InstCombine] peek through fdiv to find a squared sqrt
A more general canonicalization between fdiv and fmul would not
handle this case because that would have to be limited by uses
to prevent 2 values from becoming 3 values:
(x/y) * (x/y) --> (x*x) / (y*y)
(But we probably should still have that limited -- but more general --
canonicalization independently of this change.)
llvm-svn: 357943
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 03855f6bac4..6be2efdcc53 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -441,6 +441,25 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) { return replaceInstUsesWith(I, Sqrt); } + // Like the similar transform in instsimplify, this requires 'nsz' because + // sqrt(-0.0) = -0.0, and -0.0 * -0.0 does not simplify to -0.0. + if (I.hasNoNaNs() && I.hasNoSignedZeros() && Op0 == Op1 && + Op0->hasNUses(2)) { + // Peek through fdiv to find squaring of square root: + // (X / sqrt(Y)) * (X / sqrt(Y)) --> (X * X) / Y + if (match(Op0, m_FDiv(m_Value(X), + m_Intrinsic<Intrinsic::sqrt>(m_Value(Y))))) { + Value *XX = Builder.CreateFMulFMF(X, X, &I); + return BinaryOperator::CreateFDivFMF(XX, Y, &I); + } + // (sqrt(Y) / X) * (sqrt(Y) / X) --> Y / (X * X) + if (match(Op0, m_FDiv(m_Intrinsic<Intrinsic::sqrt>(m_Value(Y)), + m_Value(X)))) { + Value *XX = Builder.CreateFMulFMF(X, X, &I); + return BinaryOperator::CreateFDivFMF(Y, XX, &I); + } + } + // exp(X) * exp(Y) -> exp(X + Y) // Match as long as at least one of exp has only one use. if (match(Op0, m_Intrinsic<Intrinsic::exp>(m_Value(X))) && |