|
16 | 16 | #include "llvm/ADT/SmallPtrSet.h"
|
17 | 17 | #include "llvm/ADT/SmallVector.h"
|
18 | 18 | #include "llvm/Analysis/AssumeBundleQueries.h"
|
| 19 | +#include "llvm/Analysis/ConditionCacheUtil.h" |
19 | 20 | #include "llvm/Analysis/TargetTransformInfo.h"
|
20 | 21 | #include "llvm/Analysis/ValueTracking.h"
|
21 | 22 | #include "llvm/IR/BasicBlock.h"
|
@@ -61,85 +62,35 @@ findAffectedValues(CallBase *CI, TargetTransformInfo *TTI,
|
61 | 62 | // Note: This code must be kept in-sync with the code in
|
62 | 63 | // computeKnownBitsFromAssume in ValueTracking.
|
63 | 64 |
|
64 |
| - auto AddAffected = [&Affected](Value *V, unsigned Idx = |
65 |
| - AssumptionCache::ExprResultIdx) { |
66 |
| - if (isa<Argument>(V) || isa<GlobalValue>(V)) { |
67 |
| - Affected.push_back({V, Idx}); |
68 |
| - } else if (auto *I = dyn_cast<Instruction>(V)) { |
69 |
| - Affected.push_back({I, Idx}); |
70 |
| - |
71 |
| - // Peek through unary operators to find the source of the condition. |
72 |
| - Value *Op; |
73 |
| - if (match(I, m_PtrToInt(m_Value(Op)))) { |
74 |
| - if (isa<Instruction>(Op) || isa<Argument>(Op)) |
75 |
| - Affected.push_back({Op, Idx}); |
76 |
| - } |
77 |
| - } |
| 65 | + auto InsertAffected = [&Affected](Value *V, int Idx) { |
| 66 | + Affected.push_back({V, Idx < 0 ? AssumptionCache::ExprResultIdx : Idx}); |
78 | 67 | };
|
79 | 68 |
|
80 | 69 | for (unsigned Idx = 0; Idx != CI->getNumOperandBundles(); Idx++) {
|
81 | 70 | OperandBundleUse Bundle = CI->getOperandBundleAt(Idx);
|
82 | 71 | if (Bundle.getTagName() == "separate_storage") {
|
83 | 72 | assert(Bundle.Inputs.size() == 2 &&
|
84 | 73 | "separate_storage must have two args");
|
85 |
| - AddAffected(getUnderlyingObject(Bundle.Inputs[0]), Idx); |
86 |
| - AddAffected(getUnderlyingObject(Bundle.Inputs[1]), Idx); |
| 74 | + addValueAffectedByCondition(getUnderlyingObject(Bundle.Inputs[0]), |
| 75 | + InsertAffected, Idx); |
| 76 | + addValueAffectedByCondition(getUnderlyingObject(Bundle.Inputs[1]), |
| 77 | + InsertAffected, Idx); |
87 | 78 | } else if (Bundle.Inputs.size() > ABA_WasOn &&
|
88 | 79 | Bundle.getTagName() != IgnoreBundleTag)
|
89 |
| - AddAffected(Bundle.Inputs[ABA_WasOn], Idx); |
| 80 | + addValueAffectedByCondition(Bundle.Inputs[ABA_WasOn], InsertAffected, |
| 81 | + Idx); |
90 | 82 | }
|
91 | 83 |
|
92 |
| - Value *Cond = CI->getArgOperand(0), *A, *B; |
93 |
| - AddAffected(Cond); |
94 |
| - if (match(Cond, m_Not(m_Value(A)))) |
95 |
| - AddAffected(A); |
96 |
| - |
97 |
| - CmpInst::Predicate Pred; |
98 |
| - if (match(Cond, m_Cmp(Pred, m_Value(A), m_Value(B)))) { |
99 |
| - AddAffected(A); |
100 |
| - AddAffected(B); |
101 |
| - |
102 |
| - if (Pred == ICmpInst::ICMP_EQ) { |
103 |
| - if (match(B, m_ConstantInt())) { |
104 |
| - Value *X; |
105 |
| - // (X & C) or (X | C) or (X ^ C). |
106 |
| - // (X << C) or (X >>_s C) or (X >>_u C). |
107 |
| - if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) || |
108 |
| - match(A, m_Shift(m_Value(X), m_ConstantInt()))) |
109 |
| - AddAffected(X); |
110 |
| - } |
111 |
| - } else if (Pred == ICmpInst::ICMP_NE) { |
112 |
| - Value *X; |
113 |
| - // Handle (X & pow2 != 0). |
114 |
| - if (match(A, m_And(m_Value(X), m_Power2())) && match(B, m_Zero())) |
115 |
| - AddAffected(X); |
116 |
| - } else if (Pred == ICmpInst::ICMP_ULT) { |
117 |
| - Value *X; |
118 |
| - // Handle (A + C1) u< C2, which is the canonical form of A > C3 && A < C4, |
119 |
| - // and recognized by LVI at least. |
120 |
| - if (match(A, m_Add(m_Value(X), m_ConstantInt())) && |
121 |
| - match(B, m_ConstantInt())) |
122 |
| - AddAffected(X); |
123 |
| - } else if (CmpInst::isFPPredicate(Pred)) { |
124 |
| - // fcmp fneg(x), y |
125 |
| - // fcmp fabs(x), y |
126 |
| - // fcmp fneg(fabs(x)), y |
127 |
| - if (match(A, m_FNeg(m_Value(A)))) |
128 |
| - AddAffected(A); |
129 |
| - if (match(A, m_FAbs(m_Value(A)))) |
130 |
| - AddAffected(A); |
131 |
| - } |
132 |
| - } else if (match(Cond, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A), |
133 |
| - m_Value(B)))) { |
134 |
| - AddAffected(A); |
135 |
| - } |
| 84 | + Value *Cond = CI->getArgOperand(0); |
| 85 | + findValuesAffectedByCondition(Cond, /*IsAssume*/ true, InsertAffected); |
136 | 86 |
|
137 | 87 | if (TTI) {
|
138 | 88 | const Value *Ptr;
|
139 | 89 | unsigned AS;
|
140 | 90 | std::tie(Ptr, AS) = TTI->getPredicatedAddrSpace(Cond);
|
141 | 91 | if (Ptr)
|
142 |
| - AddAffected(const_cast<Value *>(Ptr->stripInBoundsOffsets())); |
| 92 | + addValueAffectedByCondition( |
| 93 | + const_cast<Value *>(Ptr->stripInBoundsOffsets()), InsertAffected); |
143 | 94 | }
|
144 | 95 | }
|
145 | 96 |
|
|
0 commit comments