1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===- PatternMatch.h - Match on the LLVM IR --------------------*- C++ -*-===//
2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//                     The LLVM Compiler Infrastructure
4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source
6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details.
7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file provides a simple and efficient mechanism for performing general
11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// tree-based pattern matches on the LLVM IR.  The power of these routines is
12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// that it allows you to write concise patterns that are expressive and easy to
13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// understand.  The other major advantage of this is that it allows you to
14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// trivially capture/bind elements in the pattern to variables.  For example,
15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// you can do something like this:
16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//  Value *Exp = ...
18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//  Value *X, *Y;  ConstantInt *C1, *C2;      // (X & C1) | (Y & C2)
19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//  if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)),
20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//                      m_And(m_Value(Y), m_ConstantInt(C2))))) {
21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//    ... Pattern is matched and variables are bound ...
22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//  }
23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This is primarily useful to things like the instruction combiner, but can
25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// also be useful for static analysis tools or code generators.
26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_IR_PATTERNMATCH_H
30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_IR_PATTERNMATCH_H
31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/APFloat.h"
33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/APInt.h"
34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/CallSite.h"
35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/Constant.h"
36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/Constants.h"
37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/InstrTypes.h"
38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/Instruction.h"
39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/Instructions.h"
40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/Intrinsics.h"
41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/Operator.h"
42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/Value.h"
43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Support/Casting.h"
44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <cstdint>
45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace llvm {
47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace PatternMatch {
48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Val, typename Pattern> bool match(Val *V, const Pattern &P) {
50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return const_cast<Pattern &>(P).match(V);
51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename SubPattern_t> struct OneUse_match {
54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SubPattern_t SubPattern;
55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  OneUse_match(const SubPattern_t &SP) : SubPattern(SP) {}
57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return V->hasOneUse() && SubPattern.match(V);
60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename T> inline OneUse_match<T> m_OneUse(const T &SubPattern) {
64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return SubPattern;
65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Class> struct class_match {
68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) { return isa<Class>(V); }
69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an arbitrary value and ignore it.
72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline class_match<Value> m_Value() { return class_match<Value>(); }
73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an arbitrary binary operation and ignore it.
75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline class_match<BinaryOperator> m_BinOp() {
76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return class_match<BinaryOperator>();
77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches any compare instruction and ignore it.
80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline class_match<CmpInst> m_Cmp() { return class_match<CmpInst>(); }
81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an arbitrary ConstantInt and ignore it.
83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline class_match<ConstantInt> m_ConstantInt() {
84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return class_match<ConstantInt>();
85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an arbitrary undef constant.
88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); }
89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an arbitrary Constant and ignore it.
91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline class_match<Constant> m_Constant() { return class_match<Constant>(); }
92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Matching combinators
94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LTy, typename RTy> struct match_combine_or {
95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LTy L;
96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RTy R;
97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  match_combine_or(const LTy &Left, const RTy &Right) : L(Left), R(Right) {}
99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (L.match(V))
102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return true;
103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (R.match(V))
104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return true;
105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LTy, typename RTy> struct match_combine_and {
110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LTy L;
111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RTy R;
112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  match_combine_and(const LTy &Left, const RTy &Right) : L(Left), R(Right) {}
114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (L.match(V))
117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (R.match(V))
118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return true;
119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Combine two pattern matchers matching L || R
124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LTy, typename RTy>
125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline match_combine_or<LTy, RTy> m_CombineOr(const LTy &L, const RTy &R) {
126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return match_combine_or<LTy, RTy>(L, R);
127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Combine two pattern matchers matching L && R
130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LTy, typename RTy>
131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline match_combine_and<LTy, RTy> m_CombineAnd(const LTy &L, const RTy &R) {
132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return match_combine_and<LTy, RTy>(L, R);
133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct match_zero {
136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *C = dyn_cast<Constant>(V))
138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return C->isNullValue();
139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an arbitrary zero/null constant.  This includes
144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// zero_initializer for vectors and ConstantPointerNull for pointers.
145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline match_zero m_Zero() { return match_zero(); }
146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct match_neg_zero {
148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *C = dyn_cast<Constant>(V))
150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return C->isNegativeZeroValue();
151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an arbitrary zero/null constant.  This includes
156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// zero_initializer for vectors and ConstantPointerNull for pointers. For
157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// floating point constants, this will match negative zero but not positive
158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// zero
159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline match_neg_zero m_NegZero() { return match_neg_zero(); }
160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct match_any_zero {
162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *C = dyn_cast<Constant>(V))
164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return C->isZeroValue();
165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
166f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief - Match an arbitrary zero/null constant.  This includes
170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// zero_initializer for vectors and ConstantPointerNull for pointers. For
171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// floating point constants, this will match negative zero and positive zero
172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline match_any_zero m_AnyZero() { return match_any_zero(); }
173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct match_nan {
175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *C = dyn_cast<ConstantFP>(V))
177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return C->isNaN();
178f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Match an arbitrary NaN constant. This includes quiet and signalling nans.
183f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline match_nan m_NaN() { return match_nan(); }
184f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
185f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct match_one {
186f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
187f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *C = dyn_cast<Constant>(V))
188f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return C->isOneValue();
189f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
190f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
191f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
192f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
193f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an integer 1 or a vector with all elements equal to 1.
194f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline match_one m_One() { return match_one(); }
195f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
196f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct match_all_ones {
197f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
198f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *C = dyn_cast<Constant>(V))
199f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return C->isAllOnesValue();
200f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
201f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
202f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
203f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
204f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an integer or vector with all bits set to true.
205f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline match_all_ones m_AllOnes() { return match_all_ones(); }
206f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
207f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct match_sign_mask {
208f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
209f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *C = dyn_cast<Constant>(V))
210f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return C->isMinSignedValue();
211f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
212f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
213f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
214f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
215f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an integer or vector with only the sign bit(s) set.
216f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline match_sign_mask m_SignMask() { return match_sign_mask(); }
217f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
218f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct apint_match {
219f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const APInt *&Res;
220f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
221f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  apint_match(const APInt *&R) : Res(R) {}
222f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
223f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
224f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *CI = dyn_cast<ConstantInt>(V)) {
225f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Res = &CI->getValue();
226f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return true;
227f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
228f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (V->getType()->isVectorTy())
229f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (const auto *C = dyn_cast<Constant>(V))
230f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        if (auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue())) {
231f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          Res = &CI->getValue();
232f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          return true;
233f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        }
234f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
235f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
236f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
237f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Either constexpr if or renaming ConstantFP::getValueAPF to
238f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// ConstantFP::getValue is needed to do it via single template
239f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// function for both apint/apfloat.
240f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct apfloat_match {
241f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const APFloat *&Res;
242f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  apfloat_match(const APFloat *&R) : Res(R) {}
243f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
244f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *CI = dyn_cast<ConstantFP>(V)) {
245f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Res = &CI->getValueAPF();
246f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return true;
247f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
248f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (V->getType()->isVectorTy())
249f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (const auto *C = dyn_cast<Constant>(V))
250f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        if (auto *CI = dyn_cast_or_null<ConstantFP>(C->getSplatValue())) {
251f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          Res = &CI->getValueAPF();
252f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          return true;
253f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        }
254f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
255f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
256f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
257f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
258f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a ConstantInt or splatted ConstantVector, binding the
259f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// specified pointer to the contained APInt.
260f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline apint_match m_APInt(const APInt *&Res) { return Res; }
261f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
262f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a ConstantFP or splatted ConstantVector, binding the
263f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// specified pointer to the contained APFloat.
264f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline apfloat_match m_APFloat(const APFloat *&Res) { return Res; }
265f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
266f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <int64_t Val> struct constantint_match {
267f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
268f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *CI = dyn_cast<ConstantInt>(V)) {
269f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      const APInt &CIV = CI->getValue();
270f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (Val >= 0)
271f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return CIV == static_cast<uint64_t>(Val);
272f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      // If Val is negative, and CI is shorter than it, truncate to the right
273f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      // number of bits.  If it is larger, then we have to sign extend.  Just
274f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      // compare their negated values.
275f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return -CIV == -Val;
276f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
277f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
278f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
279f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
280f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
281f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a ConstantInt with a specific value.
282f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <int64_t Val> inline constantint_match<Val> m_ConstantInt() {
283f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return constantint_match<Val>();
284f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
285f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
286f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief This helper class is used to match scalar and vector constants that
287f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// satisfy a specified predicate.
288f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Predicate> struct cst_pred_ty : public Predicate {
289f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
290f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *CI = dyn_cast<ConstantInt>(V))
291f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return this->isValue(CI->getValue());
292f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (V->getType()->isVectorTy())
293f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (const auto *C = dyn_cast<Constant>(V))
294f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        if (const auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
295f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          return this->isValue(CI->getValue());
296f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
297f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
298f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
299f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
300f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief This helper class is used to match scalar and vector constants that
301f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// satisfy a specified predicate, and bind them to an APInt.
302f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Predicate> struct api_pred_ty : public Predicate {
303f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const APInt *&Res;
304f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
305f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  api_pred_ty(const APInt *&R) : Res(R) {}
306f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
307f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
308f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *CI = dyn_cast<ConstantInt>(V))
309f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (this->isValue(CI->getValue())) {
310f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        Res = &CI->getValue();
311f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return true;
312f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      }
313f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (V->getType()->isVectorTy())
314f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (const auto *C = dyn_cast<Constant>(V))
315f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        if (auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
316f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          if (this->isValue(CI->getValue())) {
317f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot            Res = &CI->getValue();
318f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot            return true;
319f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          }
320f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
321f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
322f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
323f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
324f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
325f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct is_power2 {
326f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isValue(const APInt &C) { return C.isPowerOf2(); }
327f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
328f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
329f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an integer or vector power of 2.
330f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline cst_pred_ty<is_power2> m_Power2() { return cst_pred_ty<is_power2>(); }
331f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline api_pred_ty<is_power2> m_Power2(const APInt *&V) { return V; }
332f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
333f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct is_maxsignedvalue {
334f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isValue(const APInt &C) { return C.isMaxSignedValue(); }
335f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
336f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
337f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline cst_pred_ty<is_maxsignedvalue> m_MaxSignedValue() { return cst_pred_ty<is_maxsignedvalue>(); }
338f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline api_pred_ty<is_maxsignedvalue> m_MaxSignedValue(const APInt *&V) { return V; }
339f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
340f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Class> struct bind_ty {
341f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Class *&VR;
342f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
343f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bind_ty(Class *&V) : VR(V) {}
344f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
345f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
346f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *CV = dyn_cast<Class>(V)) {
347f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      VR = CV;
348f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return true;
349f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
350f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
351f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
352f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
353f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
354f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a value, capturing it if we match.
355f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline bind_ty<Value> m_Value(Value *&V) { return V; }
356f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline bind_ty<const Value> m_Value(const Value *&V) { return V; }
357f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
358f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an instruction, capturing it if we match.
359f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline bind_ty<Instruction> m_Instruction(Instruction *&I) { return I; }
360f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a binary operator, capturing it if we match.
361f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; }
362f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
363f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a ConstantInt, capturing the value if we match.
364f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
365f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
366f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a Constant, capturing the value if we match.
367f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline bind_ty<Constant> m_Constant(Constant *&C) { return C; }
368f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
369f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a ConstantFP, capturing the value if we match.
370f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; }
371f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
372f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a specified Value*.
373f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct specificval_ty {
374f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const Value *Val;
375f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
376f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  specificval_ty(const Value *V) : Val(V) {}
377f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
378f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) { return V == Val; }
379f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
380f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
381f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match if we have a specific specified value.
382f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline specificval_ty m_Specific(const Value *V) { return V; }
383f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
384f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a specified floating point value or vector of all elements of
385f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// that value.
386f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct specific_fpval {
387f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  double Val;
388f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
389f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  specific_fpval(double V) : Val(V) {}
390f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
391f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
392f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *CFP = dyn_cast<ConstantFP>(V))
393f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return CFP->isExactlyValue(Val);
394f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (V->getType()->isVectorTy())
395f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (const auto *C = dyn_cast<Constant>(V))
396f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        if (auto *CFP = dyn_cast_or_null<ConstantFP>(C->getSplatValue()))
397f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          return CFP->isExactlyValue(Val);
398f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
399f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
400f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
401f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
402f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a specific floating point value or vector with all elements
403f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// equal to the value.
404f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline specific_fpval m_SpecificFP(double V) { return specific_fpval(V); }
405f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
406f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a float 1.0 or vector with all elements equal to 1.0.
407f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline specific_fpval m_FPOne() { return m_SpecificFP(1.0); }
408f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
409f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct bind_const_intval_ty {
410f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  uint64_t &VR;
411f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
412f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bind_const_intval_ty(uint64_t &V) : VR(V) {}
413f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
414f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
415f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *CV = dyn_cast<ConstantInt>(V))
416f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (CV->getValue().ule(UINT64_MAX)) {
417f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        VR = CV->getZExtValue();
418f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return true;
419f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      }
420f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
421f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
422f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
423f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
424f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a specified integer value or vector of all elements of that
425f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// value.
426f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct specific_intval {
427f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  uint64_t Val;
428f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
429f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  specific_intval(uint64_t V) : Val(V) {}
430f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
431f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename ITy> bool match(ITy *V) {
432f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    const auto *CI = dyn_cast<ConstantInt>(V);
433f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (!CI && V->getType()->isVectorTy())
434f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (const auto *C = dyn_cast<Constant>(V))
435f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue());
436f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
437f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return CI && CI->getValue() == Val;
438f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
439f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
440f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
441f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a specific integer value or vector with all elements equal to
442f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// the value.
443f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline specific_intval m_SpecificInt(uint64_t V) { return specific_intval(V); }
444f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
445f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a ConstantInt and bind to its value.  This does not match
446f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// ConstantInts wider than 64-bits.
447f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; }
448f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
449f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
450f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Matcher for any binary operator.
451f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
452f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS_t, typename RHS_t, bool Commutable = false>
453f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct AnyBinaryOp_match {
454f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LHS_t L;
455f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RHS_t R;
456f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
457f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AnyBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
458f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
459f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
460f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *I = dyn_cast<BinaryOperator>(V))
461f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) ||
462f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             (Commutable && R.match(I->getOperand(0)) &&
463f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot              L.match(I->getOperand(1)));
464f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
465f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
466f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
467f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
468f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
469f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline AnyBinaryOp_match<LHS, RHS> m_BinOp(const LHS &L, const RHS &R) {
470f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return AnyBinaryOp_match<LHS, RHS>(L, R);
471f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
472f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
473f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
474f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Matchers for specific binary operators.
475f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
476f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
477f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS_t, typename RHS_t, unsigned Opcode,
478f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          bool Commutable = false>
479f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct BinaryOp_match {
480f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LHS_t L;
481f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RHS_t R;
482f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
483f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
484f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
485f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
486f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (V->getValueID() == Value::InstructionVal + Opcode) {
487f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      auto *I = cast<BinaryOperator>(V);
488f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) ||
489f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             (Commutable && R.match(I->getOperand(0)) &&
490f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot              L.match(I->getOperand(1)));
491f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
492f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *CE = dyn_cast<ConstantExpr>(V))
493f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return CE->getOpcode() == Opcode &&
494f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             ((L.match(CE->getOperand(0)) && R.match(CE->getOperand(1))) ||
495f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot              (Commutable && R.match(CE->getOperand(0)) &&
496f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot               L.match(CE->getOperand(1))));
497f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
498f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
499f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
500f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
501f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
502f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::Add> m_Add(const LHS &L,
503f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                        const RHS &R) {
504f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
505f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
506f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
507f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
508f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::FAdd> m_FAdd(const LHS &L,
509f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
510f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::FAdd>(L, R);
511f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
512f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
513f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
514f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::Sub> m_Sub(const LHS &L,
515f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                        const RHS &R) {
516f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
517f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
518f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
519f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
520f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::FSub> m_FSub(const LHS &L,
521f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
522f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R);
523f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
524f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
525f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
526f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L,
527f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                        const RHS &R) {
528f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
529f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
530f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
531f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
532f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::FMul> m_FMul(const LHS &L,
533f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
534f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::FMul>(L, R);
535f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
536f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
537f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
538f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::UDiv> m_UDiv(const LHS &L,
539f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
540f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R);
541f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
542f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
543f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
544f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::SDiv> m_SDiv(const LHS &L,
545f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
546f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R);
547f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
548f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
549f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
550f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::FDiv> m_FDiv(const LHS &L,
551f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
552f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R);
553f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
554f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
555f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
556f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::URem> m_URem(const LHS &L,
557f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
558f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R);
559f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
560f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
561f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
562f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::SRem> m_SRem(const LHS &L,
563f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
564f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R);
565f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
566f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
567f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
568f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::FRem> m_FRem(const LHS &L,
569f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
570f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R);
571f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
572f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
573f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
574f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::And> m_And(const LHS &L,
575f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                        const RHS &R) {
576f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::And>(L, R);
577f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
578f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
579f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
580f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::Or> m_Or(const LHS &L,
581f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                      const RHS &R) {
582f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R);
583f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
584f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
585f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
586f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::Xor> m_Xor(const LHS &L,
587f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                        const RHS &R) {
588f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R);
589f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
590f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
591f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
592f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::Shl> m_Shl(const LHS &L,
593f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                        const RHS &R) {
594f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R);
595f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
596f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
597f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
598f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::LShr> m_LShr(const LHS &L,
599f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
600f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R);
601f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
602f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
603f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
604f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::AShr> m_AShr(const LHS &L,
605f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
606f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
607f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
608f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
609f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS_t, typename RHS_t, unsigned Opcode,
610f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          unsigned WrapFlags = 0>
611f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct OverflowingBinaryOp_match {
612f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LHS_t L;
613f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RHS_t R;
614f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
615f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  OverflowingBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS)
616f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      : L(LHS), R(RHS) {}
617f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
618f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
619f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *Op = dyn_cast<OverflowingBinaryOperator>(V)) {
620f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (Op->getOpcode() != Opcode)
621f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return false;
622f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (WrapFlags & OverflowingBinaryOperator::NoUnsignedWrap &&
623f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          !Op->hasNoUnsignedWrap())
624f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return false;
625f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (WrapFlags & OverflowingBinaryOperator::NoSignedWrap &&
626f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          !Op->hasNoSignedWrap())
627f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return false;
628f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return L.match(Op->getOperand(0)) && R.match(Op->getOperand(1));
629f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
630f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
631f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
632f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
633f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
634f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
635f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
636f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                 OverflowingBinaryOperator::NoSignedWrap>
637f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_NSWAdd(const LHS &L, const RHS &R) {
638f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
639f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                   OverflowingBinaryOperator::NoSignedWrap>(
640f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      L, R);
641f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
642f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
643f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
644f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                 OverflowingBinaryOperator::NoSignedWrap>
645f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_NSWSub(const LHS &L, const RHS &R) {
646f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
647f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                   OverflowingBinaryOperator::NoSignedWrap>(
648f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      L, R);
649f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
650f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
651f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
652f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                 OverflowingBinaryOperator::NoSignedWrap>
653f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_NSWMul(const LHS &L, const RHS &R) {
654f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
655f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                   OverflowingBinaryOperator::NoSignedWrap>(
656f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      L, R);
657f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
658f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
659f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
660f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                 OverflowingBinaryOperator::NoSignedWrap>
661f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_NSWShl(const LHS &L, const RHS &R) {
662f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
663f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                   OverflowingBinaryOperator::NoSignedWrap>(
664f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      L, R);
665f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
666f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
667f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
668f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
669f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                 OverflowingBinaryOperator::NoUnsignedWrap>
670f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_NUWAdd(const LHS &L, const RHS &R) {
671f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
672f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                   OverflowingBinaryOperator::NoUnsignedWrap>(
673f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      L, R);
674f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
675f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
676f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
677f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                 OverflowingBinaryOperator::NoUnsignedWrap>
678f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_NUWSub(const LHS &L, const RHS &R) {
679f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
680f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                   OverflowingBinaryOperator::NoUnsignedWrap>(
681f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      L, R);
682f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
683f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
684f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
685f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                 OverflowingBinaryOperator::NoUnsignedWrap>
686f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_NUWMul(const LHS &L, const RHS &R) {
687f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
688f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                   OverflowingBinaryOperator::NoUnsignedWrap>(
689f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      L, R);
690f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
691f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
692f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
693f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                 OverflowingBinaryOperator::NoUnsignedWrap>
694f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_NUWShl(const LHS &L, const RHS &R) {
695f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
696f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                   OverflowingBinaryOperator::NoUnsignedWrap>(
697f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      L, R);
698f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
699f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
700f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
701f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Class that matches a group of binary opcodes.
702f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
703f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS_t, typename RHS_t, typename Predicate>
704f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct BinOpPred_match : Predicate {
705f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LHS_t L;
706f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RHS_t R;
707f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
708f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  BinOpPred_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
709f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
710f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
711f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *I = dyn_cast<Instruction>(V))
712f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return this->isOpType(I->getOpcode()) && L.match(I->getOperand(0)) &&
713f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             R.match(I->getOperand(1));
714f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *CE = dyn_cast<ConstantExpr>(V))
715f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return this->isOpType(CE->getOpcode()) && L.match(CE->getOperand(0)) &&
716f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             R.match(CE->getOperand(1));
717f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
718f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
719f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
720f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
721f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct is_shift_op {
722f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isOpType(unsigned Opcode) { return Instruction::isShift(Opcode); }
723f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
724f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
725f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct is_right_shift_op {
726f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isOpType(unsigned Opcode) {
727f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Opcode == Instruction::LShr || Opcode == Instruction::AShr;
728f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
729f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
730f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
731f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct is_logical_shift_op {
732f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isOpType(unsigned Opcode) {
733f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Opcode == Instruction::LShr || Opcode == Instruction::Shl;
734f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
735f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
736f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
737f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct is_bitwiselogic_op {
738f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isOpType(unsigned Opcode) {
739f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Instruction::isBitwiseLogicOp(Opcode);
740f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
741f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
742f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
743f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct is_idiv_op {
744f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isOpType(unsigned Opcode) {
745f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Opcode == Instruction::SDiv || Opcode == Instruction::UDiv;
746f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
747f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
748f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
749f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches shift operations.
750f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
751f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinOpPred_match<LHS, RHS, is_shift_op> m_Shift(const LHS &L,
752f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                      const RHS &R) {
753f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinOpPred_match<LHS, RHS, is_shift_op>(L, R);
754f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
755f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
756f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches logical shift operations.
757f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
758f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinOpPred_match<LHS, RHS, is_right_shift_op> m_Shr(const LHS &L,
759f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                          const RHS &R) {
760f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinOpPred_match<LHS, RHS, is_right_shift_op>(L, R);
761f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
762f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
763f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches logical shift operations.
764f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
765f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinOpPred_match<LHS, RHS, is_logical_shift_op>
766f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_LogicalShift(const LHS &L, const RHS &R) {
767f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinOpPred_match<LHS, RHS, is_logical_shift_op>(L, R);
768f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
769f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
770f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches bitwise logic operations.
771f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
772f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinOpPred_match<LHS, RHS, is_bitwiselogic_op>
773f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_BitwiseLogic(const LHS &L, const RHS &R) {
774f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinOpPred_match<LHS, RHS, is_bitwiselogic_op>(L, R);
775f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
776f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
777f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches integer division operations.
778f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
779f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinOpPred_match<LHS, RHS, is_idiv_op> m_IDiv(const LHS &L,
780f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                    const RHS &R) {
781f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinOpPred_match<LHS, RHS, is_idiv_op>(L, R);
782f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
783f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
784f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
785f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Class that matches exact binary ops.
786f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
787f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename SubPattern_t> struct Exact_match {
788f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SubPattern_t SubPattern;
789f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
790f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Exact_match(const SubPattern_t &SP) : SubPattern(SP) {}
791f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
792f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
793f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *PEO = dyn_cast<PossiblyExactOperator>(V))
794f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return PEO->isExact() && SubPattern.match(V);
795f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
796f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
797f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
798f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
799f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename T> inline Exact_match<T> m_Exact(const T &SubPattern) {
800f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return SubPattern;
801f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
802f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
803f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
804f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Matchers for CmpInst classes
805f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
806f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
807f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS_t, typename RHS_t, typename Class, typename PredicateTy,
808f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          bool Commutable = false>
809f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct CmpClass_match {
810f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  PredicateTy &Predicate;
811f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LHS_t L;
812f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RHS_t R;
813f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
814f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, const RHS_t &RHS)
815f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      : Predicate(Pred), L(LHS), R(RHS) {}
816f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
817f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
818f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *I = dyn_cast<Class>(V))
819f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if ((L.match(I->getOperand(0)) && R.match(I->getOperand(1))) ||
820f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          (Commutable && R.match(I->getOperand(0)) &&
821f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot           L.match(I->getOperand(1)))) {
822f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        Predicate = I->getPredicate();
823f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return true;
824f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      }
825f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
826f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
827f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
828f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
829f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
830f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CmpClass_match<LHS, RHS, CmpInst, CmpInst::Predicate>
831f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_Cmp(CmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
832f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CmpClass_match<LHS, RHS, CmpInst, CmpInst::Predicate>(Pred, L, R);
833f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
834f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
835f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
836f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
837f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
838f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>(Pred, L, R);
839f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
840f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
841f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
842f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
843f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
844f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>(Pred, L, R);
845f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
846f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
847f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
848f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Matchers for SelectInst classes
849f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
850f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
851f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Cond_t, typename LHS_t, typename RHS_t>
852f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct SelectClass_match {
853f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Cond_t C;
854f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LHS_t L;
855f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RHS_t R;
856f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
857f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SelectClass_match(const Cond_t &Cond, const LHS_t &LHS, const RHS_t &RHS)
858f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      : C(Cond), L(LHS), R(RHS) {}
859f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
860f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
861f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *I = dyn_cast<SelectInst>(V))
862f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return C.match(I->getOperand(0)) && L.match(I->getOperand(1)) &&
863f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             R.match(I->getOperand(2));
864f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
865f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
866f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
867f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
868f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Cond, typename LHS, typename RHS>
869f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline SelectClass_match<Cond, LHS, RHS> m_Select(const Cond &C, const LHS &L,
870f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                  const RHS &R) {
871f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return SelectClass_match<Cond, LHS, RHS>(C, L, R);
872f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
873f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
874f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief This matches a select of two constants, e.g.:
875f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// m_SelectCst<-1, 0>(m_Value(V))
876f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <int64_t L, int64_t R, typename Cond>
877f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline SelectClass_match<Cond, constantint_match<L>, constantint_match<R>>
878f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_SelectCst(const Cond &C) {
879f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return m_Select(C, m_ConstantInt<L>(), m_ConstantInt<R>());
880f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
881f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
882f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
883f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Matchers for CastInst classes
884f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
885f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
886f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Op_t, unsigned Opcode> struct CastClass_match {
887f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Op_t Op;
888f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
889f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  CastClass_match(const Op_t &OpMatch) : Op(OpMatch) {}
890f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
891f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
892f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *O = dyn_cast<Operator>(V))
893f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return O->getOpcode() == Opcode && Op.match(O->getOperand(0));
894f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
895f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
896f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
897f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
898f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches BitCast.
899f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename OpTy>
900f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CastClass_match<OpTy, Instruction::BitCast> m_BitCast(const OpTy &Op) {
901f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CastClass_match<OpTy, Instruction::BitCast>(Op);
902f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
903f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
904f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches PtrToInt.
905f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename OpTy>
906f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CastClass_match<OpTy, Instruction::PtrToInt> m_PtrToInt(const OpTy &Op) {
907f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CastClass_match<OpTy, Instruction::PtrToInt>(Op);
908f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
909f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
910f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches Trunc.
911f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename OpTy>
912f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CastClass_match<OpTy, Instruction::Trunc> m_Trunc(const OpTy &Op) {
913f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CastClass_match<OpTy, Instruction::Trunc>(Op);
914f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
915f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
916f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches SExt.
917f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename OpTy>
918f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CastClass_match<OpTy, Instruction::SExt> m_SExt(const OpTy &Op) {
919f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CastClass_match<OpTy, Instruction::SExt>(Op);
920f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
921f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
922f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches ZExt.
923f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename OpTy>
924f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CastClass_match<OpTy, Instruction::ZExt> m_ZExt(const OpTy &Op) {
925f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CastClass_match<OpTy, Instruction::ZExt>(Op);
926f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
927f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
928f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename OpTy>
929f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline match_combine_or<CastClass_match<OpTy, Instruction::ZExt>,
930f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                        CastClass_match<OpTy, Instruction::SExt>>
931f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_ZExtOrSExt(const OpTy &Op) {
932f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return m_CombineOr(m_ZExt(Op), m_SExt(Op));
933f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
934f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
935f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches UIToFP.
936f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename OpTy>
937f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CastClass_match<OpTy, Instruction::UIToFP> m_UIToFP(const OpTy &Op) {
938f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CastClass_match<OpTy, Instruction::UIToFP>(Op);
939f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
940f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
941f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches SIToFP.
942f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename OpTy>
943f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CastClass_match<OpTy, Instruction::SIToFP> m_SIToFP(const OpTy &Op) {
944f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CastClass_match<OpTy, Instruction::SIToFP>(Op);
945f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
946f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
947f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches FPTrunc
948f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename OpTy>
949f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CastClass_match<OpTy, Instruction::FPTrunc> m_FPTrunc(const OpTy &Op) {
950f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CastClass_match<OpTy, Instruction::FPTrunc>(Op);
951f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
952f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
953f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches FPExt
954f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename OpTy>
955f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CastClass_match<OpTy, Instruction::FPExt> m_FPExt(const OpTy &Op) {
956f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CastClass_match<OpTy, Instruction::FPExt>(Op);
957f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
958f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
959f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
960f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Matchers for unary operators
961f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
962f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
963f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS_t> struct not_match {
964f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LHS_t L;
965f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
966f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  not_match(const LHS_t &LHS) : L(LHS) {}
967f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
968f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
969f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *O = dyn_cast<Operator>(V))
970f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (O->getOpcode() == Instruction::Xor) {
971f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        if (isAllOnes(O->getOperand(1)))
972f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          return L.match(O->getOperand(0));
973f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        if (isAllOnes(O->getOperand(0)))
974f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          return L.match(O->getOperand(1));
975f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      }
976f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
977f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
978f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
979f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate:
980f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isAllOnes(Value *V) {
981f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return isa<Constant>(V) && cast<Constant>(V)->isAllOnesValue();
982f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
983f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
984f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
985f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS> inline not_match<LHS> m_Not(const LHS &L) { return L; }
986f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
987f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS_t> struct neg_match {
988f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LHS_t L;
989f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
990f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  neg_match(const LHS_t &LHS) : L(LHS) {}
991f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
992f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
993f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *O = dyn_cast<Operator>(V))
994f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (O->getOpcode() == Instruction::Sub)
995f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return matchIfNeg(O->getOperand(0), O->getOperand(1));
996f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
997f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
998f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
999f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate:
1000f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool matchIfNeg(Value *LHS, Value *RHS) {
1001f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return ((isa<ConstantInt>(LHS) && cast<ConstantInt>(LHS)->isZero()) ||
1002f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot            isa<ConstantAggregateZero>(LHS)) &&
1003f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot           L.match(RHS);
1004f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1005f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1006f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1007f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an integer negate.
1008f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS> inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
1009f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1010f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS_t> struct fneg_match {
1011f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LHS_t L;
1012f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1013f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  fneg_match(const LHS_t &LHS) : L(LHS) {}
1014f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1015f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
1016f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *O = dyn_cast<Operator>(V))
1017f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (O->getOpcode() == Instruction::FSub)
1018f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return matchIfFNeg(O->getOperand(0), O->getOperand(1));
1019f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
1020f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1021f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1022f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate:
1023f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool matchIfFNeg(Value *LHS, Value *RHS) {
1024f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *C = dyn_cast<ConstantFP>(LHS))
1025f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return C->isNegativeZeroValue() && L.match(RHS);
1026f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
1027f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1028f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1029f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1030f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match a floating point negate.
1031f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS> inline fneg_match<LHS> m_FNeg(const LHS &L) {
1032f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return L;
1033f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1034f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1035f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
1036f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Matchers for control flow.
1037f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
1038f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1039f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct br_match {
1040f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  BasicBlock *&Succ;
1041f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1042f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  br_match(BasicBlock *&Succ) : Succ(Succ) {}
1043f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1044f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
1045f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *BI = dyn_cast<BranchInst>(V))
1046f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (BI->isUnconditional()) {
1047f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        Succ = BI->getSuccessor(0);
1048f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return true;
1049f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      }
1050f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
1051f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1052f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1053f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1054f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ); }
1055f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1056f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Cond_t> struct brc_match {
1057f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Cond_t Cond;
1058f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  BasicBlock *&T, *&F;
1059f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1060f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f)
1061f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      : Cond(C), T(t), F(f) {}
1062f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1063f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
1064f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (auto *BI = dyn_cast<BranchInst>(V))
1065f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (BI->isConditional() && Cond.match(BI->getCondition())) {
1066f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        T = BI->getSuccessor(0);
1067f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        F = BI->getSuccessor(1);
1068f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return true;
1069f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      }
1070f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
1071f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1072f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1073f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1074f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Cond_t>
1075f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) {
1076f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return brc_match<Cond_t>(C, T, F);
1077f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1078f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1079f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
1080f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y).
1081f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
1082f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1083f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename CmpInst_t, typename LHS_t, typename RHS_t, typename Pred_t,
1084f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          bool Commutable = false>
1085f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct MaxMin_match {
1086f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LHS_t L;
1087f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RHS_t R;
1088f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1089f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MaxMin_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
1090f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1091f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
1092f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x".
1093f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    auto *SI = dyn_cast<SelectInst>(V);
1094f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (!SI)
1095f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return false;
1096f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    auto *Cmp = dyn_cast<CmpInst_t>(SI->getCondition());
1097f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (!Cmp)
1098f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return false;
1099f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // At this point we have a select conditioned on a comparison.  Check that
1100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // it is the values returned by the select that are being compared.
1101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Value *TrueVal = SI->getTrueValue();
1102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Value *FalseVal = SI->getFalseValue();
1103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Value *LHS = Cmp->getOperand(0);
1104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Value *RHS = Cmp->getOperand(1);
1105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if ((TrueVal != LHS || FalseVal != RHS) &&
1106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        (TrueVal != RHS || FalseVal != LHS))
1107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return false;
1108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    typename CmpInst_t::Predicate Pred =
1109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        LHS == TrueVal ? Cmp->getPredicate() : Cmp->getInversePredicate();
1110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // Does "(x pred y) ? x : y" represent the desired max/min operation?
1111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (!Pred_t::match(Pred))
1112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return false;
1113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // It does!  Bind the operands.
1114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return (L.match(LHS) && R.match(RHS)) ||
1115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot           (Commutable && R.match(LHS) && L.match(RHS));
1116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Helper class for identifying signed max predicates.
1120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct smax_pred_ty {
1121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static bool match(ICmpInst::Predicate Pred) {
1122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE;
1123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Helper class for identifying signed min predicates.
1127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct smin_pred_ty {
1128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static bool match(ICmpInst::Predicate Pred) {
1129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SLE;
1130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Helper class for identifying unsigned max predicates.
1134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct umax_pred_ty {
1135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static bool match(ICmpInst::Predicate Pred) {
1136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE;
1137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Helper class for identifying unsigned min predicates.
1141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct umin_pred_ty {
1142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static bool match(ICmpInst::Predicate Pred) {
1143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE;
1144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Helper class for identifying ordered max predicates.
1148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct ofmax_pred_ty {
1149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static bool match(FCmpInst::Predicate Pred) {
1150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Pred == CmpInst::FCMP_OGT || Pred == CmpInst::FCMP_OGE;
1151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Helper class for identifying ordered min predicates.
1155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct ofmin_pred_ty {
1156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static bool match(FCmpInst::Predicate Pred) {
1157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Pred == CmpInst::FCMP_OLT || Pred == CmpInst::FCMP_OLE;
1158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Helper class for identifying unordered max predicates.
1162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct ufmax_pred_ty {
1163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static bool match(FCmpInst::Predicate Pred) {
1164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Pred == CmpInst::FCMP_UGT || Pred == CmpInst::FCMP_UGE;
1165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1166f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Helper class for identifying unordered min predicates.
1169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct ufmin_pred_ty {
1170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static bool match(FCmpInst::Predicate Pred) {
1171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Pred == CmpInst::FCMP_ULT || Pred == CmpInst::FCMP_ULE;
1172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty> m_SMax(const LHS &L,
1177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                             const RHS &R) {
1178f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>(L, R);
1179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty> m_SMin(const LHS &L,
1183f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                             const RHS &R) {
1184f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>(L, R);
1185f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1186f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1187f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1188f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty> m_UMax(const LHS &L,
1189f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                             const RHS &R) {
1190f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>(L, R);
1191f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1192f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1193f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1194f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty> m_UMin(const LHS &L,
1195f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                             const RHS &R) {
1196f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>(L, R);
1197f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1198f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1199f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an 'ordered' floating point maximum function.
1200f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Floating point has one special value 'NaN'. Therefore, there is no total
1201f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// order. However, if we can ignore the 'NaN' value (for example, because of a
1202f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum'
1203f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// semantics. In the presence of 'NaN' we have to preserve the original
1204f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// select(fcmp(ogt/ge, L, R), L, R) semantics matched by this predicate.
1205f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
1206f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///                         max(L, R)  iff L and R are not NaN
1207f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///  m_OrdFMax(L, R) =      R          iff L or R are NaN
1208f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1209f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty> m_OrdFMax(const LHS &L,
1210f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                                 const RHS &R) {
1211f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty>(L, R);
1212f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1213f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1214f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an 'ordered' floating point minimum function.
1215f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Floating point has one special value 'NaN'. Therefore, there is no total
1216f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// order. However, if we can ignore the 'NaN' value (for example, because of a
1217f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
1218f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// semantics. In the presence of 'NaN' we have to preserve the original
1219f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// select(fcmp(olt/le, L, R), L, R) semantics matched by this predicate.
1220f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
1221f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///                         min(L, R)  iff L and R are not NaN
1222f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///  m_OrdFMin(L, R) =      R          iff L or R are NaN
1223f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1224f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty> m_OrdFMin(const LHS &L,
1225f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                                 const RHS &R) {
1226f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty>(L, R);
1227f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1228f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1229f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an 'unordered' floating point maximum function.
1230f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Floating point has one special value 'NaN'. Therefore, there is no total
1231f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// order. However, if we can ignore the 'NaN' value (for example, because of a
1232f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum'
1233f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// semantics. In the presence of 'NaN' we have to preserve the original
1234f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// select(fcmp(ugt/ge, L, R), L, R) semantics matched by this predicate.
1235f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
1236f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///                         max(L, R)  iff L and R are not NaN
1237f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///  m_UnordFMax(L, R) =    L          iff L or R are NaN
1238f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1239f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>
1240f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_UnordFMax(const LHS &L, const RHS &R) {
1241f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R);
1242f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1243f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1244f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an 'unordered' floating point minimum function.
1245f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Floating point has one special value 'NaN'. Therefore, there is no total
1246f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// order. However, if we can ignore the 'NaN' value (for example, because of a
1247f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
1248f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// semantics. In the presence of 'NaN' we have to preserve the original
1249f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate.
1250f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
1251f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///                          min(L, R)  iff L and R are not NaN
1252f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///  m_UnordFMin(L, R) =     L          iff L or R are NaN
1253f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1254f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>
1255f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_UnordFMin(const LHS &L, const RHS &R) {
1256f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R);
1257f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1258f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1259f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
1260f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Matchers for overflow check patterns: e.g. (a + b) u< a
1261f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
1262f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1263f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS_t, typename RHS_t, typename Sum_t>
1264f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct UAddWithOverflow_match {
1265f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LHS_t L;
1266f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  RHS_t R;
1267f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Sum_t S;
1268f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1269f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  UAddWithOverflow_match(const LHS_t &L, const RHS_t &R, const Sum_t &S)
1270f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      : L(L), R(R), S(S) {}
1271f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1272f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
1273f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Value *ICmpLHS, *ICmpRHS;
1274f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    ICmpInst::Predicate Pred;
1275f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (!m_ICmp(Pred, m_Value(ICmpLHS), m_Value(ICmpRHS)).match(V))
1276f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return false;
1277f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1278f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Value *AddLHS, *AddRHS;
1279f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    auto AddExpr = m_Add(m_Value(AddLHS), m_Value(AddRHS));
1280f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1281f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // (a + b) u< a, (a + b) u< b
1282f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (Pred == ICmpInst::ICMP_ULT)
1283f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (AddExpr.match(ICmpLHS) && (ICmpRHS == AddLHS || ICmpRHS == AddRHS))
1284f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS);
1285f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1286f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // a >u (a + b), b >u (a + b)
1287f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (Pred == ICmpInst::ICMP_UGT)
1288f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (AddExpr.match(ICmpRHS) && (ICmpLHS == AddLHS || ICmpLHS == AddRHS))
1289f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS);
1290f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1291f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
1292f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1293f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1294f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1295f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an icmp instruction checking for unsigned overflow on addition.
1296f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
1297f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// S is matched to the addition whose result is being checked for overflow, and
1298f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// L and R are matched to the LHS and RHS of S.
1299f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS_t, typename RHS_t, typename Sum_t>
1300f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotUAddWithOverflow_match<LHS_t, RHS_t, Sum_t>
1301f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S) {
1302f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return UAddWithOverflow_match<LHS_t, RHS_t, Sum_t>(L, R, S);
1303f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1304f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1305f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Opnd_t> struct Argument_match {
1306f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned OpI;
1307f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Opnd_t Val;
1308f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1309f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) {}
1310f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1311f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
1312f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CallSite CS(V);
1313f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return CS.isCall() && Val.match(CS.getArgument(OpI));
1314f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1315f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1316f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1317f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match an argument.
1318f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <unsigned OpI, typename Opnd_t>
1319f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) {
1320f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return Argument_match<Opnd_t>(OpI, Op);
1321f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1322f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1323f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Intrinsic matchers.
1324f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct IntrinsicID_match {
1325f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned ID;
1326f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1327f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  IntrinsicID_match(Intrinsic::ID IntrID) : ID(IntrID) {}
1328f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1329f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
1330f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (const auto *CI = dyn_cast<CallInst>(V))
1331f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (const auto *F = CI->getCalledFunction())
1332f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return F->getIntrinsicID() == ID;
1333f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return false;
1334f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1335f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1336f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1337f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Intrinsic matches are combinations of ID matchers, and argument
1338f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// matchers. Higher arity matcher are defined recursively in terms of and-ing
1339f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// them with lower arity matchers. Here's some convenient typedefs for up to
1340f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// several arguments, and more can be added as needed
1341f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename T0 = void, typename T1 = void, typename T2 = void,
1342f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          typename T3 = void, typename T4 = void, typename T5 = void,
1343f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          typename T6 = void, typename T7 = void, typename T8 = void,
1344f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          typename T9 = void, typename T10 = void>
1345f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct m_Intrinsic_Ty;
1346f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename T0> struct m_Intrinsic_Ty<T0> {
1347f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using Ty = match_combine_and<IntrinsicID_match, Argument_match<T0>>;
1348f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1349f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename T0, typename T1> struct m_Intrinsic_Ty<T0, T1> {
1350f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using Ty =
1351f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      match_combine_and<typename m_Intrinsic_Ty<T0>::Ty, Argument_match<T1>>;
1352f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1353f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename T0, typename T1, typename T2>
1354f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct m_Intrinsic_Ty<T0, T1, T2> {
1355f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using Ty =
1356f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty,
1357f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                        Argument_match<T2>>;
1358f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1359f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename T0, typename T1, typename T2, typename T3>
1360f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct m_Intrinsic_Ty<T0, T1, T2, T3> {
1361f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using Ty =
1362f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty,
1363f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                        Argument_match<T3>>;
1364f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1365f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1366f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Match intrinsic calls like this:
1367f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// m_Intrinsic<Intrinsic::fabs>(m_Value(X))
1368f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <Intrinsic::ID IntrID> inline IntrinsicID_match m_Intrinsic() {
1369f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return IntrinsicID_match(IntrID);
1370f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1371f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1372f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <Intrinsic::ID IntrID, typename T0>
1373f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline typename m_Intrinsic_Ty<T0>::Ty m_Intrinsic(const T0 &Op0) {
1374f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return m_CombineAnd(m_Intrinsic<IntrID>(), m_Argument<0>(Op0));
1375f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1376f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1377f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <Intrinsic::ID IntrID, typename T0, typename T1>
1378f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline typename m_Intrinsic_Ty<T0, T1>::Ty m_Intrinsic(const T0 &Op0,
1379f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                       const T1 &Op1) {
1380f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return m_CombineAnd(m_Intrinsic<IntrID>(Op0), m_Argument<1>(Op1));
1381f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1382f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1383f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <Intrinsic::ID IntrID, typename T0, typename T1, typename T2>
1384f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline typename m_Intrinsic_Ty<T0, T1, T2>::Ty
1385f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2) {
1386f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1), m_Argument<2>(Op2));
1387f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1388f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1389f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <Intrinsic::ID IntrID, typename T0, typename T1, typename T2,
1390f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          typename T3>
1391f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline typename m_Intrinsic_Ty<T0, T1, T2, T3>::Ty
1392f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) {
1393f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2), m_Argument<3>(Op3));
1394f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1395f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1396f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Helper intrinsic matching specializations.
1397f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Opnd0>
1398f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline typename m_Intrinsic_Ty<Opnd0>::Ty m_BitReverse(const Opnd0 &Op0) {
1399f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return m_Intrinsic<Intrinsic::bitreverse>(Op0);
1400f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1401f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1402f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Opnd0>
1403f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline typename m_Intrinsic_Ty<Opnd0>::Ty m_BSwap(const Opnd0 &Op0) {
1404f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return m_Intrinsic<Intrinsic::bswap>(Op0);
1405f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1406f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1407f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Opnd0, typename Opnd1>
1408f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMin(const Opnd0 &Op0,
1409f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                        const Opnd1 &Op1) {
1410f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return m_Intrinsic<Intrinsic::minnum>(Op0, Op1);
1411f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1412f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1413f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Opnd0, typename Opnd1>
1414f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMax(const Opnd0 &Op0,
1415f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                        const Opnd1 &Op1) {
1416f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return m_Intrinsic<Intrinsic::maxnum>(Op0, Op1);
1417f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1418f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1419f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Opnd_t> struct Signum_match {
1420f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Opnd_t Val;
1421f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Signum_match(const Opnd_t &V) : Val(V) {}
1422f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1423f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  template <typename OpTy> bool match(OpTy *V) {
1424f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned TypeSize = V->getType()->getScalarSizeInBits();
1425f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (TypeSize == 0)
1426f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return false;
1427f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1428f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned ShiftWidth = TypeSize - 1;
1429f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Value *OpL = nullptr, *OpR = nullptr;
1430f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1431f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // This is the representation of signum we match:
1432f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    //
1433f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    //  signum(x) == (x >> 63) | (-x >>u 63)
1434f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    //
1435f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // An i1 value is its own signum, so it's correct to match
1436f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    //
1437f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    //  signum(x) == (x >> 0)  | (-x >>u 0)
1438f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    //
1439f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // for i1 values.
1440f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1441f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    auto LHS = m_AShr(m_Value(OpL), m_SpecificInt(ShiftWidth));
1442f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    auto RHS = m_LShr(m_Neg(m_Value(OpR)), m_SpecificInt(ShiftWidth));
1443f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    auto Signum = m_Or(LHS, RHS);
1444f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1445f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Signum.match(V) && OpL == OpR && Val.match(OpL);
1446f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
1447f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
1448f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1449f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches a signum pattern.
1450f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
1451f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// signum(x) =
1452f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///      x >  0  ->  1
1453f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///      x == 0  ->  0
1454f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///      x <  0  -> -1
1455f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename Val_t> inline Signum_match<Val_t> m_Signum(const Val_t &V) {
1456f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return Signum_match<Val_t>(V);
1457f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1458f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1459f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
1460f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Matchers for two-operands operators with the operators in either order
1461f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
1462f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1463f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches a BinaryOperator with LHS and RHS in either order.
1464f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1465f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline AnyBinaryOp_match<LHS, RHS, true> m_c_BinOp(const LHS &L, const RHS &R) {
1466f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return AnyBinaryOp_match<LHS, RHS, true>(L, R);
1467f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1468f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1469f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches an ICmp with a predicate over LHS and RHS in either order.
1470f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Does not swap the predicate.
1471f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1472f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate, true>
1473f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
1474f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate, true>(Pred, L,
1475f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                                       R);
1476f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1477f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1478f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches a Add with LHS and RHS in either order.
1479f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1480f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::Add, true> m_c_Add(const LHS &L,
1481f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                                const RHS &R) {
1482f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::Add, true>(L, R);
1483f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1484f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1485f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches a Mul with LHS and RHS in either order.
1486f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1487f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::Mul, true> m_c_Mul(const LHS &L,
1488f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                                const RHS &R) {
1489f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::Mul, true>(L, R);
1490f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1491f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1492f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches an And with LHS and RHS in either order.
1493f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1494f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::And, true> m_c_And(const LHS &L,
1495f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                                const RHS &R) {
1496f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::And, true>(L, R);
1497f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1498f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1499f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches an Or with LHS and RHS in either order.
1500f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1501f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::Or, true> m_c_Or(const LHS &L,
1502f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                              const RHS &R) {
1503f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::Or, true>(L, R);
1504f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1505f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1506f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Matches an Xor with LHS and RHS in either order.
1507f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1508f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline BinaryOp_match<LHS, RHS, Instruction::Xor, true> m_c_Xor(const LHS &L,
1509f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                                                const RHS &R) {
1510f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return BinaryOp_match<LHS, RHS, Instruction::Xor, true>(L, R);
1511f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1512f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1513f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Matches an SMin with LHS and RHS in either order.
1514f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1515f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty, true>
1516f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_c_SMin(const LHS &L, const RHS &R) {
1517f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty, true>(L, R);
1518f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1519f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Matches an SMax with LHS and RHS in either order.
1520f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1521f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty, true>
1522f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_c_SMax(const LHS &L, const RHS &R) {
1523f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty, true>(L, R);
1524f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1525f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Matches a UMin with LHS and RHS in either order.
1526f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1527f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty, true>
1528f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_c_UMin(const LHS &L, const RHS &R) {
1529f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty, true>(L, R);
1530f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1531f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Matches a UMax with LHS and RHS in either order.
1532f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename LHS, typename RHS>
1533f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>
1534f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotm_c_UMax(const LHS &L, const RHS &R) {
1535f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>(L, R);
1536f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
1537f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1538f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace PatternMatch
1539f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace llvm
1540f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
1541f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif // LLVM_IR_PATTERNMATCH_H
1542