[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