[PATCH] D28929: [ConstantFolding] Constant-fold llvm.sqrt(x) like other intrinsics.

Justin Lebar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 19 16:50:22 PST 2017


jlebar created this revision.

Currently we return undef, but we're in the process of changing the
LangRef so that llvm.sqrt behaves like the other math intrinsics,
matching the return value of the standard libcall but not setting errno.

This change is legal even without the LangRef change because currently
calling llvm.sqrt(x) where x is negative is spec'ed to be UB.  But in
practice it's also safe because we're simply constant-folding fewer
inputs: Inputs >= -0 get constant-folded as before, but inputs < -0 now
aren't constant-folded, because ConstantFoldFP aborts if the host math
function raises an fp exception.


https://reviews.llvm.org/D28929

Files:
  llvm/lib/Analysis/ConstantFolding.cpp
  llvm/test/Transforms/InstCombine/constant-fold-math.ll


Index: llvm/test/Transforms/InstCombine/constant-fold-math.ll
===================================================================
--- llvm/test/Transforms/InstCombine/constant-fold-math.ll
+++ llvm/test/Transforms/InstCombine/constant-fold-math.ll
@@ -7,8 +7,6 @@
 declare double @llvm.fma.f64(double, double, double) #0
 declare double @llvm.fmuladd.f64(double, double, double) #0
 
-declare double @llvm.sqrt.f64(double) #0
-
 
 ; CHECK-LABEL: @constant_fold_fma_f32
 ; CHECK-NEXT: ret float 6.000000e+00
@@ -45,12 +43,4 @@
   ret double %x
 }
 
-; The sqrt intrinsic is undefined for negative inputs besides -0.0.
-; CHECK-LABEL: @bad_sqrt
-; CHECK-NEXT: ret double undef
-define double @bad_sqrt() {
-  %x = call double @llvm.sqrt.f64(double -2.000000e+00)
-  ret double %x
-}
-
 attributes #0 = { nounwind readnone }
Index: llvm/lib/Analysis/ConstantFolding.cpp
===================================================================
--- llvm/lib/Analysis/ConstantFolding.cpp
+++ llvm/lib/Analysis/ConstantFolding.cpp
@@ -1630,6 +1630,8 @@
           return ConstantFoldFP(sin, V, Ty);
         case Intrinsic::cos:
           return ConstantFoldFP(cos, V, Ty);
+        case Intrinsic::sqrt:
+          return ConstantFoldFP(sqrt, V, Ty);
       }
 
       if (!TLI)
@@ -1683,19 +1685,6 @@
         else if ((Name == "log10" && V > 0 && TLI->has(LibFunc::log10)) ||
                  (Name == "log10f" && V > 0 && TLI->has(LibFunc::log10f)))
           return ConstantFoldFP(log10, V, Ty);
-        else if (IntrinsicID == Intrinsic::sqrt &&
-                 (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy())) {
-          if (V >= -0.0)
-            return ConstantFoldFP(sqrt, V, Ty);
-          else {
-            // Unlike the sqrt definitions in C/C++, POSIX, and IEEE-754 - which
-            // all guarantee or favor returning NaN - the square root of a
-            // negative number is not defined for the LLVM sqrt intrinsic.
-            // This is because the intrinsic should only be emitted in place of
-            // libm's sqrt function when using "no-nans-fp-math".
-            return UndefValue::get(Ty);
-          }
-        }
         break;
       case 'r':
         if ((Name == "round" && TLI->has(LibFunc::round)) ||


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28929.85064.patch
Type: text/x-patch
Size: 2256 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170120/22740e6e/attachment.bin>


More information about the llvm-commits mailing list