Skip to content

Commit 7c0d52c

Browse files
authored
[ValueTracking] Support dominating known bits condition in and/or (#74728)
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 35d6ae8 commit 7c0d52c

File tree

4 files changed

+74
-51
lines changed

4 files changed

+74
-51
lines changed

llvm/lib/Analysis/DomConditionCache.cpp

Lines changed: 32 additions & 16 deletions
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

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -706,28 +706,40 @@ static void computeKnownBitsFromCmp(const Value *V, CmpInst::Predicate Pred,
706706
}
707707
}
708708

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

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

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

733745
if (Known.hasConflict())

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

Lines changed: 5 additions & 10 deletions
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

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3523,10 +3523,10 @@ define void @wrappingindvars1(i8 %t, i32 %len, ptr %A) {
35233523
; IND-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
35243524
; IND-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
35253525
; IND: vector.ph:
3526-
; IND-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -2
3526+
; IND-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 510
35273527
; IND-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
35283528
; IND-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
3529-
; IND-NEXT: [[IND_END2:%.*]] = add i32 [[N_VEC]], [[EXT]]
3529+
; IND-NEXT: [[IND_END2:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
35303530
; IND-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[EXT]], i64 0
35313531
; IND-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i32> [[DOTSPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
35323532
; IND-NEXT: [[INDUCTION:%.*]] = add nuw nsw <2 x i32> [[DOTSPLAT]], <i32 0, i32 1>
@@ -3589,10 +3589,10 @@ define void @wrappingindvars1(i8 %t, i32 %len, ptr %A) {
35893589
; UNROLL-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
35903590
; UNROLL-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
35913591
; UNROLL: vector.ph:
3592-
; UNROLL-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -4
3592+
; UNROLL-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 508
35933593
; UNROLL-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
35943594
; UNROLL-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
3595-
; UNROLL-NEXT: [[IND_END2:%.*]] = add i32 [[N_VEC]], [[EXT]]
3595+
; UNROLL-NEXT: [[IND_END2:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
35963596
; UNROLL-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[EXT]], i64 0
35973597
; UNROLL-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i32> [[DOTSPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
35983598
; UNROLL-NEXT: [[INDUCTION:%.*]] = add nuw nsw <2 x i32> [[DOTSPLAT]], <i32 0, i32 1>
@@ -3733,10 +3733,10 @@ define void @wrappingindvars1(i8 %t, i32 %len, ptr %A) {
37333733
; INTERLEAVE-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
37343734
; INTERLEAVE-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
37353735
; INTERLEAVE: vector.ph:
3736-
; INTERLEAVE-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -8
3736+
; INTERLEAVE-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 504
37373737
; INTERLEAVE-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
37383738
; INTERLEAVE-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
3739-
; INTERLEAVE-NEXT: [[IND_END2:%.*]] = add i32 [[N_VEC]], [[EXT]]
3739+
; INTERLEAVE-NEXT: [[IND_END2:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
37403740
; INTERLEAVE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[EXT]], i64 0
37413741
; INTERLEAVE-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x i32> [[DOTSPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
37423742
; INTERLEAVE-NEXT: [[INDUCTION:%.*]] = add nuw nsw <4 x i32> [[DOTSPLAT]], <i32 0, i32 1, i32 2, i32 3>
@@ -3907,11 +3907,11 @@ define void @wrappingindvars2(i8 %t, i32 %len, ptr %A) {
39073907
; IND-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
39083908
; IND-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
39093909
; IND: vector.ph:
3910-
; IND-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -2
3910+
; IND-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 510
39113911
; IND-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
39123912
; IND-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
3913-
; IND-NEXT: [[EXT_MUL5:%.*]] = add i32 [[N_VEC]], [[EXT]]
3914-
; IND-NEXT: [[IND_END1:%.*]] = shl i32 [[EXT_MUL5]], 2
3913+
; IND-NEXT: [[EXT_MUL5:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
3914+
; IND-NEXT: [[IND_END1:%.*]] = shl nuw nsw i32 [[EXT_MUL5]], 2
39153915
; IND-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[EXT_MUL]], i64 0
39163916
; IND-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i32> [[DOTSPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
39173917
; IND-NEXT: [[INDUCTION:%.*]] = add nuw nsw <2 x i32> [[DOTSPLAT]], <i32 0, i32 4>
@@ -3976,11 +3976,11 @@ define void @wrappingindvars2(i8 %t, i32 %len, ptr %A) {
39763976
; UNROLL-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
39773977
; UNROLL-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
39783978
; UNROLL: vector.ph:
3979-
; UNROLL-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -4
3979+
; UNROLL-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 508
39803980
; UNROLL-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
39813981
; UNROLL-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
3982-
; UNROLL-NEXT: [[EXT_MUL6:%.*]] = add i32 [[N_VEC]], [[EXT]]
3983-
; UNROLL-NEXT: [[IND_END1:%.*]] = shl i32 [[EXT_MUL6]], 2
3982+
; UNROLL-NEXT: [[EXT_MUL6:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
3983+
; UNROLL-NEXT: [[IND_END1:%.*]] = shl nuw nsw i32 [[EXT_MUL6]], 2
39843984
; UNROLL-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[EXT_MUL]], i64 0
39853985
; UNROLL-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i32> [[DOTSPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
39863986
; UNROLL-NEXT: [[INDUCTION:%.*]] = add nuw nsw <2 x i32> [[DOTSPLAT]], <i32 0, i32 4>
@@ -4126,11 +4126,11 @@ define void @wrappingindvars2(i8 %t, i32 %len, ptr %A) {
41264126
; INTERLEAVE-NEXT: [[TMP9:%.*]] = or i1 [[TMP3]], [[TMP8]]
41274127
; INTERLEAVE-NEXT: br i1 [[TMP9]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
41284128
; INTERLEAVE: vector.ph:
4129-
; INTERLEAVE-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], -8
4129+
; INTERLEAVE-NEXT: [[N_VEC:%.*]] = and i32 [[TMP0]], 504
41304130
; INTERLEAVE-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i8
41314131
; INTERLEAVE-NEXT: [[IND_END:%.*]] = add i8 [[DOTCAST]], [[T]]
4132-
; INTERLEAVE-NEXT: [[EXT_MUL6:%.*]] = add i32 [[N_VEC]], [[EXT]]
4133-
; INTERLEAVE-NEXT: [[IND_END1:%.*]] = shl i32 [[EXT_MUL6]], 2
4132+
; INTERLEAVE-NEXT: [[EXT_MUL6:%.*]] = add nuw nsw i32 [[N_VEC]], [[EXT]]
4133+
; INTERLEAVE-NEXT: [[IND_END1:%.*]] = shl nuw nsw i32 [[EXT_MUL6]], 2
41344134
; INTERLEAVE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[EXT_MUL]], i64 0
41354135
; INTERLEAVE-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x i32> [[DOTSPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
41364136
; INTERLEAVE-NEXT: [[INDUCTION:%.*]] = add nuw nsw <4 x i32> [[DOTSPLAT]], <i32 0, i32 4, i32 8, i32 12>

0 commit comments

Comments
 (0)