summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2017-01-09 21:55:23 +0000
committerDavide Italiano <davide@freebsd.org>2017-01-09 21:55:23 +0000
commit472684eaf5b3e8aba189b38956912b4ee802c526 (patch)
tree16c529b39c9b250bb50518ea7cff4b73610fe959 /llvm
parentd4b24eda73e10a72058a123ce364ad241d03dd63 (diff)
downloadbcm5719-llvm-472684eaf5b3e8aba189b38956912b4ee802c526.tar.gz
bcm5719-llvm-472684eaf5b3e8aba189b38956912b4ee802c526.zip
[SimplifyLibCalls] pow(x, -0.5) -> 1.0 / sqrt(x).
Differential Revision: https://reviews.llvm.org/D28479 llvm-svn: 291486
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp18
-rw-r--r--llvm/test/Transforms/InstCombine/pow-sqrt.ll11
2 files changed, 28 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 11d54bcf4f8..5237ce5b399 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -1074,6 +1074,24 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) {
if (Op2C->getValueAPF().isZero()) // pow(x, 0.0) -> 1.0
return ConstantFP::get(CI->getType(), 1.0);
+ if (Op2C->isExactlyValue(-0.5) &&
+ hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf,
+ LibFunc::sqrtl)) {
+ // If -ffast-math:
+ // pow(x, -0.5) -> 1.0 / sqrt(x)
+ if (CI->hasUnsafeAlgebra()) {
+ IRBuilder<>::FastMathFlagGuard Guard(B);
+ B.setFastMathFlags(CI->getFastMathFlags());
+
+ // Here we cannot lower to an intrinsic because C99 sqrt() and llvm.sqrt
+ // are not guaranteed to have the same semantics.
+ Value *Sqrt = emitUnaryFloatFnCall(Op1, TLI->getName(LibFunc::sqrt), B,
+ Callee->getAttributes());
+
+ return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), Sqrt, "sqrtrecip");
+ }
+ }
+
if (Op2C->isExactlyValue(0.5) &&
hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf,
LibFunc::sqrtl) &&
diff --git a/llvm/test/Transforms/InstCombine/pow-sqrt.ll b/llvm/test/Transforms/InstCombine/pow-sqrt.ll
index 1e6166c5f11..52175f1b124 100644
--- a/llvm/test/Transforms/InstCombine/pow-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/pow-sqrt.ll
@@ -9,5 +9,14 @@ define double @pow_half(double %x) {
; CHECK-NEXT: %sqrt = call fast double @sqrt(double %x)
; CHECK-NEXT: ret double %sqrt
-declare double @llvm.pow.f64(double, double)
+define double @pow_neghalf(double %x) {
+ %pow = call fast double @llvm.pow.f64(double %x, double -5.000000e-01)
+ ret double %pow
+}
+; CHECK-LABEL: define double @pow_neghalf(
+; CHECK-NEXT: %sqrt = call fast double @sqrt(double %x) #0
+; CHECK-NEXT: %sqrtrecip = fdiv fast double 1.000000e+00, %sqrt
+; CHECK-NEXT: ret double %sqrtrecip
+
+declare double @llvm.pow.f64(double, double)
OpenPOWER on IntegriCloud