[llvm] [InstCombine] Implemented missed optimization in muldivrem (PR #140916)

Kshitij Paranjape via llvm-commits llvm-commits at lists.llvm.org
Wed May 21 08:52:30 PDT 2025


https://github.com/kshitijvp created https://github.com/llvm/llvm-project/pull/140916

Added pattern matching condition in
InstCombineMulDivRem.cpp for the missed optimization.

Fixes #122442

>From 3bf8f46d9a26ead3d203f8a04ff2c0dfa71ab6e0 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Wed, 21 May 2025 11:07:50 +0530
Subject: [PATCH] [InstCombine] Implemented missed optimization in muldivrem

Added pattern matching condition in
InstCombineMulDivRem.cpp for the missed optimization.

Fixes #122442
---
 .../Transforms/InstCombine/InstCombineMulDivRem.cpp  | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index c7023eb79b04e..26839d4cafb11 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1258,7 +1258,9 @@ static Value *foldIDivShl(BinaryOperator &I, InstCombiner::BuilderTy &Builder) {
 /// Common integer divide/remainder transforms
 Instruction *InstCombinerImpl::commonIDivRemTransforms(BinaryOperator &I) {
   assert(I.isIntDivRem() && "Unexpected instruction");
-  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+  const APInt *C1, *C2;
+  Value *X;
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *Op2 = I.getOperand(2);
 
   // If any element of a constant divisor fixed width vector is zero or undef
   // the behavior is undefined and we can fold the whole op to poison.
@@ -1295,6 +1297,14 @@ Instruction *InstCombinerImpl::commonIDivRemTransforms(BinaryOperator &I) {
                                           /*FoldWithMultiUse*/ true))
       return R;
   }
+  if (match(Op0, m_OneUse(m_Intrinsic<Intrinsic::smul_fix>(m_APInt(C1), m_APInt(C2)))) &&
+    match(Op1, m_OneUse(m_URem(m_Value(X), Op0))) &&
+    match(Op2, m_OneUse(m_UDiv(Op1, m_APInt(C2))))) {
+    
+    Value *XDivC2 = Builder.CreateUDiv(X, ConstantInt::get(X->getType(), *C2));
+    Value *Result = Builder.CreateURem(XDivC2, ConstantInt::get(X->getType(), *C1));
+    return replaceInstUsesWith(I, Result);
+}
 
   return nullptr;
 }



More information about the llvm-commits mailing list