Skip to content

Commit cc845e9

Browse files
goldsteinnnikic
authored andcommitted
[InstCombine] Handle assume(X & Pow2 != 0) in computeKnownBits()
If we know that X & Pow2 != 0, then the bit at that position is known one. Differential Revision: https://reviews.llvm.org/D140851
1 parent 43cf2f8 commit cc845e9

File tree

3 files changed

+27
-15
lines changed

3 files changed

+27
-15
lines changed

llvm/lib/Analysis/AssumptionCache.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,23 +105,30 @@ findAffectedValues(CallBase *CI, TargetTransformInfo *TTI,
105105
if (match(V, m_BitwiseLogic(m_Value(A), m_Value(B)))) {
106106
AddAffected(A);
107107
AddAffected(B);
108-
// (A << C) or (A >>_s C) or (A >>_u C) where C is some constant.
108+
// (A << C) or (A >>_s C) or (A >>_u C) where C is some constant.
109109
} else if (match(V, m_Shift(m_Value(A), m_ConstantInt()))) {
110110
AddAffected(A);
111111
}
112112
};
113113

114114
AddAffectedFromEq(A);
115115
AddAffectedFromEq(B);
116+
} else if (Pred == ICmpInst::ICMP_NE) {
117+
Value *X, *Y;
118+
// Handle (a & b != 0). If a/b is a power of 2 we can use this
119+
// information.
120+
if (match(A, m_And(m_Value(X), m_Value(Y))) && match(B, m_Zero())) {
121+
AddAffected(X);
122+
AddAffected(Y);
123+
}
124+
} else if (Pred == ICmpInst::ICMP_ULT) {
125+
Value *X;
126+
// Handle (A + C1) u< C2, which is the canonical form of A > C3 && A < C4,
127+
// and recognized by LVI at least.
128+
if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
129+
match(B, m_ConstantInt()))
130+
AddAffected(X);
116131
}
117-
118-
Value *X;
119-
// Handle (A + C1) u< C2, which is the canonical form of A > C3 && A < C4,
120-
// and recognized by LVI at least.
121-
if (Pred == ICmpInst::ICMP_ULT &&
122-
match(A, m_Add(m_Value(X), m_ConstantInt())) &&
123-
match(B, m_ConstantInt()))
124-
AddAffected(X);
125132
}
126133

127134
if (TTI) {

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,14 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known,
940940
Known.Zero.setHighBits(RHSKnown.countMinLeadingZeros());
941941
}
942942
break;
943+
case ICmpInst::ICMP_NE: {
944+
// assume (v & b != 0) where b is a power of 2
945+
const APInt *BPow2;
946+
if (match(Cmp, m_ICmp(Pred, m_c_And(m_V, m_Power2(BPow2)), m_Zero())) &&
947+
isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
948+
Known.One |= BPow2->zextOrTrunc(BitWidth);
949+
}
950+
} break;
943951
}
944952
}
945953

llvm/test/Transforms/InstCombine/icmp-ne-pow2.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ define i32 @pow2_32_assume(i32 %x) {
99
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4
1010
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1111
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
12-
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 4
13-
; CHECK-NEXT: ret i32 [[AND2]]
12+
; CHECK-NEXT: ret i32 4
1413
;
1514
%and = and i32 %x, 4
1615
%cmp = icmp ne i32 %and, 0
@@ -39,8 +38,7 @@ define i64 @pow2_64_assume(i64 %x) {
3938
; CHECK-NEXT: [[AND:%.*]] = and i64 [[X:%.*]], 1
4039
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[AND]], 0
4140
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
42-
; CHECK-NEXT: [[OR:%.*]] = or i64 [[X]], 1
43-
; CHECK-NEXT: ret i64 [[OR]]
41+
; CHECK-NEXT: ret i64 [[X]]
4442
;
4543
%and = and i64 %x, 1
4644
%cmp = icmp ne i64 %and, 0
@@ -69,8 +67,7 @@ define i16 @pow2_16_assume(i16 %x) {
6967
; CHECK-NEXT: [[AND:%.*]] = and i16 [[X:%.*]], 16384
7068
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[AND]], 0
7169
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
72-
; CHECK-NEXT: [[AND2:%.*]] = and i16 [[X]], 16384
73-
; CHECK-NEXT: ret i16 [[AND2]]
70+
; CHECK-NEXT: ret i16 16384
7471
;
7572
%and = and i16 %x, 16384
7673
%cmp = icmp eq i16 %and, 16384

0 commit comments

Comments
 (0)