summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-04-08 21:23:50 +0000
committerSanjay Patel <spatel@rotateright.com>2019-04-08 21:23:50 +0000
commit773e04c88366b86a4285f296ab6d632597f07db8 (patch)
tree46747a671f3704d6831098c99c2670928f91eafb /llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
parent9f74df7d5bcd63302e4b8bfb609ed6cb1f0ae9d7 (diff)
downloadbcm5719-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.cpp19
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))) &&
OpenPOWER on IntegriCloud