Skip to content

Commit ba62ff8

Browse files
committed
[ValueTracking] improve isKnownNonZero precision for smax
Instead of relying on known-bits for strictly positive, use the `isKnownPositive` API. This will use `isKnownNonZero` which is more accurate.
1 parent 86b3c85 commit ba62ff8

File tree

2 files changed

+37
-17
lines changed

2 files changed

+37
-17
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,23 +2828,47 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
28282828
case Intrinsic::uadd_sat:
28292829
return isKnownNonZero(II->getArgOperand(1), DemandedElts, Depth, Q) ||
28302830
isKnownNonZero(II->getArgOperand(0), DemandedElts, Depth, Q);
2831-
case Intrinsic::smin:
28322831
case Intrinsic::smax: {
2833-
auto KnownOpImpliesNonZero = [&](const KnownBits &K) {
2834-
return II->getIntrinsicID() == Intrinsic::smin
2835-
? K.isNegative()
2836-
: K.isStrictlyPositive();
2837-
};
2838-
KnownBits XKnown =
2832+
// if either arg is strictly positive the result is non-zero. Otherwise
2833+
// the result is non-zero if both ops are non-zero.
2834+
KnownBits Op1Known =
2835+
computeKnownBits(II->getArgOperand(1), DemandedElts, Depth, Q);
2836+
// Avoid re-computing isKnownNonZero if we already failed once.
2837+
bool OpsMaybeZero = false;
2838+
if (Op1Known.isNonNegative()) {
2839+
if (Op1Known.isNonZero() ||
2840+
isKnownNonZero(II->getArgOperand(1), DemandedElts, Depth, Q))
2841+
return true;
2842+
OpsMaybeZero = true;
2843+
}
2844+
KnownBits Op0Known =
28392845
computeKnownBits(II->getArgOperand(0), DemandedElts, Depth, Q);
2840-
if (KnownOpImpliesNonZero(XKnown))
2841-
return true;
2842-
KnownBits YKnown =
2846+
if (Op0Known.isNonNegative()) {
2847+
if (Op0Known.isNonZero() ||
2848+
isKnownNonZero(II->getArgOperand(0), DemandedElts, Depth, Q))
2849+
return true;
2850+
OpsMaybeZero = true;
2851+
}
2852+
// We already failed at least one call to isKnownNonZero
2853+
if (OpsMaybeZero)
2854+
break;
2855+
return isKnownNonZero(II->getArgOperand(0), DemandedElts, Depth, Q) &&
2856+
isKnownNonZero(II->getArgOperand(1), DemandedElts, Depth, Q);
2857+
}
2858+
2859+
case Intrinsic::smin: {
2860+
// if either arg is negative the result is non-zero. Otherwise
2861+
// the result is non-zero if both ops are non-zero.
2862+
KnownBits Op1Known =
28432863
computeKnownBits(II->getArgOperand(1), DemandedElts, Depth, Q);
2844-
if (KnownOpImpliesNonZero(YKnown))
2864+
if (Op1Known.isNegative())
2865+
return true;
2866+
KnownBits Op0Known =
2867+
computeKnownBits(II->getArgOperand(0), DemandedElts, Depth, Q);
2868+
if (Op0Known.isNegative())
28452869
return true;
28462870

2847-
if (XKnown.isNonZero() && YKnown.isNonZero())
2871+
if (Op1Known.isNonZero() && Op0Known.isNonZero())
28482872
return true;
28492873
}
28502874
[[fallthrough]];

llvm/test/Transforms/InstSimplify/known-non-zero.ll

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,7 @@ B:
169169

170170
define i1 @smax_non_zero(i8 %xx, i8 %y) {
171171
; CHECK-LABEL: @smax_non_zero(
172-
; CHECK-NEXT: [[X0:%.*]] = and i8 [[XX:%.*]], 63
173-
; CHECK-NEXT: [[X:%.*]] = add i8 [[X0]], 1
174-
; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 [[Y:%.*]])
175-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[V]], 0
176-
; CHECK-NEXT: ret i1 [[R]]
172+
; CHECK-NEXT: ret i1 false
177173
;
178174
%x0 = and i8 %xx, 63
179175
%x = add i8 %x0, 1

0 commit comments

Comments
 (0)