[llvm] [SelectionDAG] Add more cases for UDIV and SDIV (PR #86452)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 15 14:21:07 PDT 2024
https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/86452
>From 9884d6304762e8cc405cc3bd0f8146b8b230dbfd Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sun, 24 Mar 2024 14:09:28 -0400
Subject: [PATCH 1/2] [SelectionDAG] Add more cases for UDIV and SDIV
Also have UDIV just exit early if it can calculate that LHS is less than the RHS.
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 31 +++++++++++++++++--
llvm/lib/Support/KnownBits.cpp | 4 ++-
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 0ab5142ab8167..5f80c7c7315ee 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5392,14 +5392,39 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, unsigned Depth) const {
return true;
break;
}
- case ISD::UDIV:
- case ISD::SDIV:
+ case ISD::UDIV: {
// div exact can only produce a zero if the dividend is zero.
- // TODO: For udiv this is also true if Op1 u<= Op0
if (Op->getFlags().hasExact())
return isKnownNeverZero(Op.getOperand(0), Depth + 1);
+
+ // If Op1 <= Op0, then Op0 is at least 1, and therefore not 0.
+ KnownBits Op0 = computeKnownBits(Op.getOperand(0), Depth + 1);
+ KnownBits Op1 = computeKnownBits(Op.getOperand(1), Depth + 1);
+ std::optional<bool> uge = KnownBits::uge(Op0, Op1);
+ if (uge && *uge)
+ return true;
+
+ if (KnownBits::udiv(Op0, Op1).isNonZero())
+ return true;
break;
+ }
+ case ISD::SDIV: {
+ // div exact can only produce a zero if the dividend is zero.
+ if (Op->getFlags().hasExact())
+ return isKnownNeverZero(Op.getOperand(0), Depth + 1);
+ KnownBits Op0 = computeKnownBits(Op.getOperand(0), Depth + 1);
+ KnownBits Op1 = computeKnownBits(Op.getOperand(1), Depth + 1);
+ if (Op0.isStrictlyPositive() && Op1.isStrictlyPositive()) {
+ std::optional<bool> uge = KnownBits::uge(Op0, Op1);
+ if (uge && *uge)
+ return true;
+ }
+
+ if (KnownBits::sdiv(Op0, Op1).isNonZero())
+ return true;
+ break;
+ }
case ISD::ADD:
if (Op->getFlags().hasNoUnsignedWrap())
if (isKnownNeverZero(Op.getOperand(1), Depth + 1) ||
diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp
index d72355dab6f1d..fac9980a9349f 100644
--- a/llvm/lib/Support/KnownBits.cpp
+++ b/llvm/lib/Support/KnownBits.cpp
@@ -979,7 +979,9 @@ KnownBits KnownBits::udiv(const KnownBits &LHS, const KnownBits &RHS,
assert(!LHS.hasConflict() && !RHS.hasConflict());
KnownBits Known(BitWidth);
- if (LHS.isZero() || RHS.isZero()) {
+ // if LHS < RHS, then LHS / RHS is 0.
+ std::optional<bool> ult = KnownBits::ult(LHS, RHS);
+ if (LHS.isZero() || RHS.isZero() || (ult && *ult)) {
// Result is either known Zero or UB. Return Zero either way.
// Checking this earlier saves us a lot of special cases later on.
Known.setAllZero();
>From d5dd4989ff6bfdcff007eabcecb5242eb0d242b5 Mon Sep 17 00:00:00 2001
From: AtariDreams <gfunni234 at gmail.com>
Date: Mon, 15 Jul 2024 17:20:59 -0400
Subject: [PATCH 2/2] Update llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Co-authored-by: Jay Foad <jay.foad at gmail.com>
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 5f80c7c7315ee..1d974db196230 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5397,7 +5397,7 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, unsigned Depth) const {
if (Op->getFlags().hasExact())
return isKnownNeverZero(Op.getOperand(0), Depth + 1);
- // If Op1 <= Op0, then Op0 is at least 1, and therefore not 0.
+ // If Op0 >= Op1, then the result is at least 1, and therefore not 0.
KnownBits Op0 = computeKnownBits(Op.getOperand(0), Depth + 1);
KnownBits Op1 = computeKnownBits(Op.getOperand(1), Depth + 1);
std::optional<bool> uge = KnownBits::uge(Op0, Op1);
More information about the llvm-commits
mailing list