[PATCH] D86726: [InstCombine]: Transform 1.0/sqrt(X) * X to X/sqrt(X) and X * 1.0/sqrt(X) to X/sqrt(X)

Venkataramanan Kumar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 31 23:11:46 PDT 2020


venkataramanan.kumar.llvm updated this revision to Diff 289077.
venkataramanan.kumar.llvm added a comment.

Updated the patch with "nsz" check .


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86726/new/

https://reviews.llvm.org/D86726

Files:
  llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
  llvm/test/Transforms/InstCombine/fmul-sqrt.ll


Index: llvm/test/Transforms/InstCombine/fmul-sqrt.ll
===================================================================
--- llvm/test/Transforms/InstCombine/fmul-sqrt.ll
+++ llvm/test/Transforms/InstCombine/fmul-sqrt.ll
@@ -103,13 +103,13 @@
 ; CHECK-LABEL: @rsqrt_x_reassociate_extra_use(
 ; CHECK-NEXT:    [[SQRT:%.*]] = call fast double @llvm.sqrt.f64(double [[X:%.*]])
 ; CHECK-NEXT:    [[RSQRT:%.*]] = fdiv fast double 1.000000e+00, [[SQRT]]
-; CHECK-NEXT:    [[RES:%.*]] = fmul reassoc double [[RSQRT]], [[X:%.*]]
+; CHECK-NEXT:    [[RES:%.*]] = fdiv reassoc nsz double [[X:%.*]], [[SQRT]] 
 ; CHECK-NEXT:    store double [[RSQRT]], double* %p
 ; CHECK-NEXT:    ret double [[RES]]
 ;
   %sqrt = call fast double @llvm.sqrt.f64(double %x)
   %rsqrt = fdiv fast double 1.0, %sqrt
-  %res = fmul reassoc double %rsqrt, %x
+  %res = fmul reassoc nsz double %rsqrt, %x
   store double %rsqrt, double* %p
   ret double %res
 }
@@ -119,14 +119,14 @@
 ; CHECK-NEXT:    [[ADD:%.*]] = fadd fast double %x, %y
 ; CHECK-NEXT:    [[SQRT:%.*]] = call fast double @llvm.sqrt.f64(double [[ADD]])
 ; CHECK-NEXT:    [[RSQRT:%.*]] = fdiv fast double 1.000000e+00, [[SQRT]]
-; CHECK-NEXT:    [[RES:%.*]] = fmul reassoc double [[ADD]], [[RSQRT]]
+; CHECK-NEXT:    [[RES:%.*]] = fdiv reassoc nsz double [[ADD]], [[SQRT]]
 ; CHECK-NEXT:    store double [[RSQRT]], double* %p
 ; CHECK-NEXT:    ret double [[RES]]
 ;
   %add = fadd fast double %x, %y ; thwart complexity-based canonicalization
   %sqrt = call fast double @llvm.sqrt.f64(double %add)
   %rsqrt = fdiv fast double 1.0, %sqrt
-  %res = fmul reassoc double %add, %rsqrt
+  %res = fmul reassoc nsz double %add, %rsqrt
   store double %rsqrt, double* %p
   ret double %res
 }
Index: llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -544,6 +544,21 @@
       return replaceInstUsesWith(I, Sqrt);
     }
 
+    // The following transforms are done irrespective of the number of uses
+    // for the expression "1.0/sqrt(X)".
+    //  1) 1.0/sqrt(X) * X -> X/sqrt(X)
+    //  2) X * 1.0/sqrt(X) -> X/sqrt(X)
+    // We always expect the backend to reduce X/sqrt(X) to sqrt(X), if it
+    // has the necessary (reassoc) fast-math-flags.
+    if (I.hasNoSignedZeros() &&
+        match(Op0, (m_FDiv(m_SpecificFP(1.0), m_Value(Y)))) &&
+        match(Y, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))) && Op1 == X)
+      return BinaryOperator::CreateFDivFMF(X, Y, &I);
+    if (I.hasNoSignedZeros() &&
+        match(Op1, (m_FDiv(m_SpecificFP(1.0), m_Value(Y)))) &&
+        match(Y, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))) && Op0 == X)
+      return BinaryOperator::CreateFDivFMF(X, Y, &I);
+
     // 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 &&


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D86726.289077.patch
Type: text/x-patch
Size: 3042 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200901/563e97a3/attachment.bin>


More information about the llvm-commits mailing list