1
+ // ===- llvm/Analysis/ConditionCacheUtil.h -----------------------*- C++ -*-===//
2
+ //
3
+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
+ // See https://llvm.org/LICENSE.txt for license information.
5
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
+ //
7
+ // ===----------------------------------------------------------------------===//
8
+ //
9
+ // Shared by DomConditionCache and AssumptionCache. Holds common operation of
10
+ // finding values potentially affected by an assumed/branched on condition.
11
+ //
12
+ // ===----------------------------------------------------------------------===//
13
+
1
14
#ifndef LLVM_ANALYSIS_CONDITIONCACHEUTIL_H
2
15
#define LLVM_ANALYSIS_CONDITIONCACHEUTIL_H
3
16
17
+ #include " llvm/ADT/SmallVector.h"
4
18
#include " llvm/IR/PatternMatch.h"
5
19
#include < functional>
6
20
@@ -32,6 +46,14 @@ findValuesAffectedByCondition(Value *Cond, bool IsAssume,
32
46
addValueAffectedByCondition (V, InsertAffected);
33
47
};
34
48
49
+ auto AddCmpOperands = [&AddAffected, IsAssume](Value *LHS, Value *RHS) {
50
+ if (IsAssume) {
51
+ AddAffected (LHS);
52
+ AddAffected (RHS);
53
+ } else if (match (RHS, m_Constant ()))
54
+ AddAffected (LHS);
55
+ };
56
+
35
57
SmallVector<Value *, 8 > Worklist;
36
58
SmallPtrSet<Value *, 8 > Visited;
37
59
Worklist.push_back (Cond);
@@ -43,65 +65,61 @@ findValuesAffectedByCondition(Value *Cond, bool IsAssume,
43
65
CmpInst::Predicate Pred;
44
66
Value *A, *B, *X;
45
67
46
- if (IsAssume)
68
+ if (IsAssume) {
47
69
AddAffected (V);
70
+ if (match (V, m_Not (m_Value (X))))
71
+ AddAffected (X);
72
+ }
48
73
49
- if (IsAssume && match (V, m_Not (m_Value (X))))
50
- AddAffected (X);
51
- if (!IsAssume && match (V, m_LogicalOp (m_Value (A), m_Value (B)))) {
52
- Worklist.push_back (A);
53
- Worklist.push_back (B);
54
- } else if (match (V, m_Cmp (Pred, m_Value (A), m_Value (B))) &&
55
- (IsAssume || isa<ICmpInst>(V))) {
56
- if (IsAssume || match (B, m_Constant ())) {
57
- AddAffected (A);
58
- if (IsAssume)
59
- AddAffected (B);
60
-
61
- if (IsAssume ? (Pred == ICmpInst::ICMP_EQ)
62
- : ICmpInst::isEquality (Pred)) {
63
- if (match (B, m_ConstantInt ())) {
64
- // (X & C) or (X | C) or (X ^ C).
65
- // (X << C) or (X >>_s C) or (X >>_u C).
66
- if (match (A, m_BitwiseLogic (m_Value (X), m_ConstantInt ())) ||
67
- match (A, m_Shift (m_Value (X), m_ConstantInt ())))
68
- AddAffected (X);
69
- }
70
- } else {
71
- if (Pred == ICmpInst::ICMP_NE)
72
- if (match (A, m_And (m_Value (X), m_Power2 ())) && match (B, m_Zero ()))
73
- AddAffected (X);
74
-
75
- if (!IsAssume || Pred == ICmpInst::ICMP_ULT) {
76
- // Handle (A + C1) u< C2, which is the canonical form of
77
- // A > C3 && A < C4.
78
- if (match (A, m_Add (m_Value (X), m_ConstantInt ())) &&
79
- match (B, m_ConstantInt ()))
80
- AddAffected (X);
81
- }
82
- if (!IsAssume) {
83
- // Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
84
- // by computeKnownFPClass().
85
- if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGT) &&
86
- match (A, m_ElementWiseBitCast (m_Value (X))))
87
- InsertAffected (X, -1 );
88
- }
89
-
90
- if (IsAssume && CmpInst::isFPPredicate (Pred)) {
91
- // fcmp fneg(x), y
92
- // fcmp fabs(x), y
93
- // fcmp fneg(fabs(x)), y
94
- if (match (A, m_FNeg (m_Value (A))))
95
- AddAffected (A);
96
- if (match (A, m_FAbs (m_Value (A))))
97
- AddAffected (A);
98
- }
74
+ if (match (V, m_LogicalOp (m_Value (A), m_Value (B)))) {
75
+ // assume(A && B) is split to -> assume(A); assume(B);
76
+ // assume(!(A || B)) is split to -> assume(!A); assume(!B);
77
+ // TODO: We might want to handle assume(A || B) / assume(!(A && B)). If we
78
+ // make this change make sure to update computeKnownBitsFromContext.
79
+ if (!IsAssume) {
80
+ Worklist.push_back (A);
81
+ Worklist.push_back (B);
82
+ }
83
+ } else if (match (V, m_ICmp (Pred, m_Value (A), m_Value (B)))) {
84
+ AddCmpOperands (A, B);
85
+
86
+ if (ICmpInst::isEquality (Pred)) {
87
+ if (match (B, m_ConstantInt ())) {
88
+ // (X & C) or (X | C) or (X ^ C).
89
+ // (X << C) or (X >>_s C) or (X >>_u C).
90
+ if (match (A, m_BitwiseLogic (m_Value (X), m_ConstantInt ())) ||
91
+ match (A, m_Shift (m_Value (X), m_ConstantInt ())))
92
+ AddAffected (X);
93
+ }
94
+ } else {
95
+ // Handle (A + C1) u< C2, which is the canonical form of
96
+ // A > C3 && A < C4.
97
+ if (match (A, m_Add (m_Value (X), m_ConstantInt ())) &&
98
+ match (B, m_ConstantInt ()))
99
+ AddAffected (X);
100
+
101
+ // Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
102
+ // by computeKnownFPClass().
103
+ if (match (A, m_ElementWiseBitCast (m_Value (X)))) {
104
+ if (Pred == ICmpInst::ICMP_SLT && match (B, m_Zero ()))
105
+ InsertAffected (X, -1 );
106
+ else if (Pred == ICmpInst::ICMP_SGT && match (B, m_AllOnes ()))
107
+ InsertAffected (X, -1 );
99
108
}
100
109
}
101
- } else if ((!IsAssume &&
102
- match (Cond, m_FCmp (Pred, m_Value (A), m_Constant ()))) ||
103
- match (Cond, m_Intrinsic<Intrinsic::is_fpclass>(m_Value (A),
104
- m_Value (B)))) {
110
+ } else if (match (Cond, m_FCmp (Pred, m_Value (A), m_Value (B)))) {
111
+ AddCmpOperands (A, B);
112
+
113
+ // fcmp fneg(x), y
114
+ // fcmp fabs(x), y
115
+ // fcmp fneg(fabs(x)), y
116
+ if (match (A, m_FNeg (m_Value (A))))
117
+ AddAffected (A);
118
+ if (match (A, m_FAbs (m_Value (A))))
119
+ AddAffected (A);
120
+
121
+ } else if (match (V, m_Intrinsic<Intrinsic::is_fpclass>(m_Value (A),
122
+ m_Value ()))) {
105
123
// Handle patterns that computeKnownFPClass() support.
106
124
AddAffected (A);
107
125
}
0 commit comments