Skip to content

Conversation

@AZero13
Copy link
Contributor

@AZero13 AZero13 commented Mar 24, 2024

Ported from ValueTracking.

@llvmbot llvmbot added llvm:support llvm:SelectionDAG SelectionDAGISel as well labels Mar 24, 2024
@llvmbot
Copy link
Member

llvmbot commented Mar 24, 2024

@llvm/pr-subscribers-backend-x86
@llvm/pr-subscribers-llvm-analysis
@llvm/pr-subscribers-llvm-selectiondag

@llvm/pr-subscribers-llvm-support

Author: AtariDreams (AtariDreams)

Changes

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 --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();

@github-actions
Copy link

✅ With the latest revision this PR passed the C/C++ code formatter.

@github-actions
Copy link

✅ With the latest revision this PR passed the Python code formatter.

@topperc
Copy link
Collaborator

topperc commented Mar 25, 2024

Can you make the title more descriptive? Add more cases where?

@topperc
Copy link
Collaborator

topperc commented Mar 25, 2024

Tests?

Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please branch off the KnownBits.cpp changes into its own PR

Also, still waiting for test cases :)

@AZero13 AZero13 requested review from RKSimon, jayfoad and topperc July 15, 2024 21:30
@AZero13 AZero13 force-pushed the known branch 3 times, most recently from 7b35391 to 9a6cc0c Compare July 15, 2024 21:34
@AZero13 AZero13 closed this Sep 10, 2024
@AZero13 AZero13 reopened this Mar 5, 2025
@AZero13 AZero13 force-pushed the known branch 3 times, most recently from dd03d7b to 69339fc Compare March 6, 2025 00:02
@llvmbot llvmbot added the llvm:analysis Includes value tracking, cost tables and constant folding label Mar 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:X86 llvm:analysis Includes value tracking, cost tables and constant folding llvm:SelectionDAG SelectionDAGISel as well llvm:support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants