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