diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2024-06-10 18:21:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-10 18:21:20 +0200 |
commit | 8788b666aaaf4658bbaab7459968ba2bca13f529 (patch) | |
tree | 9fbd89ca9ebb933f844f2077733e42d66a85f404 /llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | |
parent | d63ade63b661e09cb1379d48cb3e49851fdf2509 (diff) | |
download | llvm-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.cpp | 13 |
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()}, |