[llvm] [SelectionDAG]: Deduce known bits from SMIN and SMAX (PR #85722)

via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 18 18:38:07 PDT 2024


https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/85722

>From e9514a396f8da12cab8dba039a11340990351000 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Mon, 18 Mar 2024 20:40:32 -0400
Subject: [PATCH] [SelectionDAG]: Deduce known bits from SMIN and SMAX

---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 24 ++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 6f6ed4bd45027b..918e72a3bfa116 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4007,8 +4007,6 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
 
     // For SMAX, if CstLow is non-negative we know the result will be
     // non-negative and thus all sign bits are 0.
-    // TODO: There's an equivalent of this for smin with negative constant for
-    // known ones.
     if (IsMax && CstLow) {
       const APInt &ValueLow = CstLow->getAPIntValue();
       if (ValueLow.isNonNegative()) {
@@ -4017,6 +4015,16 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
       }
     }
 
+    // For SMAX, if CstHigh is negative we know the result will be
+    // negative and thus all sign bits are 1.
+    if (!IsMax && CstHigh) {
+      const APInt &ValueHigh = CstHigh->getAPIntValue();
+      if (ValueHigh.isNegative()) {
+        unsigned SignBits = ComputeNumSignBits(Op.getOperand(0), Depth + 1);
+        Known.One.setHighBits(std::min(SignBits, ValueHigh.getNumSignBits()));
+      }
+    }
+
     break;
   }
   case ISD::UINT_TO_FP: {
@@ -5360,10 +5368,20 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, unsigned Depth) const {
     return isKnownNeverZero(Op.getOperand(1), Depth + 1) ||
            isKnownNeverZero(Op.getOperand(0), Depth + 1);
 
-    // TODO for smin/smax: If either operand is known negative/positive
+    // For smin/smax: If either operand is known negative/positive
     // respectively we don't need the other to be known at all.
   case ISD::SMAX:
+    if (computeKnownBits(Op.getOperand(1), Depth + 1).isStrictlyPositive() ||
+        computeKnownBits(Op.getOperand(0), Depth + 1).isStrictlyPositive())
+      return true;
+    return isKnownNeverZero(Op.getOperand(1), Depth + 1) &&
+           isKnownNeverZero(Op.getOperand(0), Depth + 1);
   case ISD::SMIN:
+    if (computeKnownBits(Op.getOperand(1), Depth + 1).isNegative() ||
+        computeKnownBits(Op.getOperand(0), Depth + 1).isNegative())
+      return true;
+    return isKnownNeverZero(Op.getOperand(1), Depth + 1) &&
+           isKnownNeverZero(Op.getOperand(0), Depth + 1);
   case ISD::UMIN:
     return isKnownNeverZero(Op.getOperand(1), Depth + 1) &&
            isKnownNeverZero(Op.getOperand(0), Depth + 1);



More information about the llvm-commits mailing list