# [PATCH] D43765: [InstSimplify] loosen FMF for sqrt(X) * sqrt(X) --> X

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 26 07:47:16 PST 2018

```spatel created this revision.
spatel added reviewers: arsenm, wristow, codeman.consulting, efriedma, hfinkel, scanon.

If my fast-math understanding is correct, 'reassoc' alone is not enough because that doesn't give us the freedom to get the negative number cases wrong.

I considered that we might not even need 'reassoc' here, but if we eliminate the sqrt calls, then we may differ in the last bit by eliminating the rounding that occurs in those calls.

https://reviews.llvm.org/D43765

Files:
lib/Analysis/InstructionSimplify.cpp
test/Transforms/InstSimplify/fast-math.ll

Index: test/Transforms/InstSimplify/fast-math.ll
===================================================================
--- test/Transforms/InstSimplify/fast-math.ll
+++ test/Transforms/InstSimplify/fast-math.ll
@@ -205,16 +205,16 @@
}

; PR21126: http://llvm.org/bugs/show_bug.cgi?id=21126
-; With unsafe/fast math, sqrt(X) * sqrt(X) is just X.
+; With loose math, sqrt(X) * sqrt(X) is just X.

declare double @llvm.sqrt.f64(double)

define double @sqrt_squared(double %f) {
; CHECK-LABEL: @sqrt_squared(
; CHECK-NEXT:    ret double [[F:%.*]]
;
%sqrt = call double @llvm.sqrt.f64(double %f)
-  %mul = fmul fast double %sqrt, %sqrt
+  %mul = fmul reassoc nnan nsz double %sqrt, %sqrt
ret double %mul
}

Index: lib/Analysis/InstructionSimplify.cpp
===================================================================
--- lib/Analysis/InstructionSimplify.cpp
+++ lib/Analysis/InstructionSimplify.cpp
@@ -4251,10 +4251,13 @@
if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op1, m_AnyZero()))
return Op1;

-  // sqrt(X) * sqrt(X) --> X
+  // sqrt(X) * sqrt(X) --> X, if we can:
+  // 1. Remove the intermediate rounding (reassociate).
+  // 2. Ignore non-zero negative numbers because sqrt would produce NAN.
+  // 3. Ignore -0.0 because sqrt(-0.0) == -0.0, but -0.0 * -0.0 == 0.0.
Value *X;
-  if (FMF.isFast() && Op0 == Op1 &&
-      match(Op0, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))))
+  if (Op0 == Op1 && match(Op0, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))) &&
+      FMF.allowReassoc() && FMF.noNaNs() && FMF.noSignedZeros())
return X;

return nullptr;

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43765.135904.patch
Type: text/x-patch
Size: 1592 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180226/879b5421/attachment.bin>
```