[llvm-branch-commits] [llvm] [InstCombine] Fold exp2(uitofp iN x) to ldexp when N equals the width of int (PR #227380)
Eric Ross via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Sep 30 09:47:52 PDT 2026
================
@@ -2633,28 +2633,43 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) {
// exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= IntSize
// exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < IntSize
+ // exp2(uitofp(x)) -> ldexp(1.0, umin(x, C)) if sizeof(x) == IntSize
Value *Op = CI->getArgOperand(0);
- if ((isa<SIToFPInst>(Op) || isa<UIToFPInst>(Op)) &&
- (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);
+ if (!isa<SIToFPInst, UIToFPInst>(Op) ||
+ (!UseIntrinsic &&
+ !hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)))
+ return Ret;
- if (UseIntrinsic) {
- return copyFlags(*CI, B.CreateIntrinsic(Intrinsic::ldexp,
- {Ty, Exp->getType()},
- {One, Exp}, CI));
- }
+ unsigned IntSize = TLI->getIntSize();
+ Value *Exp = getIntToFPVal(Op, B, IntSize);
+ Value *UIntOp = nullptr;
+ // A uitofp source as wide as int may exceed INT_MAX, so clamp it for ldexp.
+ if (!Exp && UseIntrinsic && match(Op, m_UIToFP(m_Value(UIntOp))) &&
+ UIntOp->getType()->getScalarSizeInBits() == IntSize) {
+ const fltSemantics &Sem = Ty->getScalarType()->getFltSemantics();
+ // exp2(x) and ldexp(1.0, Clamp) both overflow for every x >= Clamp.
+ int Clamp = llvm::ilogb(APFloat::getLargest(Sem)) + 1;
----------------
ZERICO2005 wrote:
> Isn't it equal to `APFloat::semanticsMaxExponent + 1`?
Yes except for `semFloat8E8M0FNU` since it can only represent exact powers of two.
https://github.com/llvm/llvm-project/pull/227380
More information about the llvm-branch-commits
mailing list