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