]>
Commit | Line | Data |
---|---|---|
1a4d82fc | 1 | //===- PatternMatch.h - Match on the LLVM IR --------------------*- C++ -*-===// |
223e47cc LB |
2 | // |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | // | |
10 | // This file provides a simple and efficient mechanism for performing general | |
11 | // tree-based pattern matches on the LLVM IR. The power of these routines is | |
12 | // that it allows you to write concise patterns that are expressive and easy to | |
13 | // understand. The other major advantage of this is that it allows you to | |
14 | // trivially capture/bind elements in the pattern to variables. For example, | |
15 | // you can do something like this: | |
16 | // | |
17 | // Value *Exp = ... | |
18 | // Value *X, *Y; ConstantInt *C1, *C2; // (X & C1) | (Y & C2) | |
19 | // if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)), | |
20 | // m_And(m_Value(Y), m_ConstantInt(C2))))) { | |
21 | // ... Pattern is matched and variables are bound ... | |
22 | // } | |
23 | // | |
24 | // This is primarily useful to things like the instruction combiner, but can | |
25 | // also be useful for static analysis tools or code generators. | |
26 | // | |
27 | //===----------------------------------------------------------------------===// | |
28 | ||
1a4d82fc JJ |
29 | #ifndef LLVM_IR_PATTERNMATCH_H |
30 | #define LLVM_IR_PATTERNMATCH_H | |
223e47cc | 31 | |
1a4d82fc | 32 | #include "llvm/IR/CallSite.h" |
970d7e83 LB |
33 | #include "llvm/IR/Constants.h" |
34 | #include "llvm/IR/Instructions.h" | |
85aaf69f | 35 | #include "llvm/IR/Intrinsics.h" |
970d7e83 | 36 | #include "llvm/IR/Operator.h" |
223e47cc LB |
37 | |
38 | namespace llvm { | |
39 | namespace PatternMatch { | |
40 | ||
85aaf69f SL |
41 | template <typename Val, typename Pattern> bool match(Val *V, const Pattern &P) { |
42 | return const_cast<Pattern &>(P).match(V); | |
223e47cc LB |
43 | } |
44 | ||
85aaf69f | 45 | template <typename SubPattern_t> struct OneUse_match { |
223e47cc | 46 | SubPattern_t SubPattern; |
970d7e83 | 47 | |
223e47cc | 48 | OneUse_match(const SubPattern_t &SP) : SubPattern(SP) {} |
970d7e83 | 49 | |
85aaf69f | 50 | template <typename OpTy> bool match(OpTy *V) { |
223e47cc LB |
51 | return V->hasOneUse() && SubPattern.match(V); |
52 | } | |
53 | }; | |
54 | ||
85aaf69f SL |
55 | template <typename T> inline OneUse_match<T> m_OneUse(const T &SubPattern) { |
56 | return SubPattern; | |
57 | } | |
970d7e83 | 58 | |
85aaf69f SL |
59 | template <typename Class> struct class_match { |
60 | template <typename ITy> bool match(ITy *V) { return isa<Class>(V); } | |
223e47cc LB |
61 | }; |
62 | ||
85aaf69f | 63 | /// \brief Match an arbitrary value and ignore it. |
223e47cc | 64 | inline class_match<Value> m_Value() { return class_match<Value>(); } |
85aaf69f SL |
65 | |
66 | /// \brief Match an arbitrary binary operation and ignore it. | |
67 | inline class_match<BinaryOperator> m_BinOp() { | |
68 | return class_match<BinaryOperator>(); | |
69 | } | |
70 | ||
71 | /// \brief Matches any compare instruction and ignore it. | |
72 | inline class_match<CmpInst> m_Cmp() { return class_match<CmpInst>(); } | |
73 | ||
74 | /// \brief Match an arbitrary ConstantInt and ignore it. | |
223e47cc LB |
75 | inline class_match<ConstantInt> m_ConstantInt() { |
76 | return class_match<ConstantInt>(); | |
77 | } | |
85aaf69f SL |
78 | |
79 | /// \brief Match an arbitrary undef constant. | |
223e47cc LB |
80 | inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); } |
81 | ||
85aaf69f | 82 | /// \brief Match an arbitrary Constant and ignore it. |
223e47cc | 83 | inline class_match<Constant> m_Constant() { return class_match<Constant>(); } |
970d7e83 LB |
84 | |
85 | /// Matching combinators | |
85aaf69f | 86 | template <typename LTy, typename RTy> struct match_combine_or { |
970d7e83 LB |
87 | LTy L; |
88 | RTy R; | |
89 | ||
85aaf69f | 90 | match_combine_or(const LTy &Left, const RTy &Right) : L(Left), R(Right) {} |
970d7e83 | 91 | |
85aaf69f | 92 | template <typename ITy> bool match(ITy *V) { |
970d7e83 LB |
93 | if (L.match(V)) |
94 | return true; | |
95 | if (R.match(V)) | |
96 | return true; | |
97 | return false; | |
98 | } | |
99 | }; | |
100 | ||
85aaf69f | 101 | template <typename LTy, typename RTy> struct match_combine_and { |
970d7e83 LB |
102 | LTy L; |
103 | RTy R; | |
104 | ||
85aaf69f | 105 | match_combine_and(const LTy &Left, const RTy &Right) : L(Left), R(Right) {} |
970d7e83 | 106 | |
85aaf69f | 107 | template <typename ITy> bool match(ITy *V) { |
970d7e83 LB |
108 | if (L.match(V)) |
109 | if (R.match(V)) | |
110 | return true; | |
111 | return false; | |
112 | } | |
113 | }; | |
114 | ||
115 | /// Combine two pattern matchers matching L || R | |
85aaf69f | 116 | template <typename LTy, typename RTy> |
970d7e83 LB |
117 | inline match_combine_or<LTy, RTy> m_CombineOr(const LTy &L, const RTy &R) { |
118 | return match_combine_or<LTy, RTy>(L, R); | |
119 | } | |
120 | ||
121 | /// Combine two pattern matchers matching L && R | |
85aaf69f | 122 | template <typename LTy, typename RTy> |
970d7e83 LB |
123 | inline match_combine_and<LTy, RTy> m_CombineAnd(const LTy &L, const RTy &R) { |
124 | return match_combine_and<LTy, RTy>(L, R); | |
125 | } | |
126 | ||
223e47cc | 127 | struct match_zero { |
85aaf69f SL |
128 | template <typename ITy> bool match(ITy *V) { |
129 | if (const auto *C = dyn_cast<Constant>(V)) | |
223e47cc LB |
130 | return C->isNullValue(); |
131 | return false; | |
132 | } | |
133 | }; | |
970d7e83 | 134 | |
85aaf69f | 135 | /// \brief Match an arbitrary zero/null constant. This includes |
223e47cc LB |
136 | /// zero_initializer for vectors and ConstantPointerNull for pointers. |
137 | inline match_zero m_Zero() { return match_zero(); } | |
970d7e83 LB |
138 | |
139 | struct match_neg_zero { | |
85aaf69f SL |
140 | template <typename ITy> bool match(ITy *V) { |
141 | if (const auto *C = dyn_cast<Constant>(V)) | |
970d7e83 LB |
142 | return C->isNegativeZeroValue(); |
143 | return false; | |
144 | } | |
145 | }; | |
146 | ||
85aaf69f | 147 | /// \brief Match an arbitrary zero/null constant. This includes |
970d7e83 LB |
148 | /// zero_initializer for vectors and ConstantPointerNull for pointers. For |
149 | /// floating point constants, this will match negative zero but not positive | |
150 | /// zero | |
151 | inline match_neg_zero m_NegZero() { return match_neg_zero(); } | |
152 | ||
85aaf69f | 153 | /// \brief - Match an arbitrary zero/null constant. This includes |
970d7e83 LB |
154 | /// zero_initializer for vectors and ConstantPointerNull for pointers. For |
155 | /// floating point constants, this will match negative zero and positive zero | |
156 | inline match_combine_or<match_zero, match_neg_zero> m_AnyZero() { | |
157 | return m_CombineOr(m_Zero(), m_NegZero()); | |
158 | } | |
159 | ||
223e47cc LB |
160 | struct apint_match { |
161 | const APInt *&Res; | |
162 | apint_match(const APInt *&R) : Res(R) {} | |
85aaf69f SL |
163 | template <typename ITy> bool match(ITy *V) { |
164 | if (auto *CI = dyn_cast<ConstantInt>(V)) { | |
223e47cc LB |
165 | Res = &CI->getValue(); |
166 | return true; | |
167 | } | |
970d7e83 | 168 | if (V->getType()->isVectorTy()) |
85aaf69f SL |
169 | if (const auto *C = dyn_cast<Constant>(V)) |
170 | if (auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue())) { | |
970d7e83 LB |
171 | Res = &CI->getValue(); |
172 | return true; | |
173 | } | |
223e47cc LB |
174 | return false; |
175 | } | |
176 | }; | |
970d7e83 | 177 | |
85aaf69f | 178 | /// \brief Match a ConstantInt or splatted ConstantVector, binding the |
223e47cc LB |
179 | /// specified pointer to the contained APInt. |
180 | inline apint_match m_APInt(const APInt *&Res) { return Res; } | |
181 | ||
85aaf69f SL |
182 | template <int64_t Val> struct constantint_match { |
183 | template <typename ITy> bool match(ITy *V) { | |
184 | if (const auto *CI = dyn_cast<ConstantInt>(V)) { | |
223e47cc LB |
185 | const APInt &CIV = CI->getValue(); |
186 | if (Val >= 0) | |
187 | return CIV == static_cast<uint64_t>(Val); | |
188 | // If Val is negative, and CI is shorter than it, truncate to the right | |
189 | // number of bits. If it is larger, then we have to sign extend. Just | |
190 | // compare their negated values. | |
191 | return -CIV == -Val; | |
192 | } | |
193 | return false; | |
194 | } | |
195 | }; | |
196 | ||
85aaf69f SL |
197 | /// \brief Match a ConstantInt with a specific value. |
198 | template <int64_t Val> inline constantint_match<Val> m_ConstantInt() { | |
223e47cc LB |
199 | return constantint_match<Val>(); |
200 | } | |
201 | ||
85aaf69f SL |
202 | /// \brief This helper class is used to match scalar and vector constants that |
203 | /// satisfy a specified predicate. | |
204 | template <typename Predicate> struct cst_pred_ty : public Predicate { | |
205 | template <typename ITy> bool match(ITy *V) { | |
206 | if (const auto *CI = dyn_cast<ConstantInt>(V)) | |
223e47cc | 207 | return this->isValue(CI->getValue()); |
970d7e83 | 208 | if (V->getType()->isVectorTy()) |
85aaf69f SL |
209 | if (const auto *C = dyn_cast<Constant>(V)) |
210 | if (const auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue())) | |
970d7e83 | 211 | return this->isValue(CI->getValue()); |
223e47cc LB |
212 | return false; |
213 | } | |
214 | }; | |
970d7e83 | 215 | |
85aaf69f SL |
216 | /// \brief This helper class is used to match scalar and vector constants that |
217 | /// satisfy a specified predicate, and bind them to an APInt. | |
218 | template <typename Predicate> struct api_pred_ty : public Predicate { | |
223e47cc LB |
219 | const APInt *&Res; |
220 | api_pred_ty(const APInt *&R) : Res(R) {} | |
85aaf69f SL |
221 | template <typename ITy> bool match(ITy *V) { |
222 | if (const auto *CI = dyn_cast<ConstantInt>(V)) | |
223e47cc LB |
223 | if (this->isValue(CI->getValue())) { |
224 | Res = &CI->getValue(); | |
225 | return true; | |
226 | } | |
970d7e83 | 227 | if (V->getType()->isVectorTy()) |
85aaf69f SL |
228 | if (const auto *C = dyn_cast<Constant>(V)) |
229 | if (auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue())) | |
970d7e83 LB |
230 | if (this->isValue(CI->getValue())) { |
231 | Res = &CI->getValue(); | |
232 | return true; | |
233 | } | |
223e47cc LB |
234 | |
235 | return false; | |
236 | } | |
237 | }; | |
970d7e83 | 238 | |
223e47cc LB |
239 | struct is_one { |
240 | bool isValue(const APInt &C) { return C == 1; } | |
241 | }; | |
242 | ||
85aaf69f | 243 | /// \brief Match an integer 1 or a vector with all elements equal to 1. |
223e47cc LB |
244 | inline cst_pred_ty<is_one> m_One() { return cst_pred_ty<is_one>(); } |
245 | inline api_pred_ty<is_one> m_One(const APInt *&V) { return V; } | |
970d7e83 | 246 | |
223e47cc LB |
247 | struct is_all_ones { |
248 | bool isValue(const APInt &C) { return C.isAllOnesValue(); } | |
249 | }; | |
970d7e83 | 250 | |
85aaf69f SL |
251 | /// \brief Match an integer or vector with all bits set to true. |
252 | inline cst_pred_ty<is_all_ones> m_AllOnes() { | |
253 | return cst_pred_ty<is_all_ones>(); | |
254 | } | |
223e47cc LB |
255 | inline api_pred_ty<is_all_ones> m_AllOnes(const APInt *&V) { return V; } |
256 | ||
257 | struct is_sign_bit { | |
258 | bool isValue(const APInt &C) { return C.isSignBit(); } | |
259 | }; | |
260 | ||
85aaf69f SL |
261 | /// \brief Match an integer or vector with only the sign bit(s) set. |
262 | inline cst_pred_ty<is_sign_bit> m_SignBit() { | |
263 | return cst_pred_ty<is_sign_bit>(); | |
264 | } | |
223e47cc LB |
265 | inline api_pred_ty<is_sign_bit> m_SignBit(const APInt *&V) { return V; } |
266 | ||
267 | struct is_power2 { | |
268 | bool isValue(const APInt &C) { return C.isPowerOf2(); } | |
269 | }; | |
270 | ||
85aaf69f | 271 | /// \brief Match an integer or vector power of 2. |
223e47cc LB |
272 | inline cst_pred_ty<is_power2> m_Power2() { return cst_pred_ty<is_power2>(); } |
273 | inline api_pred_ty<is_power2> m_Power2(const APInt *&V) { return V; } | |
274 | ||
85aaf69f SL |
275 | struct is_maxsignedvalue { |
276 | bool isValue(const APInt &C) { return C.isMaxSignedValue(); } | |
277 | }; | |
278 | ||
279 | inline cst_pred_ty<is_maxsignedvalue> m_MaxSignedValue() { return cst_pred_ty<is_maxsignedvalue>(); } | |
280 | inline api_pred_ty<is_maxsignedvalue> m_MaxSignedValue(const APInt *&V) { return V; } | |
281 | ||
282 | template <typename Class> struct bind_ty { | |
223e47cc LB |
283 | Class *&VR; |
284 | bind_ty(Class *&V) : VR(V) {} | |
285 | ||
85aaf69f SL |
286 | template <typename ITy> bool match(ITy *V) { |
287 | if (auto *CV = dyn_cast<Class>(V)) { | |
223e47cc LB |
288 | VR = CV; |
289 | return true; | |
290 | } | |
291 | return false; | |
292 | } | |
293 | }; | |
294 | ||
85aaf69f | 295 | /// \brief Match a value, capturing it if we match. |
223e47cc LB |
296 | inline bind_ty<Value> m_Value(Value *&V) { return V; } |
297 | ||
85aaf69f SL |
298 | /// \brief Match a binary operator, capturing it if we match. |
299 | inline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; } | |
300 | ||
301 | /// \brief Match a ConstantInt, capturing the value if we match. | |
223e47cc LB |
302 | inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; } |
303 | ||
85aaf69f | 304 | /// \brief Match a Constant, capturing the value if we match. |
223e47cc LB |
305 | inline bind_ty<Constant> m_Constant(Constant *&C) { return C; } |
306 | ||
85aaf69f | 307 | /// \brief Match a ConstantFP, capturing the value if we match. |
970d7e83 LB |
308 | inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; } |
309 | ||
85aaf69f | 310 | /// \brief Match a specified Value*. |
223e47cc LB |
311 | struct specificval_ty { |
312 | const Value *Val; | |
313 | specificval_ty(const Value *V) : Val(V) {} | |
314 | ||
85aaf69f | 315 | template <typename ITy> bool match(ITy *V) { return V == Val; } |
223e47cc LB |
316 | }; |
317 | ||
85aaf69f | 318 | /// \brief Match if we have a specific specified value. |
223e47cc LB |
319 | inline specificval_ty m_Specific(const Value *V) { return V; } |
320 | ||
85aaf69f SL |
321 | /// \brief Match a specified floating point value or vector of all elements of |
322 | /// that value. | |
970d7e83 LB |
323 | struct specific_fpval { |
324 | double Val; | |
325 | specific_fpval(double V) : Val(V) {} | |
326 | ||
85aaf69f SL |
327 | template <typename ITy> bool match(ITy *V) { |
328 | if (const auto *CFP = dyn_cast<ConstantFP>(V)) | |
970d7e83 LB |
329 | return CFP->isExactlyValue(Val); |
330 | if (V->getType()->isVectorTy()) | |
85aaf69f SL |
331 | if (const auto *C = dyn_cast<Constant>(V)) |
332 | if (auto *CFP = dyn_cast_or_null<ConstantFP>(C->getSplatValue())) | |
970d7e83 LB |
333 | return CFP->isExactlyValue(Val); |
334 | return false; | |
335 | } | |
336 | }; | |
337 | ||
85aaf69f SL |
338 | /// \brief Match a specific floating point value or vector with all elements |
339 | /// equal to the value. | |
970d7e83 LB |
340 | inline specific_fpval m_SpecificFP(double V) { return specific_fpval(V); } |
341 | ||
85aaf69f | 342 | /// \brief Match a float 1.0 or vector with all elements equal to 1.0. |
970d7e83 LB |
343 | inline specific_fpval m_FPOne() { return m_SpecificFP(1.0); } |
344 | ||
223e47cc LB |
345 | struct bind_const_intval_ty { |
346 | uint64_t &VR; | |
347 | bind_const_intval_ty(uint64_t &V) : VR(V) {} | |
970d7e83 | 348 | |
85aaf69f SL |
349 | template <typename ITy> bool match(ITy *V) { |
350 | if (const auto *CV = dyn_cast<ConstantInt>(V)) | |
223e47cc LB |
351 | if (CV->getBitWidth() <= 64) { |
352 | VR = CV->getZExtValue(); | |
353 | return true; | |
354 | } | |
355 | return false; | |
356 | } | |
357 | }; | |
358 | ||
85aaf69f SL |
359 | /// \brief Match a specified integer value or vector of all elements of that |
360 | // value. | |
1a4d82fc JJ |
361 | struct specific_intval { |
362 | uint64_t Val; | |
363 | specific_intval(uint64_t V) : Val(V) {} | |
364 | ||
85aaf69f SL |
365 | template <typename ITy> bool match(ITy *V) { |
366 | const auto *CI = dyn_cast<ConstantInt>(V); | |
1a4d82fc JJ |
367 | if (!CI && V->getType()->isVectorTy()) |
368 | if (const auto *C = dyn_cast<Constant>(V)) | |
369 | CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()); | |
370 | ||
371 | if (CI && CI->getBitWidth() <= 64) | |
372 | return CI->getZExtValue() == Val; | |
373 | ||
374 | return false; | |
375 | } | |
376 | }; | |
377 | ||
85aaf69f SL |
378 | /// \brief Match a specific integer value or vector with all elements equal to |
379 | /// the value. | |
1a4d82fc JJ |
380 | inline specific_intval m_SpecificInt(uint64_t V) { return specific_intval(V); } |
381 | ||
85aaf69f SL |
382 | /// \brief Match a ConstantInt and bind to its value. This does not match |
383 | /// ConstantInts wider than 64-bits. | |
223e47cc | 384 | inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; } |
970d7e83 | 385 | |
85aaf69f SL |
386 | //===----------------------------------------------------------------------===// |
387 | // Matcher for any binary operator. | |
388 | // | |
389 | template <typename LHS_t, typename RHS_t> struct AnyBinaryOp_match { | |
390 | LHS_t L; | |
391 | RHS_t R; | |
392 | ||
393 | AnyBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} | |
394 | ||
395 | template <typename OpTy> bool match(OpTy *V) { | |
396 | if (auto *I = dyn_cast<BinaryOperator>(V)) | |
397 | return L.match(I->getOperand(0)) && R.match(I->getOperand(1)); | |
398 | return false; | |
399 | } | |
400 | }; | |
401 | ||
402 | template <typename LHS, typename RHS> | |
403 | inline AnyBinaryOp_match<LHS, RHS> m_BinOp(const LHS &L, const RHS &R) { | |
404 | return AnyBinaryOp_match<LHS, RHS>(L, R); | |
405 | } | |
406 | ||
223e47cc LB |
407 | //===----------------------------------------------------------------------===// |
408 | // Matchers for specific binary operators. | |
409 | // | |
410 | ||
85aaf69f | 411 | template <typename LHS_t, typename RHS_t, unsigned Opcode> |
223e47cc LB |
412 | struct BinaryOp_match { |
413 | LHS_t L; | |
414 | RHS_t R; | |
415 | ||
416 | BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} | |
417 | ||
85aaf69f | 418 | template <typename OpTy> bool match(OpTy *V) { |
223e47cc | 419 | if (V->getValueID() == Value::InstructionVal + Opcode) { |
85aaf69f | 420 | auto *I = cast<BinaryOperator>(V); |
223e47cc LB |
421 | return L.match(I->getOperand(0)) && R.match(I->getOperand(1)); |
422 | } | |
85aaf69f | 423 | if (auto *CE = dyn_cast<ConstantExpr>(V)) |
223e47cc LB |
424 | return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) && |
425 | R.match(CE->getOperand(1)); | |
426 | return false; | |
427 | } | |
428 | }; | |
429 | ||
85aaf69f SL |
430 | template <typename LHS, typename RHS> |
431 | inline BinaryOp_match<LHS, RHS, Instruction::Add> m_Add(const LHS &L, | |
432 | const RHS &R) { | |
223e47cc LB |
433 | return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R); |
434 | } | |
435 | ||
85aaf69f SL |
436 | template <typename LHS, typename RHS> |
437 | inline BinaryOp_match<LHS, RHS, Instruction::FAdd> m_FAdd(const LHS &L, | |
438 | const RHS &R) { | |
223e47cc LB |
439 | return BinaryOp_match<LHS, RHS, Instruction::FAdd>(L, R); |
440 | } | |
441 | ||
85aaf69f SL |
442 | template <typename LHS, typename RHS> |
443 | inline BinaryOp_match<LHS, RHS, Instruction::Sub> m_Sub(const LHS &L, | |
444 | const RHS &R) { | |
223e47cc LB |
445 | return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R); |
446 | } | |
447 | ||
85aaf69f SL |
448 | template <typename LHS, typename RHS> |
449 | inline BinaryOp_match<LHS, RHS, Instruction::FSub> m_FSub(const LHS &L, | |
450 | const RHS &R) { | |
223e47cc LB |
451 | return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R); |
452 | } | |
453 | ||
85aaf69f SL |
454 | template <typename LHS, typename RHS> |
455 | inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L, | |
456 | const RHS &R) { | |
223e47cc LB |
457 | return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R); |
458 | } | |
459 | ||
85aaf69f SL |
460 | template <typename LHS, typename RHS> |
461 | inline BinaryOp_match<LHS, RHS, Instruction::FMul> m_FMul(const LHS &L, | |
462 | const RHS &R) { | |
223e47cc LB |
463 | return BinaryOp_match<LHS, RHS, Instruction::FMul>(L, R); |
464 | } | |
465 | ||
85aaf69f SL |
466 | template <typename LHS, typename RHS> |
467 | inline BinaryOp_match<LHS, RHS, Instruction::UDiv> m_UDiv(const LHS &L, | |
468 | const RHS &R) { | |
223e47cc LB |
469 | return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R); |
470 | } | |
471 | ||
85aaf69f SL |
472 | template <typename LHS, typename RHS> |
473 | inline BinaryOp_match<LHS, RHS, Instruction::SDiv> m_SDiv(const LHS &L, | |
474 | const RHS &R) { | |
223e47cc LB |
475 | return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R); |
476 | } | |
477 | ||
85aaf69f SL |
478 | template <typename LHS, typename RHS> |
479 | inline BinaryOp_match<LHS, RHS, Instruction::FDiv> m_FDiv(const LHS &L, | |
480 | const RHS &R) { | |
223e47cc LB |
481 | return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R); |
482 | } | |
483 | ||
85aaf69f SL |
484 | template <typename LHS, typename RHS> |
485 | inline BinaryOp_match<LHS, RHS, Instruction::URem> m_URem(const LHS &L, | |
486 | const RHS &R) { | |
223e47cc LB |
487 | return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R); |
488 | } | |
489 | ||
85aaf69f SL |
490 | template <typename LHS, typename RHS> |
491 | inline BinaryOp_match<LHS, RHS, Instruction::SRem> m_SRem(const LHS &L, | |
492 | const RHS &R) { | |
223e47cc LB |
493 | return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R); |
494 | } | |
495 | ||
85aaf69f SL |
496 | template <typename LHS, typename RHS> |
497 | inline BinaryOp_match<LHS, RHS, Instruction::FRem> m_FRem(const LHS &L, | |
498 | const RHS &R) { | |
223e47cc LB |
499 | return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R); |
500 | } | |
501 | ||
85aaf69f SL |
502 | template <typename LHS, typename RHS> |
503 | inline BinaryOp_match<LHS, RHS, Instruction::And> m_And(const LHS &L, | |
504 | const RHS &R) { | |
223e47cc LB |
505 | return BinaryOp_match<LHS, RHS, Instruction::And>(L, R); |
506 | } | |
507 | ||
85aaf69f SL |
508 | template <typename LHS, typename RHS> |
509 | inline BinaryOp_match<LHS, RHS, Instruction::Or> m_Or(const LHS &L, | |
510 | const RHS &R) { | |
223e47cc LB |
511 | return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R); |
512 | } | |
513 | ||
85aaf69f SL |
514 | template <typename LHS, typename RHS> |
515 | inline BinaryOp_match<LHS, RHS, Instruction::Xor> m_Xor(const LHS &L, | |
516 | const RHS &R) { | |
223e47cc LB |
517 | return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R); |
518 | } | |
519 | ||
85aaf69f SL |
520 | template <typename LHS, typename RHS> |
521 | inline BinaryOp_match<LHS, RHS, Instruction::Shl> m_Shl(const LHS &L, | |
522 | const RHS &R) { | |
223e47cc LB |
523 | return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R); |
524 | } | |
525 | ||
85aaf69f SL |
526 | template <typename LHS, typename RHS> |
527 | inline BinaryOp_match<LHS, RHS, Instruction::LShr> m_LShr(const LHS &L, | |
528 | const RHS &R) { | |
223e47cc LB |
529 | return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R); |
530 | } | |
531 | ||
85aaf69f SL |
532 | template <typename LHS, typename RHS> |
533 | inline BinaryOp_match<LHS, RHS, Instruction::AShr> m_AShr(const LHS &L, | |
534 | const RHS &R) { | |
223e47cc LB |
535 | return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R); |
536 | } | |
537 | ||
85aaf69f SL |
538 | template <typename LHS_t, typename RHS_t, unsigned Opcode, |
539 | unsigned WrapFlags = 0> | |
1a4d82fc JJ |
540 | struct OverflowingBinaryOp_match { |
541 | LHS_t L; | |
542 | RHS_t R; | |
543 | ||
85aaf69f SL |
544 | OverflowingBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) |
545 | : L(LHS), R(RHS) {} | |
1a4d82fc | 546 | |
85aaf69f SL |
547 | template <typename OpTy> bool match(OpTy *V) { |
548 | if (auto *Op = dyn_cast<OverflowingBinaryOperator>(V)) { | |
1a4d82fc JJ |
549 | if (Op->getOpcode() != Opcode) |
550 | return false; | |
551 | if (WrapFlags & OverflowingBinaryOperator::NoUnsignedWrap && | |
552 | !Op->hasNoUnsignedWrap()) | |
553 | return false; | |
554 | if (WrapFlags & OverflowingBinaryOperator::NoSignedWrap && | |
555 | !Op->hasNoSignedWrap()) | |
556 | return false; | |
557 | return L.match(Op->getOperand(0)) && R.match(Op->getOperand(1)); | |
558 | } | |
559 | return false; | |
560 | } | |
561 | }; | |
562 | ||
563 | template <typename LHS, typename RHS> | |
564 | inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add, | |
565 | OverflowingBinaryOperator::NoSignedWrap> | |
566 | m_NSWAdd(const LHS &L, const RHS &R) { | |
567 | return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add, | |
568 | OverflowingBinaryOperator::NoSignedWrap>( | |
569 | L, R); | |
570 | } | |
571 | template <typename LHS, typename RHS> | |
572 | inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub, | |
573 | OverflowingBinaryOperator::NoSignedWrap> | |
574 | m_NSWSub(const LHS &L, const RHS &R) { | |
575 | return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub, | |
576 | OverflowingBinaryOperator::NoSignedWrap>( | |
577 | L, R); | |
578 | } | |
579 | template <typename LHS, typename RHS> | |
580 | inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul, | |
581 | OverflowingBinaryOperator::NoSignedWrap> | |
582 | m_NSWMul(const LHS &L, const RHS &R) { | |
583 | return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul, | |
584 | OverflowingBinaryOperator::NoSignedWrap>( | |
585 | L, R); | |
586 | } | |
587 | template <typename LHS, typename RHS> | |
588 | inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl, | |
589 | OverflowingBinaryOperator::NoSignedWrap> | |
590 | m_NSWShl(const LHS &L, const RHS &R) { | |
591 | return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl, | |
592 | OverflowingBinaryOperator::NoSignedWrap>( | |
593 | L, R); | |
594 | } | |
595 | ||
596 | template <typename LHS, typename RHS> | |
597 | inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add, | |
598 | OverflowingBinaryOperator::NoUnsignedWrap> | |
599 | m_NUWAdd(const LHS &L, const RHS &R) { | |
600 | return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add, | |
601 | OverflowingBinaryOperator::NoUnsignedWrap>( | |
602 | L, R); | |
603 | } | |
604 | template <typename LHS, typename RHS> | |
605 | inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub, | |
606 | OverflowingBinaryOperator::NoUnsignedWrap> | |
607 | m_NUWSub(const LHS &L, const RHS &R) { | |
608 | return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub, | |
609 | OverflowingBinaryOperator::NoUnsignedWrap>( | |
610 | L, R); | |
611 | } | |
612 | template <typename LHS, typename RHS> | |
613 | inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul, | |
614 | OverflowingBinaryOperator::NoUnsignedWrap> | |
615 | m_NUWMul(const LHS &L, const RHS &R) { | |
616 | return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul, | |
617 | OverflowingBinaryOperator::NoUnsignedWrap>( | |
618 | L, R); | |
619 | } | |
620 | template <typename LHS, typename RHS> | |
621 | inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl, | |
622 | OverflowingBinaryOperator::NoUnsignedWrap> | |
623 | m_NUWShl(const LHS &L, const RHS &R) { | |
624 | return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl, | |
625 | OverflowingBinaryOperator::NoUnsignedWrap>( | |
626 | L, R); | |
627 | } | |
628 | ||
223e47cc LB |
629 | //===----------------------------------------------------------------------===// |
630 | // Class that matches two different binary ops. | |
631 | // | |
85aaf69f | 632 | template <typename LHS_t, typename RHS_t, unsigned Opc1, unsigned Opc2> |
223e47cc LB |
633 | struct BinOp2_match { |
634 | LHS_t L; | |
635 | RHS_t R; | |
636 | ||
637 | BinOp2_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} | |
638 | ||
85aaf69f | 639 | template <typename OpTy> bool match(OpTy *V) { |
223e47cc LB |
640 | if (V->getValueID() == Value::InstructionVal + Opc1 || |
641 | V->getValueID() == Value::InstructionVal + Opc2) { | |
85aaf69f | 642 | auto *I = cast<BinaryOperator>(V); |
223e47cc LB |
643 | return L.match(I->getOperand(0)) && R.match(I->getOperand(1)); |
644 | } | |
85aaf69f | 645 | if (auto *CE = dyn_cast<ConstantExpr>(V)) |
223e47cc LB |
646 | return (CE->getOpcode() == Opc1 || CE->getOpcode() == Opc2) && |
647 | L.match(CE->getOperand(0)) && R.match(CE->getOperand(1)); | |
648 | return false; | |
649 | } | |
650 | }; | |
651 | ||
85aaf69f SL |
652 | /// \brief Matches LShr or AShr. |
653 | template <typename LHS, typename RHS> | |
223e47cc LB |
654 | inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr> |
655 | m_Shr(const LHS &L, const RHS &R) { | |
656 | return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>(L, R); | |
657 | } | |
658 | ||
85aaf69f SL |
659 | /// \brief Matches LShr or Shl. |
660 | template <typename LHS, typename RHS> | |
223e47cc LB |
661 | inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl> |
662 | m_LogicalShift(const LHS &L, const RHS &R) { | |
663 | return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>(L, R); | |
664 | } | |
665 | ||
85aaf69f SL |
666 | /// \brief Matches UDiv and SDiv. |
667 | template <typename LHS, typename RHS> | |
223e47cc LB |
668 | inline BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv> |
669 | m_IDiv(const LHS &L, const RHS &R) { | |
670 | return BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>(L, R); | |
671 | } | |
672 | ||
673 | //===----------------------------------------------------------------------===// | |
674 | // Class that matches exact binary ops. | |
675 | // | |
85aaf69f | 676 | template <typename SubPattern_t> struct Exact_match { |
223e47cc LB |
677 | SubPattern_t SubPattern; |
678 | ||
679 | Exact_match(const SubPattern_t &SP) : SubPattern(SP) {} | |
680 | ||
85aaf69f | 681 | template <typename OpTy> bool match(OpTy *V) { |
223e47cc LB |
682 | if (PossiblyExactOperator *PEO = dyn_cast<PossiblyExactOperator>(V)) |
683 | return PEO->isExact() && SubPattern.match(V); | |
684 | return false; | |
685 | } | |
686 | }; | |
687 | ||
85aaf69f SL |
688 | template <typename T> inline Exact_match<T> m_Exact(const T &SubPattern) { |
689 | return SubPattern; | |
690 | } | |
223e47cc LB |
691 | |
692 | //===----------------------------------------------------------------------===// | |
693 | // Matchers for CmpInst classes | |
694 | // | |
695 | ||
85aaf69f | 696 | template <typename LHS_t, typename RHS_t, typename Class, typename PredicateTy> |
223e47cc LB |
697 | struct CmpClass_match { |
698 | PredicateTy &Predicate; | |
699 | LHS_t L; | |
700 | RHS_t R; | |
701 | ||
702 | CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, const RHS_t &RHS) | |
85aaf69f | 703 | : Predicate(Pred), L(LHS), R(RHS) {} |
223e47cc | 704 | |
85aaf69f | 705 | template <typename OpTy> bool match(OpTy *V) { |
223e47cc LB |
706 | if (Class *I = dyn_cast<Class>(V)) |
707 | if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) { | |
708 | Predicate = I->getPredicate(); | |
709 | return true; | |
710 | } | |
711 | return false; | |
712 | } | |
713 | }; | |
714 | ||
85aaf69f SL |
715 | template <typename LHS, typename RHS> |
716 | inline CmpClass_match<LHS, RHS, CmpInst, CmpInst::Predicate> | |
717 | m_Cmp(CmpInst::Predicate &Pred, const LHS &L, const RHS &R) { | |
718 | return CmpClass_match<LHS, RHS, CmpInst, CmpInst::Predicate>(Pred, L, R); | |
719 | } | |
720 | ||
721 | template <typename LHS, typename RHS> | |
223e47cc LB |
722 | inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate> |
723 | m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) { | |
85aaf69f | 724 | return CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>(Pred, L, R); |
223e47cc LB |
725 | } |
726 | ||
85aaf69f | 727 | template <typename LHS, typename RHS> |
223e47cc LB |
728 | inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate> |
729 | m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) { | |
85aaf69f | 730 | return CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>(Pred, L, R); |
223e47cc LB |
731 | } |
732 | ||
733 | //===----------------------------------------------------------------------===// | |
734 | // Matchers for SelectInst classes | |
735 | // | |
736 | ||
85aaf69f | 737 | template <typename Cond_t, typename LHS_t, typename RHS_t> |
223e47cc LB |
738 | struct SelectClass_match { |
739 | Cond_t C; | |
740 | LHS_t L; | |
741 | RHS_t R; | |
742 | ||
85aaf69f SL |
743 | SelectClass_match(const Cond_t &Cond, const LHS_t &LHS, const RHS_t &RHS) |
744 | : C(Cond), L(LHS), R(RHS) {} | |
223e47cc | 745 | |
85aaf69f SL |
746 | template <typename OpTy> bool match(OpTy *V) { |
747 | if (auto *I = dyn_cast<SelectInst>(V)) | |
748 | return C.match(I->getOperand(0)) && L.match(I->getOperand(1)) && | |
223e47cc LB |
749 | R.match(I->getOperand(2)); |
750 | return false; | |
751 | } | |
752 | }; | |
753 | ||
85aaf69f SL |
754 | template <typename Cond, typename LHS, typename RHS> |
755 | inline SelectClass_match<Cond, LHS, RHS> m_Select(const Cond &C, const LHS &L, | |
756 | const RHS &R) { | |
223e47cc LB |
757 | return SelectClass_match<Cond, LHS, RHS>(C, L, R); |
758 | } | |
759 | ||
85aaf69f SL |
760 | /// \brief This matches a select of two constants, e.g.: |
761 | /// m_SelectCst<-1, 0>(m_Value(V)) | |
762 | template <int64_t L, int64_t R, typename Cond> | |
763 | inline SelectClass_match<Cond, constantint_match<L>, constantint_match<R>> | |
223e47cc LB |
764 | m_SelectCst(const Cond &C) { |
765 | return m_Select(C, m_ConstantInt<L>(), m_ConstantInt<R>()); | |
766 | } | |
767 | ||
223e47cc LB |
768 | //===----------------------------------------------------------------------===// |
769 | // Matchers for CastInst classes | |
770 | // | |
771 | ||
85aaf69f | 772 | template <typename Op_t, unsigned Opcode> struct CastClass_match { |
223e47cc LB |
773 | Op_t Op; |
774 | ||
775 | CastClass_match(const Op_t &OpMatch) : Op(OpMatch) {} | |
776 | ||
85aaf69f SL |
777 | template <typename OpTy> bool match(OpTy *V) { |
778 | if (auto *O = dyn_cast<Operator>(V)) | |
223e47cc LB |
779 | return O->getOpcode() == Opcode && Op.match(O->getOperand(0)); |
780 | return false; | |
781 | } | |
782 | }; | |
783 | ||
85aaf69f SL |
784 | /// \brief Matches BitCast. |
785 | template <typename OpTy> | |
786 | inline CastClass_match<OpTy, Instruction::BitCast> m_BitCast(const OpTy &Op) { | |
223e47cc LB |
787 | return CastClass_match<OpTy, Instruction::BitCast>(Op); |
788 | } | |
970d7e83 | 789 | |
85aaf69f SL |
790 | /// \brief Matches PtrToInt. |
791 | template <typename OpTy> | |
792 | inline CastClass_match<OpTy, Instruction::PtrToInt> m_PtrToInt(const OpTy &Op) { | |
223e47cc LB |
793 | return CastClass_match<OpTy, Instruction::PtrToInt>(Op); |
794 | } | |
795 | ||
85aaf69f SL |
796 | /// \brief Matches Trunc. |
797 | template <typename OpTy> | |
798 | inline CastClass_match<OpTy, Instruction::Trunc> m_Trunc(const OpTy &Op) { | |
223e47cc LB |
799 | return CastClass_match<OpTy, Instruction::Trunc>(Op); |
800 | } | |
801 | ||
85aaf69f SL |
802 | /// \brief Matches SExt. |
803 | template <typename OpTy> | |
804 | inline CastClass_match<OpTy, Instruction::SExt> m_SExt(const OpTy &Op) { | |
223e47cc LB |
805 | return CastClass_match<OpTy, Instruction::SExt>(Op); |
806 | } | |
807 | ||
85aaf69f SL |
808 | /// \brief Matches ZExt. |
809 | template <typename OpTy> | |
810 | inline CastClass_match<OpTy, Instruction::ZExt> m_ZExt(const OpTy &Op) { | |
223e47cc LB |
811 | return CastClass_match<OpTy, Instruction::ZExt>(Op); |
812 | } | |
970d7e83 | 813 | |
85aaf69f SL |
814 | /// \brief Matches UIToFP. |
815 | template <typename OpTy> | |
816 | inline CastClass_match<OpTy, Instruction::UIToFP> m_UIToFP(const OpTy &Op) { | |
1a4d82fc JJ |
817 | return CastClass_match<OpTy, Instruction::UIToFP>(Op); |
818 | } | |
819 | ||
85aaf69f SL |
820 | /// \brief Matches SIToFP. |
821 | template <typename OpTy> | |
822 | inline CastClass_match<OpTy, Instruction::SIToFP> m_SIToFP(const OpTy &Op) { | |
1a4d82fc JJ |
823 | return CastClass_match<OpTy, Instruction::SIToFP>(Op); |
824 | } | |
223e47cc LB |
825 | |
826 | //===----------------------------------------------------------------------===// | |
827 | // Matchers for unary operators | |
828 | // | |
829 | ||
85aaf69f | 830 | template <typename LHS_t> struct not_match { |
223e47cc LB |
831 | LHS_t L; |
832 | ||
833 | not_match(const LHS_t &LHS) : L(LHS) {} | |
834 | ||
85aaf69f SL |
835 | template <typename OpTy> bool match(OpTy *V) { |
836 | if (auto *O = dyn_cast<Operator>(V)) | |
223e47cc LB |
837 | if (O->getOpcode() == Instruction::Xor) |
838 | return matchIfNot(O->getOperand(0), O->getOperand(1)); | |
839 | return false; | |
840 | } | |
85aaf69f | 841 | |
223e47cc LB |
842 | private: |
843 | bool matchIfNot(Value *LHS, Value *RHS) { | |
844 | return (isa<ConstantInt>(RHS) || isa<ConstantDataVector>(RHS) || | |
845 | // FIXME: Remove CV. | |
846 | isa<ConstantVector>(RHS)) && | |
85aaf69f | 847 | cast<Constant>(RHS)->isAllOnesValue() && L.match(LHS); |
223e47cc LB |
848 | } |
849 | }; | |
850 | ||
85aaf69f | 851 | template <typename LHS> inline not_match<LHS> m_Not(const LHS &L) { return L; } |
223e47cc | 852 | |
85aaf69f | 853 | template <typename LHS_t> struct neg_match { |
223e47cc LB |
854 | LHS_t L; |
855 | ||
856 | neg_match(const LHS_t &LHS) : L(LHS) {} | |
857 | ||
85aaf69f SL |
858 | template <typename OpTy> bool match(OpTy *V) { |
859 | if (auto *O = dyn_cast<Operator>(V)) | |
223e47cc LB |
860 | if (O->getOpcode() == Instruction::Sub) |
861 | return matchIfNeg(O->getOperand(0), O->getOperand(1)); | |
862 | return false; | |
863 | } | |
85aaf69f | 864 | |
223e47cc LB |
865 | private: |
866 | bool matchIfNeg(Value *LHS, Value *RHS) { | |
867 | return ((isa<ConstantInt>(LHS) && cast<ConstantInt>(LHS)->isZero()) || | |
868 | isa<ConstantAggregateZero>(LHS)) && | |
869 | L.match(RHS); | |
870 | } | |
871 | }; | |
872 | ||
85aaf69f SL |
873 | /// \brief Match an integer negate. |
874 | template <typename LHS> inline neg_match<LHS> m_Neg(const LHS &L) { return L; } | |
223e47cc | 875 | |
85aaf69f | 876 | template <typename LHS_t> struct fneg_match { |
223e47cc LB |
877 | LHS_t L; |
878 | ||
879 | fneg_match(const LHS_t &LHS) : L(LHS) {} | |
880 | ||
85aaf69f SL |
881 | template <typename OpTy> bool match(OpTy *V) { |
882 | if (auto *O = dyn_cast<Operator>(V)) | |
223e47cc LB |
883 | if (O->getOpcode() == Instruction::FSub) |
884 | return matchIfFNeg(O->getOperand(0), O->getOperand(1)); | |
885 | return false; | |
886 | } | |
85aaf69f | 887 | |
223e47cc LB |
888 | private: |
889 | bool matchIfFNeg(Value *LHS, Value *RHS) { | |
85aaf69f | 890 | if (const auto *C = dyn_cast<ConstantFP>(LHS)) |
223e47cc LB |
891 | return C->isNegativeZeroValue() && L.match(RHS); |
892 | return false; | |
893 | } | |
894 | }; | |
895 | ||
85aaf69f SL |
896 | /// \brief Match a floating point negate. |
897 | template <typename LHS> inline fneg_match<LHS> m_FNeg(const LHS &L) { | |
898 | return L; | |
899 | } | |
223e47cc LB |
900 | |
901 | //===----------------------------------------------------------------------===// | |
902 | // Matchers for control flow. | |
903 | // | |
904 | ||
970d7e83 LB |
905 | struct br_match { |
906 | BasicBlock *&Succ; | |
85aaf69f | 907 | br_match(BasicBlock *&Succ) : Succ(Succ) {} |
970d7e83 | 908 | |
85aaf69f SL |
909 | template <typename OpTy> bool match(OpTy *V) { |
910 | if (auto *BI = dyn_cast<BranchInst>(V)) | |
970d7e83 LB |
911 | if (BI->isUnconditional()) { |
912 | Succ = BI->getSuccessor(0); | |
913 | return true; | |
914 | } | |
915 | return false; | |
916 | } | |
917 | }; | |
918 | ||
919 | inline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ); } | |
920 | ||
85aaf69f | 921 | template <typename Cond_t> struct brc_match { |
223e47cc LB |
922 | Cond_t Cond; |
923 | BasicBlock *&T, *&F; | |
924 | brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f) | |
85aaf69f | 925 | : Cond(C), T(t), F(f) {} |
223e47cc | 926 | |
85aaf69f SL |
927 | template <typename OpTy> bool match(OpTy *V) { |
928 | if (auto *BI = dyn_cast<BranchInst>(V)) | |
223e47cc LB |
929 | if (BI->isConditional() && Cond.match(BI->getCondition())) { |
930 | T = BI->getSuccessor(0); | |
931 | F = BI->getSuccessor(1); | |
932 | return true; | |
933 | } | |
934 | return false; | |
935 | } | |
936 | }; | |
937 | ||
85aaf69f | 938 | template <typename Cond_t> |
223e47cc LB |
939 | inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) { |
940 | return brc_match<Cond_t>(C, T, F); | |
941 | } | |
942 | ||
223e47cc LB |
943 | //===----------------------------------------------------------------------===// |
944 | // Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y). | |
945 | // | |
946 | ||
85aaf69f | 947 | template <typename CmpInst_t, typename LHS_t, typename RHS_t, typename Pred_t> |
223e47cc LB |
948 | struct MaxMin_match { |
949 | LHS_t L; | |
950 | RHS_t R; | |
951 | ||
85aaf69f | 952 | MaxMin_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} |
223e47cc | 953 | |
85aaf69f | 954 | template <typename OpTy> bool match(OpTy *V) { |
223e47cc | 955 | // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x". |
85aaf69f | 956 | auto *SI = dyn_cast<SelectInst>(V); |
223e47cc LB |
957 | if (!SI) |
958 | return false; | |
85aaf69f | 959 | auto *Cmp = dyn_cast<CmpInst_t>(SI->getCondition()); |
223e47cc LB |
960 | if (!Cmp) |
961 | return false; | |
962 | // At this point we have a select conditioned on a comparison. Check that | |
963 | // it is the values returned by the select that are being compared. | |
964 | Value *TrueVal = SI->getTrueValue(); | |
965 | Value *FalseVal = SI->getFalseValue(); | |
966 | Value *LHS = Cmp->getOperand(0); | |
967 | Value *RHS = Cmp->getOperand(1); | |
968 | if ((TrueVal != LHS || FalseVal != RHS) && | |
969 | (TrueVal != RHS || FalseVal != LHS)) | |
970 | return false; | |
85aaf69f SL |
971 | typename CmpInst_t::Predicate Pred = |
972 | LHS == TrueVal ? Cmp->getPredicate() : Cmp->getSwappedPredicate(); | |
223e47cc LB |
973 | // Does "(x pred y) ? x : y" represent the desired max/min operation? |
974 | if (!Pred_t::match(Pred)) | |
975 | return false; | |
976 | // It does! Bind the operands. | |
977 | return L.match(LHS) && R.match(RHS); | |
978 | } | |
979 | }; | |
980 | ||
85aaf69f | 981 | /// \brief Helper class for identifying signed max predicates. |
223e47cc LB |
982 | struct smax_pred_ty { |
983 | static bool match(ICmpInst::Predicate Pred) { | |
984 | return Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE; | |
985 | } | |
986 | }; | |
987 | ||
85aaf69f | 988 | /// \brief Helper class for identifying signed min predicates. |
223e47cc LB |
989 | struct smin_pred_ty { |
990 | static bool match(ICmpInst::Predicate Pred) { | |
991 | return Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SLE; | |
992 | } | |
993 | }; | |
994 | ||
85aaf69f | 995 | /// \brief Helper class for identifying unsigned max predicates. |
223e47cc LB |
996 | struct umax_pred_ty { |
997 | static bool match(ICmpInst::Predicate Pred) { | |
998 | return Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE; | |
999 | } | |
1000 | }; | |
1001 | ||
85aaf69f | 1002 | /// \brief Helper class for identifying unsigned min predicates. |
223e47cc LB |
1003 | struct umin_pred_ty { |
1004 | static bool match(ICmpInst::Predicate Pred) { | |
1005 | return Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE; | |
1006 | } | |
1007 | }; | |
1008 | ||
85aaf69f | 1009 | /// \brief Helper class for identifying ordered max predicates. |
1a4d82fc JJ |
1010 | struct ofmax_pred_ty { |
1011 | static bool match(FCmpInst::Predicate Pred) { | |
1012 | return Pred == CmpInst::FCMP_OGT || Pred == CmpInst::FCMP_OGE; | |
1013 | } | |
1014 | }; | |
1015 | ||
85aaf69f | 1016 | /// \brief Helper class for identifying ordered min predicates. |
1a4d82fc JJ |
1017 | struct ofmin_pred_ty { |
1018 | static bool match(FCmpInst::Predicate Pred) { | |
1019 | return Pred == CmpInst::FCMP_OLT || Pred == CmpInst::FCMP_OLE; | |
1020 | } | |
1021 | }; | |
1022 | ||
85aaf69f | 1023 | /// \brief Helper class for identifying unordered max predicates. |
1a4d82fc JJ |
1024 | struct ufmax_pred_ty { |
1025 | static bool match(FCmpInst::Predicate Pred) { | |
1026 | return Pred == CmpInst::FCMP_UGT || Pred == CmpInst::FCMP_UGE; | |
1027 | } | |
1028 | }; | |
1029 | ||
85aaf69f | 1030 | /// \brief Helper class for identifying unordered min predicates. |
1a4d82fc JJ |
1031 | struct ufmin_pred_ty { |
1032 | static bool match(FCmpInst::Predicate Pred) { | |
1033 | return Pred == CmpInst::FCMP_ULT || Pred == CmpInst::FCMP_ULE; | |
1034 | } | |
1035 | }; | |
1036 | ||
85aaf69f SL |
1037 | template <typename LHS, typename RHS> |
1038 | inline MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty> m_SMax(const LHS &L, | |
1039 | const RHS &R) { | |
1a4d82fc | 1040 | return MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>(L, R); |
223e47cc LB |
1041 | } |
1042 | ||
85aaf69f SL |
1043 | template <typename LHS, typename RHS> |
1044 | inline MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty> m_SMin(const LHS &L, | |
1045 | const RHS &R) { | |
1a4d82fc | 1046 | return MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>(L, R); |
223e47cc LB |
1047 | } |
1048 | ||
85aaf69f SL |
1049 | template <typename LHS, typename RHS> |
1050 | inline MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty> m_UMax(const LHS &L, | |
1051 | const RHS &R) { | |
1a4d82fc | 1052 | return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>(L, R); |
223e47cc LB |
1053 | } |
1054 | ||
85aaf69f SL |
1055 | template <typename LHS, typename RHS> |
1056 | inline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty> m_UMin(const LHS &L, | |
1057 | const RHS &R) { | |
1a4d82fc JJ |
1058 | return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>(L, R); |
1059 | } | |
1060 | ||
1061 | /// \brief Match an 'ordered' floating point maximum function. | |
1062 | /// Floating point has one special value 'NaN'. Therefore, there is no total | |
1063 | /// order. However, if we can ignore the 'NaN' value (for example, because of a | |
1064 | /// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum' | |
1065 | /// semantics. In the presence of 'NaN' we have to preserve the original | |
1066 | /// select(fcmp(ogt/ge, L, R), L, R) semantics matched by this predicate. | |
1067 | /// | |
1068 | /// max(L, R) iff L and R are not NaN | |
1069 | /// m_OrdFMax(L, R) = R iff L or R are NaN | |
85aaf69f SL |
1070 | template <typename LHS, typename RHS> |
1071 | inline MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty> m_OrdFMax(const LHS &L, | |
1072 | const RHS &R) { | |
1a4d82fc JJ |
1073 | return MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty>(L, R); |
1074 | } | |
1075 | ||
1076 | /// \brief Match an 'ordered' floating point minimum function. | |
1077 | /// Floating point has one special value 'NaN'. Therefore, there is no total | |
1078 | /// order. However, if we can ignore the 'NaN' value (for example, because of a | |
1079 | /// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum' | |
1080 | /// semantics. In the presence of 'NaN' we have to preserve the original | |
1081 | /// select(fcmp(olt/le, L, R), L, R) semantics matched by this predicate. | |
1082 | /// | |
1083 | /// max(L, R) iff L and R are not NaN | |
1084 | /// m_OrdFMin(L, R) = R iff L or R are NaN | |
85aaf69f SL |
1085 | template <typename LHS, typename RHS> |
1086 | inline MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty> m_OrdFMin(const LHS &L, | |
1087 | const RHS &R) { | |
1a4d82fc JJ |
1088 | return MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty>(L, R); |
1089 | } | |
1090 | ||
1091 | /// \brief Match an 'unordered' floating point maximum function. | |
1092 | /// Floating point has one special value 'NaN'. Therefore, there is no total | |
1093 | /// order. However, if we can ignore the 'NaN' value (for example, because of a | |
1094 | /// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum' | |
1095 | /// semantics. In the presence of 'NaN' we have to preserve the original | |
1096 | /// select(fcmp(ugt/ge, L, R), L, R) semantics matched by this predicate. | |
1097 | /// | |
1098 | /// max(L, R) iff L and R are not NaN | |
1099 | /// m_UnordFMin(L, R) = L iff L or R are NaN | |
85aaf69f | 1100 | template <typename LHS, typename RHS> |
1a4d82fc JJ |
1101 | inline MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty> |
1102 | m_UnordFMax(const LHS &L, const RHS &R) { | |
1103 | return MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R); | |
1104 | } | |
1105 | ||
1106 | /// \brief Match an 'unordered' floating point minimum function. | |
1107 | /// Floating point has one special value 'NaN'. Therefore, there is no total | |
1108 | /// order. However, if we can ignore the 'NaN' value (for example, because of a | |
1109 | /// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum' | |
1110 | /// semantics. In the presence of 'NaN' we have to preserve the original | |
1111 | /// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate. | |
1112 | /// | |
1113 | /// max(L, R) iff L and R are not NaN | |
1114 | /// m_UnordFMin(L, R) = L iff L or R are NaN | |
85aaf69f | 1115 | template <typename LHS, typename RHS> |
1a4d82fc JJ |
1116 | inline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty> |
1117 | m_UnordFMin(const LHS &L, const RHS &R) { | |
1118 | return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R); | |
223e47cc LB |
1119 | } |
1120 | ||
85aaf69f | 1121 | template <typename Opnd_t> struct Argument_match { |
970d7e83 LB |
1122 | unsigned OpI; |
1123 | Opnd_t Val; | |
85aaf69f | 1124 | Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) {} |
970d7e83 | 1125 | |
85aaf69f | 1126 | template <typename OpTy> bool match(OpTy *V) { |
970d7e83 LB |
1127 | CallSite CS(V); |
1128 | return CS.isCall() && Val.match(CS.getArgument(OpI)); | |
1129 | } | |
1130 | }; | |
1131 | ||
85aaf69f SL |
1132 | /// \brief Match an argument. |
1133 | template <unsigned OpI, typename Opnd_t> | |
970d7e83 LB |
1134 | inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) { |
1135 | return Argument_match<Opnd_t>(OpI, Op); | |
1136 | } | |
1137 | ||
85aaf69f | 1138 | /// \brief Intrinsic matchers. |
970d7e83 LB |
1139 | struct IntrinsicID_match { |
1140 | unsigned ID; | |
85aaf69f | 1141 | IntrinsicID_match(Intrinsic::ID IntrID) : ID(IntrID) {} |
970d7e83 | 1142 | |
85aaf69f SL |
1143 | template <typename OpTy> bool match(OpTy *V) { |
1144 | if (const auto *CI = dyn_cast<CallInst>(V)) | |
1145 | if (const auto *F = CI->getCalledFunction()) | |
1146 | return F->getIntrinsicID() == ID; | |
1147 | return false; | |
970d7e83 LB |
1148 | } |
1149 | }; | |
1150 | ||
1151 | /// Intrinsic matches are combinations of ID matchers, and argument | |
1152 | /// matchers. Higher arity matcher are defined recursively in terms of and-ing | |
1153 | /// them with lower arity matchers. Here's some convenient typedefs for up to | |
1154 | /// several arguments, and more can be added as needed | |
1155 | template <typename T0 = void, typename T1 = void, typename T2 = void, | |
1156 | typename T3 = void, typename T4 = void, typename T5 = void, | |
1157 | typename T6 = void, typename T7 = void, typename T8 = void, | |
85aaf69f SL |
1158 | typename T9 = void, typename T10 = void> |
1159 | struct m_Intrinsic_Ty; | |
1160 | template <typename T0> struct m_Intrinsic_Ty<T0> { | |
1161 | typedef match_combine_and<IntrinsicID_match, Argument_match<T0>> Ty; | |
970d7e83 | 1162 | }; |
85aaf69f SL |
1163 | template <typename T0, typename T1> struct m_Intrinsic_Ty<T0, T1> { |
1164 | typedef match_combine_and<typename m_Intrinsic_Ty<T0>::Ty, Argument_match<T1>> | |
1165 | Ty; | |
970d7e83 LB |
1166 | }; |
1167 | template <typename T0, typename T1, typename T2> | |
1168 | struct m_Intrinsic_Ty<T0, T1, T2> { | |
1169 | typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty, | |
85aaf69f | 1170 | Argument_match<T2>> Ty; |
970d7e83 LB |
1171 | }; |
1172 | template <typename T0, typename T1, typename T2, typename T3> | |
1173 | struct m_Intrinsic_Ty<T0, T1, T2, T3> { | |
1174 | typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty, | |
85aaf69f | 1175 | Argument_match<T3>> Ty; |
970d7e83 LB |
1176 | }; |
1177 | ||
85aaf69f SL |
1178 | /// \brief Match intrinsic calls like this: |
1179 | /// m_Intrinsic<Intrinsic::fabs>(m_Value(X)) | |
1180 | template <Intrinsic::ID IntrID> inline IntrinsicID_match m_Intrinsic() { | |
1181 | return IntrinsicID_match(IntrID); | |
1182 | } | |
970d7e83 | 1183 | |
85aaf69f SL |
1184 | template <Intrinsic::ID IntrID, typename T0> |
1185 | inline typename m_Intrinsic_Ty<T0>::Ty m_Intrinsic(const T0 &Op0) { | |
970d7e83 LB |
1186 | return m_CombineAnd(m_Intrinsic<IntrID>(), m_Argument<0>(Op0)); |
1187 | } | |
1188 | ||
85aaf69f SL |
1189 | template <Intrinsic::ID IntrID, typename T0, typename T1> |
1190 | inline typename m_Intrinsic_Ty<T0, T1>::Ty m_Intrinsic(const T0 &Op0, | |
1191 | const T1 &Op1) { | |
970d7e83 LB |
1192 | return m_CombineAnd(m_Intrinsic<IntrID>(Op0), m_Argument<1>(Op1)); |
1193 | } | |
1194 | ||
85aaf69f | 1195 | template <Intrinsic::ID IntrID, typename T0, typename T1, typename T2> |
970d7e83 LB |
1196 | inline typename m_Intrinsic_Ty<T0, T1, T2>::Ty |
1197 | m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2) { | |
1198 | return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1), m_Argument<2>(Op2)); | |
1199 | } | |
1200 | ||
85aaf69f SL |
1201 | template <Intrinsic::ID IntrID, typename T0, typename T1, typename T2, |
1202 | typename T3> | |
970d7e83 LB |
1203 | inline typename m_Intrinsic_Ty<T0, T1, T2, T3>::Ty |
1204 | m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) { | |
1205 | return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2), m_Argument<3>(Op3)); | |
1206 | } | |
1207 | ||
85aaf69f SL |
1208 | // Helper intrinsic matching specializations. |
1209 | template <typename Opnd0> | |
1210 | inline typename m_Intrinsic_Ty<Opnd0>::Ty m_BSwap(const Opnd0 &Op0) { | |
970d7e83 LB |
1211 | return m_Intrinsic<Intrinsic::bswap>(Op0); |
1212 | } | |
1213 | ||
85aaf69f SL |
1214 | template <typename Opnd0, typename Opnd1> |
1215 | inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMin(const Opnd0 &Op0, | |
1216 | const Opnd1 &Op1) { | |
1217 | return m_Intrinsic<Intrinsic::minnum>(Op0, Op1); | |
1218 | } | |
1219 | ||
1220 | template <typename Opnd0, typename Opnd1> | |
1221 | inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMax(const Opnd0 &Op0, | |
1222 | const Opnd1 &Op1) { | |
1223 | return m_Intrinsic<Intrinsic::maxnum>(Op0, Op1); | |
1224 | } | |
1225 | ||
223e47cc LB |
1226 | } // end namespace PatternMatch |
1227 | } // end namespace llvm | |
1228 | ||
1229 | #endif |