Skip to content

Commit 0341e89

Browse files
committed
[ValueTracking] Compute knownbits from (icmp ult/ule (add nuw X, Y), C)
`(icmp ule/ult (or X, Y), C)` implies both `(icmp ule/ult X, C)` and `(icmp ule/ult Y, C)`. We can use this to deduce leading zeros in `X`. Proofs: https://alive2.llvm.org/ce/z/ocvv5F
1 parent 8d9ea71 commit 0341e89

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -698,13 +698,19 @@ static void computeKnownBitsFromCmp(const Value *V, CmpInst::Predicate Pred,
698698
break;
699699
}
700700
default:
701-
const APInt *Offset = nullptr;
702-
if (match(LHS, m_CombineOr(m_V, m_AddLike(m_V, m_APInt(Offset)))) &&
703-
match(RHS, m_APInt(C))) {
704-
ConstantRange LHSRange = ConstantRange::makeAllowedICmpRegion(Pred, *C);
705-
if (Offset)
706-
LHSRange = LHSRange.sub(*Offset);
707-
Known = Known.unionWith(LHSRange.toKnownBits());
701+
if (match(RHS, m_APInt(C))) {
702+
const APInt *Offset = nullptr;
703+
if (match(LHS, m_CombineOr(m_V, m_AddLike(m_V, m_APInt(Offset))))) {
704+
ConstantRange LHSRange = ConstantRange::makeAllowedICmpRegion(Pred, *C);
705+
if (Offset)
706+
LHSRange = LHSRange.sub(*Offset);
707+
Known = Known.unionWith(LHSRange.toKnownBits());
708+
}
709+
if ((Pred == ICmpInst::ICMP_ULE || Pred == ICmpInst::ICMP_ULT) &&
710+
match(LHS, m_c_NUWAdd(m_V, m_Value()))) {
711+
Known.Zero.setHighBits(
712+
(*C - (Pred == ICmpInst::ICMP_ULT)).countLeadingZeros());
713+
}
708714
}
709715
break;
710716
}
@@ -9283,11 +9289,20 @@ void llvm::findValuesAffectedByCondition(
92839289
AddAffected(X);
92849290
}
92859291
} else {
9286-
// Handle (A + C1) u< C2, which is the canonical form of
9287-
// A > C3 && A < C4.
9288-
if (match(A, m_AddLike(m_Value(X), m_ConstantInt())) &&
9289-
match(B, m_ConstantInt()))
9290-
AddAffected(X);
9292+
if (match(B, m_ConstantInt())) {
9293+
// Handle (A + C1) u< C2, which is the canonical form of
9294+
// A > C3 && A < C4.
9295+
if (match(A, m_AddLike(m_Value(X), m_ConstantInt())))
9296+
AddAffected(X);
9297+
9298+
Value *Y;
9299+
// X nuw+ Y u< C -> X u< C && Y u< C
9300+
if (ICmpInst::isUnsigned(Pred) &&
9301+
match(A, m_NUWAdd(m_Value(X), m_Value(Y)))) {
9302+
AddAffected(X);
9303+
AddAffected(Y);
9304+
}
9305+
}
92919306

92929307
// Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
92939308
// by computeKnownFPClass().

llvm/test/Transforms/InstCombine/known-bits.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -536,8 +536,7 @@ define i8 @test_icmp_add(i8 %n, i8 %n2, i8 %other) {
536536
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_ADD]], 32
537537
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
538538
; CHECK: if.then:
539-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
540-
; CHECK-NEXT: ret i8 [[R]]
539+
; CHECK-NEXT: ret i8 0
541540
; CHECK: if.else:
542541
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
543542
;
@@ -563,8 +562,7 @@ define i8 @test_icmp_add2(i8 %n, i8 %n2, i8 %other) {
563562
; CHECK: if.then:
564563
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
565564
; CHECK: if.else:
566-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
567-
; CHECK-NEXT: ret i8 [[R]]
565+
; CHECK-NEXT: ret i8 0
568566
;
569567
entry:
570568
%n_add = add nuw i8 %n, %n2

0 commit comments

Comments
 (0)