[llvm] [SelectionDAG]: Deduce known bits from SMIN and SMAX (PR #85722)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 18 17:41:21 PDT 2024
https://github.com/AtariDreams created https://github.com/llvm/llvm-project/pull/85722
None
>From 8d241d6cd0cb2b53f1256feb47b1c96408fced0e 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 | 23 ++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 6f6ed4bd45027b..81d2df1db565ea 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,19 @@ 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(0), Depth + 1).isStrictlyPositive() ||
+ computeKnownBits(Op.getOperand(1), 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(0), Depth + 1).isNegative() ||
+ computeKnownBits(Op.getOperand(1), Depth + 1).isNegative())
+ 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