mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
[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
This commit is contained in:
parent
20ae0dcecf
commit
22610cd767
@ -1630,6 +1630,8 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
|
|||||||
return ConstantFoldFP(sin, V, Ty);
|
return ConstantFoldFP(sin, V, Ty);
|
||||||
case Intrinsic::cos:
|
case Intrinsic::cos:
|
||||||
return ConstantFoldFP(cos, V, Ty);
|
return ConstantFoldFP(cos, V, Ty);
|
||||||
|
case Intrinsic::sqrt:
|
||||||
|
return ConstantFoldFP(sqrt, V, Ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TLI)
|
if (!TLI)
|
||||||
@ -1683,19 +1685,6 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
|
|||||||
else if ((Name == "log10" && V > 0 && TLI->has(LibFunc::log10)) ||
|
else if ((Name == "log10" && V > 0 && TLI->has(LibFunc::log10)) ||
|
||||||
(Name == "log10f" && V > 0 && TLI->has(LibFunc::log10f)))
|
(Name == "log10f" && V > 0 && TLI->has(LibFunc::log10f)))
|
||||||
return ConstantFoldFP(log10, V, Ty);
|
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;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
if ((Name == "round" && TLI->has(LibFunc::round)) ||
|
if ((Name == "round" && TLI->has(LibFunc::round)) ||
|
||||||
|
@ -45,9 +45,10 @@ define double @constant_fold_fmuladd_f64() #0 {
|
|||||||
ret double %x
|
ret double %x
|
||||||
}
|
}
|
||||||
|
|
||||||
; The sqrt intrinsic is undefined for negative inputs besides -0.0.
|
; Currently we don't constant-fold intrinsics whose corresponding libcalls
|
||||||
|
; raise an fp exception.
|
||||||
; CHECK-LABEL: @bad_sqrt
|
; CHECK-LABEL: @bad_sqrt
|
||||||
; CHECK-NEXT: ret double undef
|
; CHECK-NEXT: call double @llvm.sqrt.f64(double -2
|
||||||
define double @bad_sqrt() {
|
define double @bad_sqrt() {
|
||||||
%x = call double @llvm.sqrt.f64(double -2.000000e+00)
|
%x = call double @llvm.sqrt.f64(double -2.000000e+00)
|
||||||
ret double %x
|
ret double %x
|
||||||
|
Loading…
Reference in New Issue
Block a user