[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 02:21:31 PDT 2026


================
@@ -2507,10 +2507,74 @@ static Instruction *foldFPtoI(Instruction &FI, InstCombiner &IC) {
   return nullptr;
 }
 
+/// fpto{u/s}i (fdiv ({u/s}itofp X), C) --> {u/s}div X, C
+///
+/// Given N = integer width, p = FP mantissa width, this is safe if:
+/// Unsigned: C > 0 and N <= p.
+/// Signed: C != 0, N - 1 <= p, and not (X == INT_MIN and C == -1).
+/// Then {u/s}itofp is exact and the rounded quotient never crosses an integer,
+/// i.e. floor(rne_p(X/C)) == floor(X/C).
+///
+/// See #205305 for detailed reasoning.
+static Instruction *foldFPToIOfFDiv(Instruction &FI, InstCombinerImpl &IC,
+                                    bool IsSigned) {
+  auto *FDiv = dyn_cast<BinaryOperator>(FI.getOperand(0));
+  if (!FDiv || FDiv->getOpcode() != Instruction::FDiv || !FDiv->hasOneUse())
+    return nullptr;
+
+  auto *IToFP = dyn_cast<CastInst>(FDiv->getOperand(0));
+  if (!IToFP || !IToFP->hasOneUse())
+    return nullptr;
+  if (IsSigned ? !isa<SIToFPInst>(IToFP) : !isa<UIToFPInst>(IToFP))
+    return nullptr;
+  Value *X = IToFP->getOperand(0);
+  Type *IntTy = X->getType();
+  if (!IntTy->isIntOrIntVectorTy())
+    return nullptr;
+
+  if (FI.getType() != IntTy)
+    return nullptr;
+
+  Type *FPTy = FDiv->getType();
+  unsigned IntWidth = IntTy->getScalarSizeInBits();
+  int MantissaWidth = FPTy->getScalarType()->getFPMantissaWidth();
+  if (MantissaWidth < (int)IntWidth - IsSigned)
+    return nullptr;
+
+  auto *CFP = dyn_cast<ConstantFP>(FDiv->getOperand(1));
+  if (!CFP)
+    return nullptr;
+
+  APFloat APF = CFP->getValueAPF();
----------------
goranmoomin wrote:

Done in latest commit.

https://github.com/llvm/llvm-project/pull/205853


More information about the llvm-commits mailing list