[llvm] r327797 - [InstCombine] add nnan requirement for sqrt(x) * sqrt(y) -> sqrt(x*y)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 18 07:32:54 PDT 2018


Author: spatel
Date: Sun Mar 18 07:32:54 2018
New Revision: 327797

URL: http://llvm.org/viewvc/llvm-project?rev=327797&view=rev
Log:
[InstCombine] add nnan requirement for sqrt(x) * sqrt(y) -> sqrt(x*y)

This is similar to D43765.

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

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=327797&r1=327796&r2=327797&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Sun Mar 18 07:32:54 2018
@@ -636,7 +636,9 @@ Instruction *InstCombiner::visitFMul(Bin
   }
 
   // sqrt(X) * sqrt(Y) -> sqrt(X * Y)
-  if (I.hasAllowReassoc() &&
+  // nnan disallows the possibility of returning a number if both operands are
+  // negative (in that case, we should return NaN).
+  if (I.hasAllowReassoc() && I.hasNoNaNs() &&
       match(Op0, m_OneUse(m_Intrinsic<Intrinsic::sqrt>(m_Value(X)))) &&
       match(Op1, m_OneUse(m_Intrinsic<Intrinsic::sqrt>(m_Value(Y))))) {
     Value *XY = Builder.CreateFMulFMF(X, Y, &I);

Modified: llvm/trunk/test/Transforms/InstCombine/fmul-sqrt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fmul-sqrt.ll?rev=327797&r1=327796&r2=327797&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fmul-sqrt.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fmul-sqrt.ll Sun Mar 18 07:32:54 2018
@@ -38,11 +38,27 @@ define double @sqrt_a_sqrt_b_multiple_us
 
 ; sqrt(a) * sqrt(b) => sqrt(a*b) with fast-math
 
+define double @sqrt_a_sqrt_b_reassoc_nnan(double %a, double %b) {
+; CHECK-LABEL: @sqrt_a_sqrt_b_reassoc_nnan(
+; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc nnan double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc nnan double @llvm.sqrt.f64(double [[TMP1]])
+; CHECK-NEXT:    ret double [[TMP2]]
+;
+  %1 = call double @llvm.sqrt.f64(double %a)
+  %2 = call double @llvm.sqrt.f64(double %b)
+  %mul = fmul reassoc nnan double %1, %2
+  ret double %mul
+}
+
+; nnan disallows the possibility that both operands are negative,
+; so we won't return a number when the answer should be NaN.
+
 define double @sqrt_a_sqrt_b_reassoc(double %a, double %b) {
 ; CHECK-LABEL: @sqrt_a_sqrt_b_reassoc(
-; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc double [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc double @llvm.sqrt.f64(double [[TMP1]])
-; CHECK-NEXT:    ret double [[TMP2]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.sqrt.f64(double [[B:%.*]])
+; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    ret double [[MUL]]
 ;
   %1 = call double @llvm.sqrt.f64(double %a)
   %2 = call double @llvm.sqrt.f64(double %b)
@@ -51,23 +67,23 @@ define double @sqrt_a_sqrt_b_reassoc(dou
 }
 
 ; sqrt(a) * sqrt(b) * sqrt(c) * sqrt(d) => sqrt(a*b*c*d) with fast-math
-; 'reassoc' on the fmuls is all that is required, but check propagation of other FMF.
+; 'reassoc nnan' on the fmuls is all that is required, but check propagation of other FMF.
 
 define double @sqrt_a_sqrt_b_sqrt_c_sqrt_d_reassoc(double %a, double %b, double %c, double %d) {
 ; CHECK-LABEL: @sqrt_a_sqrt_b_sqrt_c_sqrt_d_reassoc(
-; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc arcp double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc nnan arcp double [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nnan double [[TMP1]], [[C:%.*]]
-; CHECK-NEXT:    [[TMP3:%.*]] = fmul reassoc ninf double [[TMP2]], [[D:%.*]]
-; CHECK-NEXT:    [[TMP4:%.*]] = call reassoc ninf double @llvm.sqrt.f64(double [[TMP3]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul reassoc nnan ninf double [[TMP2]], [[D:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = call reassoc nnan ninf double @llvm.sqrt.f64(double [[TMP3]])
 ; CHECK-NEXT:    ret double [[TMP4]]
 ;
   %1 = call double @llvm.sqrt.f64(double %a)
   %2 = call double @llvm.sqrt.f64(double %b)
   %3 = call double @llvm.sqrt.f64(double %c)
   %4 = call double @llvm.sqrt.f64(double %d)
-  %mul = fmul reassoc arcp double %1, %2
+  %mul = fmul reassoc nnan arcp double %1, %2
   %mul1 = fmul reassoc nnan double %mul, %3
-  %mul2 = fmul reassoc ninf double %mul1, %4
+  %mul2 = fmul reassoc nnan ninf double %mul1, %4
   ret double %mul2
 }
 




More information about the llvm-commits mailing list