[llvm] Create more optimizing functions to fold inverse pairs (PR #77799)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 11 11:04:21 PST 2024
https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/77799
>From 146d5bc6c8c1de12821a85f9b63665eae2b0a6a5 Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Thu, 11 Jan 2024 12:14:31 -0500
Subject: [PATCH] [Transforms] Create more optimizing functions to fold inverse
pairs
I don't know if I should merge this with optimizeTan since the logic is almost the same, but then that would make the name optimizeTan a bad one and I do not know what would be a better fit.
Sadly, this is not mathmatically true for the non-hyperbolic versions, or tanh. However, atanh(tanh(x)) does fold to x.
atanh(tanh(x)) is x. Note this is not tanh(atanh(x)), as that only works if x is between -1 and 1.
---
.../llvm/Transforms/Utils/SimplifyLibCalls.h | 3 +
.../lib/Transforms/Utils/SimplifyLibCalls.cpp | 108 +++++++++++++++++-
2 files changed, 108 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index eb10545ee149e4..50ec6425fdeb23 100644
--- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -203,6 +203,9 @@ class LibCallSimplifier {
Value *optimizeSqrt(CallInst *CI, IRBuilderBase &B);
Value *optimizeSinCosPi(CallInst *CI, bool IsSin, IRBuilderBase &B);
Value *optimizeTan(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeSinh(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeCosh(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeATanh(CallInst *CI, IRBuilderBase &B);
// Wrapper for all floating point library call optimizations
Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func,
IRBuilderBase &B);
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index a7cd68e860e467..02626202ee5e9f 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -2635,6 +2635,99 @@ Value *LibCallSimplifier::optimizeTan(CallInst *CI, IRBuilderBase &B) {
return Ret;
}
+Value *LibCallSimplifier::optimizeSinh(CallInst *CI, IRBuilderBase &B) {
+ Module *M = CI->getModule();
+ Function *Callee = CI->getCalledFunction();
+ Value *Ret = nullptr;
+ StringRef Name = Callee->getName();
+ if (UnsafeFPShrink && Name == "sinh" && hasFloatVersion(M, Name))
+ Ret = optimizeUnaryDoubleFP(CI, B, TLI, true);
+
+ Value *Op1 = CI->getArgOperand(0);
+ auto *OpC = dyn_cast<CallInst>(Op1);
+ if (!OpC)
+ return Ret;
+
+ // Both calls must be 'fast' in order to remove them.
+ if (!CI->isFast() || !OpC->isFast())
+ return Ret;
+
+ // sinh(asinh(x)) -> x
+ // sinhf(asinhf(x)) -> x
+ // sinhl(asinhl(x)) -> x
+ LibFunc Func;
+ Function *F = OpC->getCalledFunction();
+ if (F && TLI->getLibFunc(F->getName(), Func) &&
+ isLibFuncEmittable(M, TLI, Func) &&
+ ((Func == LibFunc_asinh && Callee->getName() == "sinh") ||
+ (Func == LibFunc_asinhf && Callee->getName() == "sinhf") ||
+ (Func == LibFunc_asinhl && Callee->getName() == "sinhl")))
+ Ret = OpC->getArgOperand(0);
+ return Ret;
+}
+
+Value *LibCallSimplifier::optimizeCosh(CallInst *CI, IRBuilderBase &B) {
+ Module *M = CI->getModule();
+ Function *Callee = CI->getCalledFunction();
+ Value *Ret = nullptr;
+ StringRef Name = Callee->getName();
+ if (UnsafeFPShrink && Name == "cosh" && hasFloatVersion(M, Name))
+ Ret = optimizeUnaryDoubleFP(CI, B, TLI, true);
+
+ Value *Op1 = CI->getArgOperand(0);
+ auto *OpC = dyn_cast<CallInst>(Op1);
+ if (!OpC)
+ return Ret;
+
+ // Both calls must be 'fast' in order to remove them.
+ if (!CI->isFast() || !OpC->isFast())
+ return Ret;
+
+ // cosh(acosh(x)) -> x
+ // coshf(acoshf(x)) -> x
+ // coshl(acoshl(x)) -> x
+ LibFunc Func;
+ Function *F = OpC->getCalledFunction();
+ if (F && TLI->getLibFunc(F->getName(), Func) &&
+ isLibFuncEmittable(M, TLI, Func) &&
+ ((Func == LibFunc_acosh && Callee->getName() == "cosh") ||
+ (Func == LibFunc_acoshf && Callee->getName() == "coshf") ||
+ (Func == LibFunc_acoshl && Callee->getName() == "coshl")))
+ Ret = OpC->getArgOperand(0);
+ return Ret;
+}
+
+Value *LibCallSimplifier::optimizeATanh(CallInst *CI, IRBuilderBase &B) {
+ Module *M = CI->getModule();
+ Function *Callee = CI->getCalledFunction();
+ Value *Ret = nullptr;
+ StringRef Name = Callee->getName();
+ if (UnsafeFPShrink && Name == "atanh" && hasFloatVersion(M, Name))
+ Ret = optimizeUnaryDoubleFP(CI, B, TLI, true);
+
+ Value *Op1 = CI->getArgOperand(0);
+ auto *OpC = dyn_cast<CallInst>(Op1);
+ if (!OpC)
+ return Ret;
+
+ // Both calls must be 'fast' in order to remove them.
+ if (!CI->isFast() || !OpC->isFast())
+ return Ret;
+
+ // atanh(tanh(x)) -> x
+ // atanhf(tanhf(x)) -> x
+ // atanhl(tanhl(x)) -> x
+ LibFunc Func;
+ Function *F = OpC->getCalledFunction();
+ if (F && TLI->getLibFunc(F->getName(), Func) &&
+ isLibFuncEmittable(M, TLI, Func) &&
+ ((Func == LibFunc_tanh && Callee->getName() == "atanh") ||
+ (Func == LibFunc_tanhf && Callee->getName() == "atanhf") ||
+ (Func == LibFunc_tanhl && Callee->getName() == "atanhl")))
+ Ret = OpC->getArgOperand(0);
+ return Ret;
+}
+
static bool isTrigLibCall(CallInst *CI) {
// We can only hope to do anything useful if we can ignore things like errno
// and floating-point exceptions.
@@ -3625,6 +3718,18 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
case LibFunc_tanf:
case LibFunc_tanl:
return optimizeTan(CI, Builder);
+ case LibFunc_sinh:
+ case LibFunc_sinhf:
+ case LibFunc_sinhl:
+ return optimizeSinh(CI, Builder);
+ case LibFunc_cosh:
+ case LibFunc_coshf:
+ case LibFunc_coshl:
+ return optimizeCosh(CI, Builder);
+ case LibFunc_atanh:
+ case LibFunc_tanhf:
+ case LibFunc_tanhl:
+ return optimizeATanh(CI, Builder);
case LibFunc_ceil:
return replaceUnaryCall(CI, Builder, Intrinsic::ceil);
case LibFunc_floor:
@@ -3644,15 +3749,12 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
case LibFunc_asin:
case LibFunc_asinh:
case LibFunc_atan:
- case LibFunc_atanh:
case LibFunc_cbrt:
- case LibFunc_cosh:
case LibFunc_exp:
case LibFunc_exp10:
case LibFunc_expm1:
case LibFunc_cos:
case LibFunc_sin:
- case LibFunc_sinh:
case LibFunc_tanh:
if (UnsafeFPShrink && hasFloatVersion(M, CI->getCalledFunction()->getName()))
return optimizeUnaryDoubleFP(CI, Builder, TLI, true);
More information about the llvm-commits
mailing list