Skip to content

Commit 0144892

Browse files
committed
[ValueTracking] Support dominating known bits condition in and/or
This extends computeKnownBits() support for dominating conditions to also handle and/or conditions. We'll look through either and or or depending on which edge we're considering. This change is mainly for the sake of completeness, so we don't start missing optimizations if SimplifyCFG decides to merge some branches.
1 parent 52296e2 commit 0144892

File tree

4 files changed

+74
-51
lines changed

4 files changed

+74
-51
lines changed

llvm/lib/Analysis/DomConditionCache.cpp

+32-16
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,39 @@ static void findAffectedValues(Value *Cond,
3434
}
3535
};
3636

37-
ICmpInst::Predicate Pred;
38-
Value *A;
39-
if (match(Cond, m_ICmp(Pred, m_Value(A), m_Constant()))) {
40-
AddAffected(A);
37+
bool TopLevelIsAnd = match(Cond, m_LogicalAnd());
38+
SmallVector<Value *, 8> Worklist;
39+
SmallPtrSet<Value *, 8> Visited;
40+
Worklist.push_back(Cond);
41+
while (!Worklist.empty()) {
42+
Value *V = Worklist.pop_back_val();
43+
if (!Visited.insert(V).second)
44+
continue;
4145

42-
if (ICmpInst::isEquality(Pred)) {
43-
Value *X;
44-
// (X & C) or (X | C) or (X ^ C).
45-
// (X << C) or (X >>_s C) or (X >>_u C).
46-
if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
47-
match(A, m_Shift(m_Value(X), m_ConstantInt())))
48-
AddAffected(X);
49-
} else {
50-
Value *X;
51-
// Handle (A + C1) u< C2, which is the canonical form of A > C3 && A < C4.
52-
if (match(A, m_Add(m_Value(X), m_ConstantInt())))
53-
AddAffected(X);
46+
ICmpInst::Predicate Pred;
47+
Value *A, *B;
48+
// Only recurse into and/or if it matches the top-level and/or type.
49+
if (TopLevelIsAnd ? match(V, m_LogicalAnd(m_Value(A), m_Value(B)))
50+
: match(V, m_LogicalOr(m_Value(A), m_Value(B)))) {
51+
Worklist.push_back(A);
52+
Worklist.push_back(B);
53+
} else if (match(V, m_ICmp(Pred, m_Value(A), m_Constant()))) {
54+
AddAffected(A);
55+
56+
if (ICmpInst::isEquality(Pred)) {
57+
Value *X;
58+
// (X & C) or (X | C) or (X ^ C).
59+
// (X << C) or (X >>_s C) or (X >>_u C).
60+
if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
61+
match(A, m_Shift(m_Value(X), m_ConstantInt())))
62+
AddAffected(X);
63+
} else {
64+
Value *X;
65+
// Handle (A + C1) u< C2, which is the canonical form of
66+
// A > C3 && A < C4.
67+
if (match(A, m_Add(m_Value(X), m_ConstantInt())))
68+
AddAffected(X);
69+
}
5470
}
5571
}
5672
}

llvm/lib/Analysis/ValueTracking.cpp

+22-10
Original file line numberDiff line numberDiff line change
@@ -705,28 +705,40 @@ static void computeKnownBitsFromCmp(const Value *V, CmpInst::Predicate Pred,
705705
}
706706
}
707707

708+
static void computeKnownBitsFromCond(const Value *V, Value *Cond,
709+
KnownBits &Known, unsigned Depth,
710+
const SimplifyQuery &SQ, bool Invert) {
711+
Value *A, *B;
712+
if (Depth < MaxAnalysisRecursionDepth &&
713+
(Invert ? match(Cond, m_LogicalOr(m_Value(A), m_Value(B)))
714+
: match(Cond, m_LogicalAnd(m_Value(A), m_Value(B))))) {
715+
computeKnownBitsFromCond(V, A, Known, Depth + 1, SQ, Invert);
716+
computeKnownBitsFromCond(V, B, Known, Depth + 1, SQ, Invert);
717+
}
718+
719+
if (auto *Cmp = dyn_cast<ICmpInst>(Cond))
720+
computeKnownBitsFromCmp(
721+
V, Invert ? Cmp->getInversePredicate() : Cmp->getPredicate(),
722+
Cmp->getOperand(0), Cmp->getOperand(1), Known, SQ);
723+
}
724+
708725
void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
709-
unsigned Depth, const SimplifyQuery &Q) {
726+
unsigned Depth, const SimplifyQuery &Q) {
710727
if (!Q.CxtI)
711728
return;
712729

713730
if (Q.DC && Q.DT) {
714731
// Handle dominating conditions.
715732
for (BranchInst *BI : Q.DC->conditionsFor(V)) {
716-
auto *Cmp = dyn_cast<ICmpInst>(BI->getCondition());
717-
if (!Cmp)
718-
continue;
719-
720733
BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0));
721734
if (Q.DT->dominates(Edge0, Q.CxtI->getParent()))
722-
computeKnownBitsFromCmp(V, Cmp->getPredicate(), Cmp->getOperand(0),
723-
Cmp->getOperand(1), Known, Q);
735+
computeKnownBitsFromCond(V, BI->getCondition(), Known, Depth, Q,
736+
/*Invert*/ false);
724737

725738
BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1));
726739
if (Q.DT->dominates(Edge1, Q.CxtI->getParent()))
727-
computeKnownBitsFromCmp(V, Cmp->getInversePredicate(),
728-
Cmp->getOperand(0), Cmp->getOperand(1), Known,
729-
Q);
740+
computeKnownBitsFromCond(V, BI->getCondition(), Known, Depth, Q,
741+
/*Invert*/ true);
730742
}
731743

732744
if (Known.hasConflict())

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

+5-10
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,7 @@ define i8 @test_cond_and(i8 %x, i1 %c) {
105105
; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP]], [[C:%.*]]
106106
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
107107
; CHECK: if:
108-
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
109-
; CHECK-NEXT: ret i8 [[OR1]]
108+
; CHECK-NEXT: ret i8 -4
110109
; CHECK: exit:
111110
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
112111
; CHECK-NEXT: ret i8 [[OR2]]
@@ -133,8 +132,7 @@ define i8 @test_cond_and_commuted(i8 %x, i1 %c1, i1 %c2) {
133132
; CHECK-NEXT: [[COND:%.*]] = and i1 [[C3]], [[CMP]]
134133
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
135134
; CHECK: if:
136-
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
137-
; CHECK-NEXT: ret i8 [[OR1]]
135+
; CHECK-NEXT: ret i8 -4
138136
; CHECK: exit:
139137
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
140138
; CHECK-NEXT: ret i8 [[OR2]]
@@ -161,8 +159,7 @@ define i8 @test_cond_logical_and(i8 %x, i1 %c) {
161159
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i1 [[C:%.*]], i1 false
162160
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
163161
; CHECK: if:
164-
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
165-
; CHECK-NEXT: ret i8 [[OR1]]
162+
; CHECK-NEXT: ret i8 -4
166163
; CHECK: exit:
167164
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
168165
; CHECK-NEXT: ret i8 [[OR2]]
@@ -218,8 +215,7 @@ define i8 @test_cond_inv_or(i8 %x, i1 %c) {
218215
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
219216
; CHECK-NEXT: ret i8 [[OR1]]
220217
; CHECK: exit:
221-
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
222-
; CHECK-NEXT: ret i8 [[OR2]]
218+
; CHECK-NEXT: ret i8 -4
223219
;
224220
%and = and i8 %x, 3
225221
%cmp = icmp ne i8 %and, 0
@@ -242,8 +238,7 @@ define i8 @test_cond_inv_logical_or(i8 %x, i1 %c) {
242238
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP_NOT]], i1 [[C:%.*]], i1 false
243239
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
244240
; CHECK: if:
245-
; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
246-
; CHECK-NEXT: ret i8 [[OR1]]
241+
; CHECK-NEXT: ret i8 -4
247242
; CHECK: exit:
248243
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
249244
; CHECK-NEXT: ret i8 [[OR2]]

llvm/test/Transforms/LoopVectorize/induction.ll

+15-15
Original file line numberDiff line numberDiff line change
@@ -3525,10 +3525,10 @@ define void @wrappingindvars1(i8 %t, i32 %len, ptr %A) {
35253525
; IND-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
35263526
; IND-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
35273527
; IND: vector.ph:
3528-
; IND-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -2
3528+
; IND-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 510
35293529
; IND-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
35303530
; IND-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
3531-
; IND-NEXT: [[IND_END2:%.*]] = add i32 [[N_VEC]], [[EXT]]
3531+
; IND-NEXT: [[IND_END2:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
35323532
; IND-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[EXT]], i64 0
35333533
; IND-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i32> [[DOTSPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
35343534
; IND-NEXT: [[INDUCTION:%.*]] = add nuw nsw <2 x i32> [[DOTSPLAT]], <i32 0, i32 1>
@@ -3591,10 +3591,10 @@ define void @wrappingindvars1(i8 %t, i32 %len, ptr %A) {
35913591
; UNROLL-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
35923592
; UNROLL-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
35933593
; UNROLL: vector.ph:
3594-
; UNROLL-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -4
3594+
; UNROLL-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 508
35953595
; UNROLL-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
35963596
; UNROLL-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
3597-
; UNROLL-NEXT: [[IND_END2:%.*]] = add i32 [[N_VEC]], [[EXT]]
3597+
; UNROLL-NEXT: [[IND_END2:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
35983598
; UNROLL-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[EXT]], i64 0
35993599
; UNROLL-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i32> [[DOTSPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
36003600
; UNROLL-NEXT: [[INDUCTION:%.*]] = add nuw nsw <2 x i32> [[DOTSPLAT]], <i32 0, i32 1>
@@ -3735,10 +3735,10 @@ define void @wrappingindvars1(i8 %t, i32 %len, ptr %A) {
37353735
; INTERLEAVE-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
37363736
; INTERLEAVE-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
37373737
; INTERLEAVE: vector.ph:
3738-
; INTERLEAVE-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -8
3738+
; INTERLEAVE-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 504
37393739
; INTERLEAVE-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
37403740
; INTERLEAVE-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
3741-
; INTERLEAVE-NEXT: [[IND_END2:%.*]] = add i32 [[N_VEC]], [[EXT]]
3741+
; INTERLEAVE-NEXT: [[IND_END2:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
37423742
; INTERLEAVE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[EXT]], i64 0
37433743
; INTERLEAVE-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x i32> [[DOTSPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
37443744
; INTERLEAVE-NEXT: [[INDUCTION:%.*]] = add nuw nsw <4 x i32> [[DOTSPLAT]], <i32 0, i32 1, i32 2, i32 3>
@@ -3909,11 +3909,11 @@ define void @wrappingindvars2(i8 %t, i32 %len, ptr %A) {
39093909
; IND-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
39103910
; IND-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
39113911
; IND: vector.ph:
3912-
; IND-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -2
3912+
; IND-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 510
39133913
; IND-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
39143914
; IND-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
3915-
; IND-NEXT: [[EXT_MUL5:%.*]] = add i32 [[N_VEC]], [[EXT]]
3916-
; IND-NEXT: [[IND_END1:%.*]] = shl i32 [[EXT_MUL5]], 2
3915+
; IND-NEXT: [[EXT_MUL5:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
3916+
; IND-NEXT: [[IND_END1:%.*]] = shl nuw nsw i32 [[EXT_MUL5]], 2
39173917
; IND-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[EXT_MUL]], i64 0
39183918
; IND-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i32> [[DOTSPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
39193919
; IND-NEXT: [[INDUCTION:%.*]] = add nuw nsw <2 x i32> [[DOTSPLAT]], <i32 0, i32 4>
@@ -3978,11 +3978,11 @@ define void @wrappingindvars2(i8 %t, i32 %len, ptr %A) {
39783978
; UNROLL-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
39793979
; UNROLL-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
39803980
; UNROLL: vector.ph:
3981-
; UNROLL-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -4
3981+
; UNROLL-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 508
39823982
; UNROLL-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
39833983
; UNROLL-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
3984-
; UNROLL-NEXT: [[EXT_MUL6:%.*]] = add i32 [[N_VEC]], [[EXT]]
3985-
; UNROLL-NEXT: [[IND_END1:%.*]] = shl i32 [[EXT_MUL6]], 2
3984+
; UNROLL-NEXT: [[EXT_MUL6:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
3985+
; UNROLL-NEXT: [[IND_END1:%.*]] = shl nuw nsw i32 [[EXT_MUL6]], 2
39863986
; UNROLL-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[EXT_MUL]], i64 0
39873987
; UNROLL-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i32> [[DOTSPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
39883988
; UNROLL-NEXT: [[INDUCTION:%.*]] = add nuw nsw <2 x i32> [[DOTSPLAT]], <i32 0, i32 4>
@@ -4128,11 +4128,11 @@ define void @wrappingindvars2(i8 %t, i32 %len, ptr %A) {
41284128
; INTERLEAVE-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
41294129
; INTERLEAVE-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
41304130
; INTERLEAVE: vector.ph:
4131-
; INTERLEAVE-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -8
4131+
; INTERLEAVE-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 504
41324132
; INTERLEAVE-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
41334133
; INTERLEAVE-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
4134-
; INTERLEAVE-NEXT: [[EXT_MUL6:%.*]] = add i32 [[N_VEC]], [[EXT]]
4135-
; INTERLEAVE-NEXT: [[IND_END1:%.*]] = shl i32 [[EXT_MUL6]], 2
4134+
; INTERLEAVE-NEXT: [[EXT_MUL6:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
4135+
; INTERLEAVE-NEXT: [[IND_END1:%.*]] = shl nuw nsw i32 [[EXT_MUL6]], 2
41364136
; INTERLEAVE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[EXT_MUL]], i64 0
41374137
; INTERLEAVE-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x i32> [[DOTSPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
41384138
; INTERLEAVE-NEXT: [[INDUCTION:%.*]] = add nuw nsw <4 x i32> [[DOTSPLAT]], <i32 0, i32 4, i32 8, i32 12>

0 commit comments

Comments
 (0)