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