aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2024-06-10 18:21:20 +0200
committerGitHub <noreply@github.com>2024-06-10 18:21:20 +0200
commit8788b666aaaf4658bbaab7459968ba2bca13f529 (patch)
tree9fbd89ca9ebb933f844f2077733e42d66a85f404 /llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
parentd63ade63b661e09cb1379d48cb3e49851fdf2509 (diff)
downloadllvm-8788b666aaaf4658bbaab7459968ba2bca13f529.zip
llvm-8788b666aaaf4658bbaab7459968ba2bca13f529.tar.gz
llvm-8788b666aaaf4658bbaab7459968ba2bca13f529.tar.bz2
SimplifyLibCalls: Don't require ldexp to emit intrinsic in exp2 combine (#92707)
When folding exp2(itofp(x)) to ldexp(1, x), don't require an ldexp libcall to emit the intrinsic. The intrinsic needs to be handled regardless of whether the system has a libcall, and we have an inline implementation of ldexp already. This fixes the instance in the exp2->ldexp fold. Another instance exists for the pow(2) -> ldexp case The LTO test change isn't ideal, since it's just moving the problem to another instance where we're relying on implied libm behavior for an intrinsic transform. Use exp10 since that's a harder case to solve in the libcall house of cards we have.
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index eb1224a..a91c3ff 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -2376,7 +2376,13 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) {
hasFloatVersion(M, Name))
Ret = optimizeUnaryDoubleFP(CI, B, TLI, true);
- const bool UseIntrinsic = CI->doesNotAccessMemory();
+ // If we have an llvm.exp2 intrinsic, emit the llvm.ldexp intrinsic. If we
+ // have the libcall, emit the libcall.
+ //
+ // TODO: In principle we should be able to just always use the intrinsic for
+ // any doesNotAccessMemory callsite.
+
+ const bool UseIntrinsic = Callee->isIntrinsic();
// Bail out for vectors because the code below only expects scalars.
Type *Ty = CI->getType();
if (!UseIntrinsic && Ty->isVectorTy())
@@ -2386,12 +2392,11 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) {
// exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < IntSize
Value *Op = CI->getArgOperand(0);
if ((isa<SIToFPInst>(Op) || isa<UIToFPInst>(Op)) &&
- hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
+ (UseIntrinsic ||
+ hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
if (Value *Exp = getIntToFPVal(Op, B, TLI->getIntSize())) {
Constant *One = ConstantFP::get(Ty, 1.0);
- // TODO: Emitting the intrinsic should not depend on whether the libcall
- // is available.
if (UseIntrinsic) {
return copyFlags(*CI, B.CreateIntrinsic(Intrinsic::ldexp,
{Ty, Exp->getType()},