Skip to content

Commit 4fb62d8

Browse files
committed
[SelectionDAG]: Deduce known bits from SMIN and SMAX
1 parent f6a2a55 commit 4fb62d8

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4007,8 +4007,6 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
40074007

40084008
// For SMAX, if CstLow is non-negative we know the result will be
40094009
// non-negative and thus all sign bits are 0.
4010-
// TODO: There's an equivalent of this for smin with negative constant for
4011-
// known ones.
40124010
if (IsMax && CstLow) {
40134011
const APInt &ValueLow = CstLow->getAPIntValue();
40144012
if (ValueLow.isNonNegative()) {
@@ -4017,6 +4015,16 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
40174015
}
40184016
}
40194017

4018+
// For SMAX, if CstHigh is negative we know the result will be
4019+
// negative and thus all sign bits are 1.
4020+
if (!IsMax && CstHigh) {
4021+
const APInt &ValueHigh = CstHigh->getAPIntValue();
4022+
if (ValueHigh.isNegative()) {
4023+
unsigned SignBits = ComputeNumSignBits(Op.getOperand(0), Depth + 1);
4024+
Known.One.setHighBits(std::min(SignBits, ValueHigh.getNumSignBits()));
4025+
}
4026+
}
4027+
40204028
break;
40214029
}
40224030
case ISD::UINT_TO_FP: {
@@ -5360,10 +5368,20 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, unsigned Depth) const {
53605368
return isKnownNeverZero(Op.getOperand(1), Depth + 1) ||
53615369
isKnownNeverZero(Op.getOperand(0), Depth + 1);
53625370

5363-
// TODO for smin/smax: If either operand is known negative/positive
5371+
// For smin/smax: If either operand is known negative/positive
53645372
// respectively we don't need the other to be known at all.
53655373
case ISD::SMAX:
5374+
if (computeKnownBits(Op.getOperand(1), Depth + 1).isStrictlyPositive() ||
5375+
computeKnownBits(Op.getOperand(0), Depth + 1).isStrictlyPositive())
5376+
return true;
5377+
return isKnownNeverZero(Op.getOperand(1), Depth + 1) &&
5378+
isKnownNeverZero(Op.getOperand(0), Depth + 1);
53665379
case ISD::SMIN:
5380+
if (computeKnownBits(Op.getOperand(1), Depth + 1).isNegative() ||
5381+
computeKnownBits(Op.getOperand(0), Depth + 1).isNegative())
5382+
return true;
5383+
return isKnownNeverZero(Op.getOperand(1), Depth + 1) &&
5384+
isKnownNeverZero(Op.getOperand(0), Depth + 1);
53675385
case ISD::UMIN:
53685386
return isKnownNeverZero(Op.getOperand(1), Depth + 1) &&
53695387
isKnownNeverZero(Op.getOperand(0), Depth + 1);

llvm/test/CodeGen/X86/known-never-zero.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,7 @@ define i32 @smax_maybe_zero(i32 %x, i32 %y) {
311311
; CHECK-NEXT: cmpl $55, %edi
312312
; CHECK-NEXT: movl $54, %eax
313313
; CHECK-NEXT: cmovgel %edi, %eax
314-
; CHECK-NEXT: bsfl %eax, %ecx
315-
; CHECK-NEXT: movl $32, %eax
316-
; CHECK-NEXT: cmovnel %ecx, %eax
314+
; CHECK-NEXT: rep bsfl %eax, %eax
317315
; CHECK-NEXT: retq
318316
%z = call i32 @llvm.smax.i32(i32 %x, i32 54)
319317
%r = call i32 @llvm.cttz.i32(i32 %z, i1 false)

0 commit comments

Comments
 (0)