Skip to content

Commit 7d54e14

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
1 parent 4efdbef commit 7d54e14

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
@@ -709,17 +709,22 @@ static void computeKnownBitsFromCmp(const Value *V, CmpInst::Predicate Pred,
709709
LHSRange = LHSRange.sub(*Offset);
710710
Known = Known.unionWith(LHSRange.toKnownBits());
711711
}
712-
// X & Y u> C -> X u> C && Y u> C
713-
if ((Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_UGE) &&
714-
match(LHS, m_c_And(m_V, m_Value()))) {
715-
Known.One.setHighBits(
716-
(*C + (Pred == ICmpInst::ICMP_UGT)).countLeadingOnes());
712+
if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_UGE) {
713+
// X & Y u> C -> X u> C && Y u> C
714+
// X nuw- Y u> C -> X u> C
715+
if (match(LHS, m_c_And(m_V, m_Value())) ||
716+
match(LHS, m_NUWSub(m_V, m_Value())))
717+
Known.One.setHighBits(
718+
(*C + (Pred == ICmpInst::ICMP_UGT)).countLeadingOnes());
717719
}
718-
// X | Y u< C -> X u< C && Y u< C
719-
if ((Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_ULE) &&
720-
match(LHS, m_c_Or(m_V, m_Value()))) {
721-
Known.Zero.setHighBits(
722-
(*C - (Pred == ICmpInst::ICMP_ULT)).countLeadingZeros());
720+
if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_ULE) {
721+
// X | Y u< C -> X u< C && Y u< C
722+
// X nuw+ Y u< C -> X u< C && Y u< C
723+
if (match(LHS, m_c_Or(m_V, m_Value())) ||
724+
match(LHS, m_c_NUWAdd(m_V, m_Value()))) {
725+
Known.Zero.setHighBits(
726+
(*C - (Pred == ICmpInst::ICMP_ULT)).countLeadingZeros());
727+
}
723728
}
724729
}
725730
break;
@@ -9467,14 +9472,20 @@ void llvm::findValuesAffectedByCondition(
94679472
if (match(A, m_AddLike(m_Value(X), m_ConstantInt())))
94689473
AddAffected(X);
94699474

9470-
Value *Y;
9471-
// X & Y u> C -> X >u C && Y >u C
9472-
// X | Y u< C -> X u< C && Y u< C
9473-
if (ICmpInst::isUnsigned(Pred) &&
9474-
(match(A, m_And(m_Value(X), m_Value(Y))) ||
9475-
match(A, m_Or(m_Value(X), m_Value(Y))))) {
9476-
AddAffected(X);
9477-
AddAffected(Y);
9475+
if (ICmpInst::isUnsigned(Pred)) {
9476+
Value *Y;
9477+
// X & Y u> C -> X >u C && Y >u C
9478+
// X | Y u< C -> X u< C && Y u< C
9479+
// X nuw+ Y u< C -> X u< C && Y u< C
9480+
if (match(A, m_And(m_Value(X), m_Value(Y))) ||
9481+
match(A, m_Or(m_Value(X), m_Value(Y))) ||
9482+
match(A, m_NUWAdd(m_Value(X), m_Value(Y)))) {
9483+
AddAffected(X);
9484+
AddAffected(Y);
9485+
}
9486+
// X nuw- Y u> C -> X u> C
9487+
if (match(A, m_NUWSub(m_Value(X), m_Value())))
9488+
AddAffected(X);
94789489
}
94799490
}
94809491

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

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,8 +1202,7 @@ define i8 @test_icmp_add(i8 %n, i8 %n2, i8 %other) {
12021202
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_ADD]], 32
12031203
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
12041204
; CHECK: if.then:
1205-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1206-
; CHECK-NEXT: ret i8 [[R]]
1205+
; CHECK-NEXT: ret i8 0
12071206
; CHECK: if.else:
12081207
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
12091208
;
@@ -1229,8 +1228,7 @@ define i8 @test_icmp_add2(i8 %n, i8 %n2, i8 %other) {
12291228
; CHECK: if.then:
12301229
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
12311230
; CHECK: if.else:
1232-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1233-
; CHECK-NEXT: ret i8 [[R]]
1231+
; CHECK-NEXT: ret i8 0
12341232
;
12351233
entry:
12361234
%n_add = add nuw i8 %n, %n2
@@ -1302,8 +1300,7 @@ define i8 @test_icmp_sub(i8 %n, i8 %n2, i8 %other) {
13021300
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_AND]], -33
13031301
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
13041302
; CHECK: if.then:
1305-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1306-
; CHECK-NEXT: ret i8 [[R]]
1303+
; CHECK-NEXT: ret i8 32
13071304
; CHECK: if.else:
13081305
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
13091306
;
@@ -1354,8 +1351,7 @@ define i8 @test_icmp_sub2(i8 %n, i8 %n2, i8 %other) {
13541351
; CHECK: if.then:
13551352
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
13561353
; CHECK: if.else:
1357-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1358-
; CHECK-NEXT: ret i8 [[R]]
1354+
; CHECK-NEXT: ret i8 32
13591355
;
13601356
entry:
13611357
%n_sub = sub nuw i8 %n, %n2

0 commit comments

Comments
 (0)