[llvm] [InstCombine] Fold fptoui (fdiv (uitofp X), C) to udiv X, C (PR #205853)
Sungbin Jo via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 5 09:03:44 PDT 2026
================
@@ -2504,7 +2504,64 @@ static Instruction *foldFPtoI(Instruction &FI, InstCombiner &IC) {
if (FPClass.isKnownNever(Mask))
return IC.replaceInstUsesWith(FI, ConstantInt::getNullValue(FI.getType()));
- return nullptr;
+ // fpto{u/s}i (fdiv ({u/s}itofp X to F), C_fp) --> {u/s}div X, C
+ //
+ // F has precision p (significand bits incl. hidden bit); C_fp is the exact FP
+ // value of the integer constant C. Given N = integer width, this is safe if:
+ // Unsigned: C > 0 and N <= p.
+ // Signed: C != 0 and N - 1 <= p, excluding (X == INT_MIN, C == -1) since
+ // sdiv INT_MIN, -1 is UB while the FP path only yields poison.
+ // fdiv X, -1 gets transformed to fneg in InstCombine regardless.
+ //
+ // The bounds make {u/s}itofp and C_fp exact (every |int| <= 2^p is exact),
+ // and ensure the rounded quotient never crosses an integer boundary:
+ // Rounding lemma: for 0 <= A <= 2^p, 1 <= B <= 2^p, q = floor(A/B),
+ // trunc(R_p(A/B)) = q.
+ // For r = A - qB > 0, m = q+1, half-gap H(m) <= q/2^p and
+ // m - A/B = (B-r)/B >= 1/B > q/2^p >= H(m), so R_p(A/B) < m; q = 0 is
+ // similar (H(1) = 2^(-p-1) < 2^-p <= 1/B).
+ // Signed case: by symmetry R_p(-z) = -R_p(z), so fptosi yields s*q = sdiv.
+ bool IsSigned = FI.getOpcode() == Instruction::FPToSI;
+ Value *X;
+ const APFloat *APF;
+ if (IsSigned) {
+ if (!match(FI.getOperand(0),
+ m_OneUse(m_FDiv(m_SIToFP(m_Value(X)), m_APFloat(APF)))))
+ return nullptr;
+ } else {
+ if (!match(FI.getOperand(0),
+ m_OneUse(m_FDiv(m_UIToFP(m_Value(X)), m_APFloat(APF)))))
+ return nullptr;
+ }
+ Type *IntTy = X->getType();
+ if (!IntTy->isIntOrIntVectorTy() || FI.getType() != IntTy)
----------------
goranmoomin wrote:
Done.
https://github.com/llvm/llvm-project/pull/205853
More information about the llvm-commits
mailing list