[llvm] [SelectionDAG] Add more cases for UDIV and SDIV (PR #86452)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 24 13:26:47 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-support
Author: AtariDreams (AtariDreams)
<details>
<summary>Changes</summary>
Also have UDIV just exit early if it can calculate that LHS is less than the RHS.
---
Full diff: https://github.com/llvm/llvm-project/pull/86452.diff
2 Files Affected:
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+28-3)
- (modified) llvm/lib/Support/KnownBits.cpp (+3-1)
``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 0ab5142ab81676..5f80c7c7315ee4 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 d72355dab6f1d3..fac9980a9349fc 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();
``````````
</details>
https://github.com/llvm/llvm-project/pull/86452
More information about the llvm-commits
mailing list