From decd49b20c24ab3c6f6490cb170e7f2795175149 Mon Sep 17 00:00:00 2001 From: jinpzhan Date: Wed, 12 Nov 2025 11:09:28 +0800 Subject: [PATCH] [InstCombine] Skip division sinking with allowReciprocal flag --- llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index a9aacc707cc20..88700af60d633 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -795,7 +795,8 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) { return BinaryOperator::CreateFDivFMF(CC1, X, FMF); } if (match(Op0, m_FDiv(m_Value(X), m_Constant(C1)))) { - // FIXME: This seems like it should also be checking for arcp + // Constant folding is not affected by allowReciprocal, + // since constants are calculated at compile time. // (X / C1) * C --> X * (C / C1) Constant *CDivC1 = ConstantFoldBinaryOpOperands(Instruction::FDiv, C, C1, DL); @@ -837,6 +838,12 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) { m_Value(Z)))) { BinaryOperator *DivOp = cast(((Z == Op0) ? Op1 : Op0)); FastMathFlags FMF = I.getFastMathFlags() & DivOp->getFastMathFlags(); + // Preserve (X / Y) * Z when reciprocal math is enabled to allow backend + // rcp instruction emission. Sinking to (X * Z) / Y would prevent this + // optimization, alter computation order and potentially affecting + // precision. + if (FMF.allowReciprocal()) + return nullptr; if (FMF.allowReassoc()) { // Sink division: (X / Y) * Z --> (X * Z) / Y auto *NewFMul = Builder.CreateFMulFMF(X, Z, FMF);