[llvm] r320901 - [SimplifyLibCalls] Inline calls to cabs when it's safe to do so
Hal Finkel via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 15 17:26:25 PST 2017
Author: hfinkel
Date: Fri Dec 15 17:26:25 2017
New Revision: 320901
URL: http://llvm.org/viewvc/llvm-project?rev=320901&view=rev
Log:
[SimplifyLibCalls] Inline calls to cabs when it's safe to do so
When unsafe algerbra is allowed calls to cabs(r) can be replaced by:
sqrt(creal(r)*creal(r) + cimag(r)*cimag(r))
Patch by Paul Walker, thanks!
Differential Revision: https://reviews.llvm.org/D40069
Added:
llvm/trunk/test/Transforms/InstCombine/cabs-array.ll
llvm/trunk/test/Transforms/InstCombine/cabs-discrete.ll
Modified:
llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.def
llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp
llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
llvm/trunk/unittests/Analysis/TargetLibraryInfoTest.cpp
Modified: llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.def?rev=320901&r1=320900&r2=320901&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.def (original)
+++ llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.def Fri Dec 15 17:26:25 2017
@@ -457,6 +457,15 @@ TLI_DEFINE_STRING_INTERNAL("bcopy")
/// void bzero(void *s, size_t n);
TLI_DEFINE_ENUM_INTERNAL(bzero)
TLI_DEFINE_STRING_INTERNAL("bzero")
+/// double cabs(double complex z)
+TLI_DEFINE_ENUM_INTERNAL(cabs)
+TLI_DEFINE_STRING_INTERNAL("cabs")
+/// float cabs(float complex z)
+TLI_DEFINE_ENUM_INTERNAL(cabsf)
+TLI_DEFINE_STRING_INTERNAL("cabsf")
+/// long double cabs(long double complex z)
+TLI_DEFINE_ENUM_INTERNAL(cabsl)
+TLI_DEFINE_STRING_INTERNAL("cabsl")
/// void *calloc(size_t count, size_t size);
TLI_DEFINE_ENUM_INTERNAL(calloc)
TLI_DEFINE_STRING_INTERNAL("calloc")
Modified: llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h?rev=320901&r1=320900&r2=320901&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h Fri Dec 15 17:26:25 2017
@@ -129,6 +129,7 @@ private:
Value *optimizeStringMemoryLibCall(CallInst *CI, IRBuilder<> &B);
// Math Library Optimizations
+ Value *optimizeCAbs(CallInst *CI, IRBuilder<> &B);
Value *optimizeCos(CallInst *CI, IRBuilder<> &B);
Value *optimizePow(CallInst *CI, IRBuilder<> &B);
Value *replacePowWithSqrt(CallInst *Pow, IRBuilder<> &B);
Modified: llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp?rev=320901&r1=320900&r2=320901&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp Fri Dec 15 17:26:25 2017
@@ -182,6 +182,9 @@ static void initialize(TargetLibraryInfo
TLI.setUnavailable(LibFunc_atanh);
TLI.setUnavailable(LibFunc_atanhf);
TLI.setUnavailable(LibFunc_atanhl);
+ TLI.setUnavailable(LibFunc_cabs);
+ TLI.setUnavailable(LibFunc_cabsf);
+ TLI.setUnavailable(LibFunc_cabsl);
TLI.setUnavailable(LibFunc_cbrt);
TLI.setUnavailable(LibFunc_cbrtf);
TLI.setUnavailable(LibFunc_cbrtl);
@@ -1267,6 +1270,25 @@ bool TargetLibraryInfoImpl::isValidProto
return (NumParams == 1 && FTy.getParamType(0)->isPointerTy() &&
FTy.getReturnType()->isIntegerTy());
+ case LibFunc_cabs:
+ case LibFunc_cabsf:
+ case LibFunc_cabsl: {
+ Type* RetTy = FTy.getReturnType();
+ if (!RetTy->isFloatingPointTy())
+ return false;
+
+ // NOTE: These prototypes are target specific and currently support
+ // "complex" passed as an array or discrete real & imaginary parameters.
+ // Add other calling conventions to enable libcall optimizations.
+ if (NumParams == 1)
+ return (FTy.getParamType(0)->isArrayTy() &&
+ FTy.getParamType(0)->getArrayNumElements() == 2 &&
+ FTy.getParamType(0)->getArrayElementType() == RetTy);
+ else if (NumParams == 2)
+ return (FTy.getParamType(0) == RetTy && FTy.getParamType(1) == RetTy);
+ else
+ return false;
+ }
case LibFunc::NumLibFuncs:
break;
}
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=320901&r1=320900&r2=320901&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Fri Dec 15 17:26:25 2017
@@ -1033,6 +1033,35 @@ static Value *optimizeBinaryDoubleFP(Cal
return B.CreateFPExt(V, B.getDoubleTy());
}
+// cabs(z) -> sqrt((creal(z)*creal(z)) + (cimag(z)*cimag(z)))
+Value *LibCallSimplifier::optimizeCAbs(CallInst *CI, IRBuilder<> &B) {
+ if (!CI->isFast())
+ return nullptr;
+
+ // Propagate fast-math flags from the existing call to new instructions.
+ IRBuilder<>::FastMathFlagGuard Guard(B);
+ B.setFastMathFlags(CI->getFastMathFlags());
+
+ Value *Real, *Imag;
+ if (CI->getNumArgOperands() == 1) {
+ Value *Op = CI->getArgOperand(0);
+ assert(Op->getType()->isArrayTy() && "Unexpected signature for cabs!");
+ Real = B.CreateExtractValue(Op, 0, "real");
+ Imag = B.CreateExtractValue(Op, 1, "imag");
+ } else {
+ assert(CI->getNumArgOperands() == 2 && "Unexpected signature for cabs!");
+ Real = CI->getArgOperand(0);
+ Imag = CI->getArgOperand(1);
+ }
+
+ Value *RealReal = B.CreateFMul(Real, Real);
+ Value *ImagImag = B.CreateFMul(Imag, Imag);
+
+ Function *FSqrt = Intrinsic::getDeclaration(CI->getModule(), Intrinsic::sqrt,
+ CI->getType());
+ return B.CreateCall(FSqrt, B.CreateFAdd(RealReal, ImagImag), "cabs");
+}
+
Value *LibCallSimplifier::optimizeCos(CallInst *CI, IRBuilder<> &B) {
Function *Callee = CI->getCalledFunction();
Value *Ret = nullptr;
@@ -2162,6 +2191,10 @@ Value *LibCallSimplifier::optimizeFloati
case LibFunc_fmax:
case LibFunc_fmaxl:
return optimizeFMinFMax(CI, Builder);
+ case LibFunc_cabs:
+ case LibFunc_cabsf:
+ case LibFunc_cabsl:
+ return optimizeCAbs(CI, Builder);
default:
return nullptr;
}
Added: llvm/trunk/test/Transforms/InstCombine/cabs-array.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cabs-array.ll?rev=320901&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/cabs-array.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/cabs-array.ll Fri Dec 15 17:26:25 2017
@@ -0,0 +1,65 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+define double @std_cabs([2 x double] %z) {
+; CHECK-LABEL: define double @std_cabs(
+; CHECK: tail call double @cabs(
+ %call = tail call double @cabs([2 x double] %z)
+ ret double %call
+}
+
+define float @std_cabsf([2 x float] %z) {
+; CHECK-LABEL: define float @std_cabsf(
+; CHECK: tail call float @cabsf(
+ %call = tail call float @cabsf([2 x float] %z)
+ ret float %call
+}
+
+define fp128 @std_cabsl([2 x fp128] %z) {
+; CHECK-LABEL: define fp128 @std_cabsl(
+; CHECK: tail call fp128 @cabsl(
+ %call = tail call fp128 @cabsl([2 x fp128] %z)
+ ret fp128 %call
+}
+
+define double @fast_cabs([2 x double] %z) {
+; CHECK-LABEL: define double @fast_cabs(
+; CHECK: %real = extractvalue [2 x double] %z, 0
+; CHECK: %imag = extractvalue [2 x double] %z, 1
+; CHECK: %1 = fmul fast double %real, %real
+; CHECK: %2 = fmul fast double %imag, %imag
+; CHECK: %3 = fadd fast double %1, %2
+; CHECK: %cabs = call fast double @llvm.sqrt.f64(double %3)
+; CHECK: ret double %cabs
+ %call = tail call fast double @cabs([2 x double] %z)
+ ret double %call
+}
+
+define float @fast_cabsf([2 x float] %z) {
+; CHECK-LABEL: define float @fast_cabsf(
+; CHECK: %real = extractvalue [2 x float] %z, 0
+; CHECK: %imag = extractvalue [2 x float] %z, 1
+; CHECK: %1 = fmul fast float %real, %real
+; CHECK: %2 = fmul fast float %imag, %imag
+; CHECK: %3 = fadd fast float %1, %2
+; CHECK: %cabs = call fast float @llvm.sqrt.f32(float %3)
+; CHECK: ret float %cabs
+ %call = tail call fast float @cabsf([2 x float] %z)
+ ret float %call
+}
+
+define fp128 @fast_cabsl([2 x fp128] %z) {
+; CHECK-LABEL: define fp128 @fast_cabsl(
+; CHECK: %real = extractvalue [2 x fp128] %z, 0
+; CHECK: %imag = extractvalue [2 x fp128] %z, 1
+; CHECK: %1 = fmul fast fp128 %real, %real
+; CHECK: %2 = fmul fast fp128 %imag, %imag
+; CHECK: %3 = fadd fast fp128 %1, %2
+; CHECK: %cabs = call fast fp128 @llvm.sqrt.f128(fp128 %3)
+; CHECK: ret fp128 %cabs
+ %call = tail call fast fp128 @cabsl([2 x fp128] %z)
+ ret fp128 %call
+}
+
+declare double @cabs([2 x double])
+declare float @cabsf([2 x float])
+declare fp128 @cabsl([2 x fp128])
Added: llvm/trunk/test/Transforms/InstCombine/cabs-discrete.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cabs-discrete.ll?rev=320901&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/cabs-discrete.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/cabs-discrete.ll Fri Dec 15 17:26:25 2017
@@ -0,0 +1,59 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+define double @std_cabs(double %real, double %imag) {
+; CHECK-LABEL: define double @std_cabs(
+; CHECK: tail call double @cabs(
+ %call = tail call double @cabs(double %real, double %imag)
+ ret double %call
+}
+
+define float @std_cabsf(float %real, float %imag) {
+; CHECK-LABEL: define float @std_cabsf(
+; CHECK: tail call float @cabsf(
+ %call = tail call float @cabsf(float %real, float %imag)
+ ret float %call
+}
+
+define fp128 @std_cabsl(fp128 %real, fp128 %imag) {
+; CHECK-LABEL: define fp128 @std_cabsl(
+; CHECK: tail call fp128 @cabsl(
+ %call = tail call fp128 @cabsl(fp128 %real, fp128 %imag)
+ ret fp128 %call
+}
+
+define double @fast_cabs(double %real, double %imag) {
+; CHECK-LABEL: define double @fast_cabs(
+; CHECK: %1 = fmul fast double %real, %real
+; CHECK: %2 = fmul fast double %imag, %imag
+; CHECK: %3 = fadd fast double %1, %2
+; CHECK: %cabs = call fast double @llvm.sqrt.f64(double %3)
+; CHECK: ret double %cabs
+ %call = tail call fast double @cabs(double %real, double %imag)
+ ret double %call
+}
+
+define float @fast_cabsf(float %real, float %imag) {
+; CHECK-LABEL: define float @fast_cabsf(
+; CHECK: %1 = fmul fast float %real, %real
+; CHECK: %2 = fmul fast float %imag, %imag
+; CHECK: %3 = fadd fast float %1, %2
+; CHECK: %cabs = call fast float @llvm.sqrt.f32(float %3)
+; CHECK: ret float %cabs
+ %call = tail call fast float @cabsf(float %real, float %imag)
+ ret float %call
+}
+
+define fp128 @fast_cabsl(fp128 %real, fp128 %imag) {
+; CHECK-LABEL: define fp128 @fast_cabsl(
+; CHECK: %1 = fmul fast fp128 %real, %real
+; CHECK: %2 = fmul fast fp128 %imag, %imag
+; CHECK: %3 = fadd fast fp128 %1, %2
+; CHECK: %cabs = call fast fp128 @llvm.sqrt.f128(fp128 %3)
+; CHECK: ret fp128 %cabs
+ %call = tail call fast fp128 @cabsl(fp128 %real, fp128 %imag)
+ ret fp128 %call
+}
+
+declare double @cabs(double %real, double %imag)
+declare float @cabsf(float %real, float %imag)
+declare fp128 @cabsl(fp128 %real, fp128 %imag)
Modified: llvm/trunk/unittests/Analysis/TargetLibraryInfoTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/TargetLibraryInfoTest.cpp?rev=320901&r1=320900&r2=320901&view=diff
==============================================================================
--- llvm/trunk/unittests/Analysis/TargetLibraryInfoTest.cpp (original)
+++ llvm/trunk/unittests/Analysis/TargetLibraryInfoTest.cpp Fri Dec 15 17:26:25 2017
@@ -131,6 +131,9 @@ TEST_F(TargetLibraryInfoTest, ValidProto
"declare double @copysign(double, double)\n"
"declare float @copysignf(float, float)\n"
"declare x86_fp80 @copysignl(x86_fp80, x86_fp80)\n"
+ "declare double @cabs([2 x double])\n"
+ "declare float @cabsf([2 x float])\n"
+ "declare x86_fp80 @cabsl([2 x x86_fp80])\n"
"declare double @cos(double)\n"
"declare float @cosf(float)\n"
"declare double @cosh(double)\n"
More information about the llvm-commits
mailing list