[llvm] [CodeGen] Avoid creating instructions dealing with ones if ones aren't invovled in the division (PR #99674)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 19 10:57:03 PDT 2024


https://github.com/AtariDreams created https://github.com/llvm/llvm-project/pull/99674

None

>From 994270de3a2a6ab2dd484525e1bd640bf3227f2d Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Thu, 18 Jul 2024 19:26:32 -0400
Subject: [PATCH] [CodeGen] Avoid creating instructions dealing with ones if
 ones aren't involved in the division

---
 .../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 27 +++++++++++++------
 .../CodeGen/SelectionDAG/TargetLowering.cpp   | 21 ++++++++++-----
 2 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index dfc3d73e322b8..b682b5ac82fbf 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -5213,6 +5213,9 @@ MachineInstr *CombinerHelper::buildUDivUsingMul(MachineInstr &MI) {
     return true;
   };
 
+  bool hasAOne = false;
+  bool hasOnlyOne = true;
+
   auto BuildUDIVPattern = [&](const Constant *C) {
     auto *CI = cast<ConstantInt>(C);
     const APInt &Divisor = CI->getValue();
@@ -5224,8 +5227,10 @@ MachineInstr *CombinerHelper::buildUDivUsingMul(MachineInstr &MI) {
     // Magic algorithm doesn't work for division by 1. We need to emit a select
     // at the end.
     // TODO: Use undef values for divisor of 1.
-    if (!Divisor.isOne()) {
-
+    if (Divisor.isOne()) {
+      hasAOne = true;
+    } else {
+      hasOnlyOne = false;
       // UnsignedDivisionByConstantInfo doesn't work correctly if leading zeros
       // in the dividend exceeds the leading zeros for the divisor.
       UnsignedDivisionByConstantInfo magics =
@@ -5285,6 +5290,8 @@ MachineInstr *CombinerHelper::buildUDivUsingMul(MachineInstr &MI) {
   bool Matched = matchUnaryPredicate(MRI, RHS, BuildUDIVPattern);
   (void)Matched;
   assert(Matched && "Expected unary predicate match to succeed");
+  assert(!(hasAOne && hasOnlyOne) &&
+         "Divisor of 1 should have been eliminated");
 
   Register PreShift, PostShift, MagicFactor, NPQFactor;
   auto *RHSDef = getOpcodeDef<GBuildVector>(RHS, MRI);
@@ -5320,12 +5327,16 @@ MachineInstr *CombinerHelper::buildUDivUsingMul(MachineInstr &MI) {
     Q = MIB.buildAdd(Ty, NPQ, Q).getReg(0);
   }
 
-  Q = MIB.buildLShr(Ty, Q, PostShift).getReg(0);
-  auto One = MIB.buildConstant(Ty, 1);
-  auto IsOne = MIB.buildICmp(
-      CmpInst::Predicate::ICMP_EQ,
-      Ty.isScalar() ? LLT::scalar(1) : Ty.changeElementSize(1), RHS, One);
-  return MIB.buildSelect(Ty, IsOne, LHS, Q);
+  if (hasAOne) {
+    Q = MIB.buildLShr(Ty, Q, PostShift).getReg(0);
+    auto One = MIB.buildConstant(Ty, 1);
+    auto IsOne = MIB.buildICmp(
+        CmpInst::Predicate::ICMP_EQ,
+        Ty.isScalar() ? LLT::scalar(1) : Ty.changeElementSize(1), RHS, One);
+    return MIB.buildSelect(Ty, IsOne, LHS, Q);
+  }
+
+  return MIB.buildLShr(Ty, Q, PostShift);
 }
 
 bool CombinerHelper::matchUDivByConst(MachineInstr &MI) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 140c97ccd90ba..11d7e1442f2d9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -6487,7 +6487,8 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
 
   bool UseNPQ = false, UsePreShift = false, UsePostShift = false;
   SmallVector<SDValue, 16> PreShifts, PostShifts, MagicFactors, NPQFactors;
-
+  bool hasAOne = false;
+  bool hasOnlyOne = true;
   auto BuildUDIVPattern = [&](ConstantSDNode *C) {
     if (C->isZero())
       return false;
@@ -6500,7 +6501,9 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
     if (Divisor.isOne()) {
       PreShift = PostShift = DAG.getUNDEF(ShSVT);
       MagicFactor = NPQFactor = DAG.getUNDEF(SVT);
+      hasAOne = true;
     } else {
+      hasOnlyOne = false;
       UnsignedDivisionByConstantInfo magics =
           UnsignedDivisionByConstantInfo::get(
               Divisor, std::min(KnownLeadingZeros, Divisor.countl_zero()));
@@ -6535,6 +6538,9 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
   if (!ISD::matchUnaryPredicate(N1, BuildUDIVPattern))
     return SDValue();
 
+  if (hasAOne && hasOnlyOne)
+    return N0;
+
   SDValue PreShift, PostShift, MagicFactor, NPQFactor;
   if (N1.getOpcode() == ISD::BUILD_VECTOR) {
     PreShift = DAG.getBuildVector(ShVT, dl, PreShifts);
@@ -6628,11 +6634,14 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
     Created.push_back(Q.getNode());
   }
 
-  EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
-
-  SDValue One = DAG.getConstant(1, dl, VT);
-  SDValue IsOne = DAG.getSetCC(dl, SetCCVT, N1, One, ISD::SETEQ);
-  return DAG.getSelect(dl, VT, IsOne, N0, Q);
+  if (hasAOne) {
+    EVT SetCCVT =
+        getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
+    SDValue One = DAG.getConstant(1, dl, VT);
+    SDValue IsOne = DAG.getSetCC(dl, SetCCVT, N1, One, ISD::SETEQ);
+    return DAG.getSelect(dl, VT, IsOne, N0, Q);
+  }
+  return Q;
 }
 
 /// If all values in Values that *don't* match the predicate are same 'splat'



More information about the llvm-commits mailing list