Skip to content

Commit e86e626

Browse files
committed
InstSimplify: teach simplifyICmpWithConstant about samesign
1 parent d6dc555 commit e86e626

File tree

2 files changed

+26
-19
lines changed

2 files changed

+26
-19
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2999,21 +2999,32 @@ static Value *simplifyICmpWithConstant(CmpPredicate Pred, Value *LHS,
29992999
return ConstantInt::getBool(ITy, !TrueIfSigned);
30003000
}
30013001

3002-
// Rule out tautological comparisons (eg., ult 0 or uge 0).
3003-
ConstantRange RHS_CR = ConstantRange::makeExactICmpRegion(Pred, *C);
3004-
if (RHS_CR.isEmptySet())
3005-
return ConstantInt::getFalse(ITy);
3006-
if (RHS_CR.isFullSet())
3007-
return ConstantInt::getTrue(ITy);
3008-
3009-
ConstantRange LHS_CR =
3002+
ConstantRange LCR =
30103003
computeConstantRange(LHS, CmpInst::isSigned(Pred), IIQ.UseInstrInfo);
3011-
if (!LHS_CR.isFullSet()) {
3012-
if (RHS_CR.contains(LHS_CR))
3013-
return ConstantInt::getTrue(ITy);
3014-
if (RHS_CR.inverse().contains(LHS_CR))
3004+
3005+
auto CheckCR = [&](const ConstantRange &CR) -> Constant * {
3006+
// Rule out tautological comparisons (eg., ult 0 or uge 0).
3007+
if (CR.isEmptySet())
30153008
return ConstantInt::getFalse(ITy);
3016-
}
3009+
if (CR.isFullSet())
3010+
return ConstantInt::getTrue(ITy);
3011+
3012+
if (!LCR.isFullSet()) {
3013+
if (CR.contains(LCR))
3014+
return ConstantInt::getTrue(ITy);
3015+
if (CR.inverse().contains(LCR))
3016+
return ConstantInt::getFalse(ITy);
3017+
}
3018+
return nullptr;
3019+
};
3020+
3021+
// Check unsigned and signed versions of relational predicates with samesign.
3022+
if (auto *K = CheckCR(ConstantRange::makeExactICmpRegion(Pred, *C)))
3023+
return K;
3024+
if (Pred.hasSameSign() && ICmpInst::isRelational(Pred))
3025+
if (auto *K = CheckCR(ConstantRange::makeExactICmpRegion(
3026+
ICmpInst::getSignedPredicate(Pred), *C)))
3027+
return K;
30173028

30183029
// (mul nuw/nsw X, MulC) != C --> true (if C is not a multiple of MulC)
30193030
// (mul nuw/nsw X, MulC) == C --> false (if C is not a multiple of MulC)

llvm/test/Analysis/ValueTracking/constant-ranges.ll

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,7 @@ define i1 @srem_negC_okay0(i8 %x) {
198198

199199
define i1 @srem_negC_okay0_samesign(i8 %x) {
200200
; CHECK-LABEL: @srem_negC_okay0_samesign(
201-
; CHECK-NEXT: [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
202-
; CHECK-NEXT: [[R:%.*]] = icmp samesign ule i8 [[VAL]], 0
203-
; CHECK-NEXT: ret i1 [[R]]
201+
; CHECK-NEXT: ret i1 true
204202
;
205203
%val = srem i8 -34, %x
206204
%r = icmp samesign ule i8 %val, 0
@@ -218,9 +216,7 @@ define i1 @srem_negC_okay1(i8 %x) {
218216

219217
define i1 @srem_negC_okay1_samesign(i8 %x) {
220218
; CHECK-LABEL: @srem_negC_okay1_samesign(
221-
; CHECK-NEXT: [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
222-
; CHECK-NEXT: [[R:%.*]] = icmp samesign uge i8 [[VAL]], -34
223-
; CHECK-NEXT: ret i1 [[R]]
219+
; CHECK-NEXT: ret i1 true
224220
;
225221
%val = srem i8 -34, %x
226222
%r = icmp samesign uge i8 %val, -34

0 commit comments

Comments
 (0)