Skip to content

Commit 05347f8

Browse files
committed
[ValueTracking] Compute knownbits from (icmp upred (add/sub nuw X, Y), C)
`(icmp ule/ult (add nuw 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`/`Y`. `(icmp uge/ugt (sub nuw X, Y), C)` implies `(icmp uge/uge X, C)` . We can use this to deduce leading ones in `X`. Proofs: https://alive2.llvm.org/ce/z/sc5k22 Closes #87180
1 parent 80a0a06 commit 05347f8

File tree

2 files changed

+33
-26
lines changed

2 files changed

+33
-26
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -706,17 +706,22 @@ static void computeKnownBitsFromCmp(const Value *V, CmpInst::Predicate Pred,
706706
LHSRange = LHSRange.sub(*Offset);
707707
Known = Known.unionWith(LHSRange.toKnownBits());
708708
}
709-
// X & Y u> C -> X u> C && Y u> C
710-
if ((Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_UGE) &&
711-
match(LHS, m_c_And(m_V, m_Value()))) {
712-
Known.One.setHighBits(
713-
(*C + (Pred == ICmpInst::ICMP_UGT)).countLeadingOnes());
709+
if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_UGE) {
710+
// X & Y u> C -> X u> C && Y u> C
711+
// X nuw- Y u> C -> X u> C
712+
if (match(LHS, m_c_And(m_V, m_Value())) ||
713+
match(LHS, m_NUWSub(m_V, m_Value())))
714+
Known.One.setHighBits(
715+
(*C + (Pred == ICmpInst::ICMP_UGT)).countLeadingOnes());
714716
}
715-
// X | Y u< C -> X u< C && Y u< C
716-
if ((Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_ULE) &&
717-
match(LHS, m_c_Or(m_V, m_Value()))) {
718-
Known.Zero.setHighBits(
719-
(*C - (Pred == ICmpInst::ICMP_ULT)).countLeadingZeros());
717+
if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_ULE) {
718+
// X | Y u< C -> X u< C && Y u< C
719+
// X nuw+ Y u< C -> X u< C && Y u< C
720+
if (match(LHS, m_c_Or(m_V, m_Value())) ||
721+
match(LHS, m_c_NUWAdd(m_V, m_Value()))) {
722+
Known.Zero.setHighBits(
723+
(*C - (Pred == ICmpInst::ICMP_ULT)).countLeadingZeros());
724+
}
720725
}
721726
}
722727
break;
@@ -9576,14 +9581,20 @@ void llvm::findValuesAffectedByCondition(
95769581
if (match(A, m_AddLike(m_Value(X), m_ConstantInt())))
95779582
AddAffected(X);
95789583

9579-
Value *Y;
9580-
// X & Y u> C -> X >u C && Y >u C
9581-
// X | Y u< C -> X u< C && Y u< C
9582-
if (ICmpInst::isUnsigned(Pred) &&
9583-
(match(A, m_And(m_Value(X), m_Value(Y))) ||
9584-
match(A, m_Or(m_Value(X), m_Value(Y))))) {
9585-
AddAffected(X);
9586-
AddAffected(Y);
9584+
if (ICmpInst::isUnsigned(Pred)) {
9585+
Value *Y;
9586+
// X & Y u> C -> X >u C && Y >u C
9587+
// X | Y u< C -> X u< C && Y u< C
9588+
// X nuw+ Y u< C -> X u< C && Y u< C
9589+
if (match(A, m_And(m_Value(X), m_Value(Y))) ||
9590+
match(A, m_Or(m_Value(X), m_Value(Y))) ||
9591+
match(A, m_NUWAdd(m_Value(X), m_Value(Y)))) {
9592+
AddAffected(X);
9593+
AddAffected(Y);
9594+
}
9595+
// X nuw- Y u> C -> X u> C
9596+
if (match(A, m_NUWSub(m_Value(X), m_Value())))
9597+
AddAffected(X);
95879598
}
95889599
}
95899600

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

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,8 +1705,7 @@ define i8 @test_icmp_add(i8 %n, i8 %n2, i8 %other) {
17051705
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_ADD]], 32
17061706
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
17071707
; CHECK: if.then:
1708-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1709-
; CHECK-NEXT: ret i8 [[R]]
1708+
; CHECK-NEXT: ret i8 0
17101709
; CHECK: if.else:
17111710
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
17121711
;
@@ -1757,8 +1756,7 @@ define i8 @test_icmp_add2(i8 %n, i8 %n2, i8 %other) {
17571756
; CHECK: if.then:
17581757
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
17591758
; CHECK: if.else:
1760-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1761-
; CHECK-NEXT: ret i8 [[R]]
1759+
; CHECK-NEXT: ret i8 0
17621760
;
17631761
entry:
17641762
%n_add = add nsw nuw i8 %n, %n2
@@ -1830,8 +1828,7 @@ define i8 @test_icmp_sub(i8 %n, i8 %n2, i8 %other) {
18301828
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_SUB]], -33
18311829
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
18321830
; CHECK: if.then:
1833-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1834-
; CHECK-NEXT: ret i8 [[R]]
1831+
; CHECK-NEXT: ret i8 32
18351832
; CHECK: if.else:
18361833
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
18371834
;
@@ -1882,8 +1879,7 @@ define i8 @test_icmp_sub2(i8 %n, i8 %n2, i8 %other) {
18821879
; CHECK: if.then:
18831880
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
18841881
; CHECK: if.else:
1885-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1886-
; CHECK-NEXT: ret i8 [[R]]
1882+
; CHECK-NEXT: ret i8 32
18871883
;
18881884
entry:
18891885
%n_sub = sub nuw i8 %n, %n2

0 commit comments

Comments
 (0)