Skip to content

Commit 8b18a34

Browse files
author
Justin Lebar
committed
[ConstantFolding] Constant-fold llvm.sqrt(x) like other intrinsics.
Summary: 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. Reviewers: hfinkel, efriedma, sanjoy Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D28929 llvm-svn: 292692
1 parent da57dbf commit 8b18a34

File tree

2 files changed

+5
-15
lines changed

2 files changed

+5
-15
lines changed

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,8 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
16301630
return ConstantFoldFP(sin, V, Ty);
16311631
case Intrinsic::cos:
16321632
return ConstantFoldFP(cos, V, Ty);
1633+
case Intrinsic::sqrt:
1634+
return ConstantFoldFP(sqrt, V, Ty);
16331635
}
16341636

16351637
if (!TLI)
@@ -1683,19 +1685,6 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
16831685
else if ((Name == "log10" && V > 0 && TLI->has(LibFunc::log10)) ||
16841686
(Name == "log10f" && V > 0 && TLI->has(LibFunc::log10f)))
16851687
return ConstantFoldFP(log10, V, Ty);
1686-
else if (IntrinsicID == Intrinsic::sqrt &&
1687-
(Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy())) {
1688-
if (V >= -0.0)
1689-
return ConstantFoldFP(sqrt, V, Ty);
1690-
else {
1691-
// Unlike the sqrt definitions in C/C++, POSIX, and IEEE-754 - which
1692-
// all guarantee or favor returning NaN - the square root of a
1693-
// negative number is not defined for the LLVM sqrt intrinsic.
1694-
// This is because the intrinsic should only be emitted in place of
1695-
// libm's sqrt function when using "no-nans-fp-math".
1696-
return UndefValue::get(Ty);
1697-
}
1698-
}
16991688
break;
17001689
case 'r':
17011690
if ((Name == "round" && TLI->has(LibFunc::round)) ||

llvm/test/Transforms/InstCombine/constant-fold-math.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ define double @constant_fold_fmuladd_f64() #0 {
4545
ret double %x
4646
}
4747

48-
; The sqrt intrinsic is undefined for negative inputs besides -0.0.
48+
; Currently we don't constant-fold intrinsics whose corresponding libcalls
49+
; raise an fp exception.
4950
; CHECK-LABEL: @bad_sqrt
50-
; CHECK-NEXT: ret double undef
51+
; CHECK-NEXT: call double @llvm.sqrt.f64(double -2
5152
define double @bad_sqrt() {
5253
%x = call double @llvm.sqrt.f64(double -2.000000e+00)
5354
ret double %x

0 commit comments

Comments
 (0)