mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[PatternMatch] Add m_WithOverflowInst and m_ExtractValue matchers
Used in D69245, these add pattern matchers for the WithOverflowInst (capturing the result) and the ExtractValue instructions taking a template parameter specifying the element being extracted.
This commit is contained in:
parent
ad6a78daf8
commit
e4307f1811
@ -35,6 +35,7 @@
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
@ -558,6 +559,8 @@ inline bind_ty<const Value> m_Value(const Value *&V) { return V; }
|
||||
inline bind_ty<Instruction> m_Instruction(Instruction *&I) { return I; }
|
||||
/// Match a binary operator, capturing it if we match.
|
||||
inline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; }
|
||||
/// Match a with overflow intrinsic, capturing it if we match.
|
||||
inline bind_ty<WithOverflowInst> m_WithOverflowInst(WithOverflowInst *&I) { return I; }
|
||||
|
||||
/// Match a ConstantInt, capturing the value if we match.
|
||||
inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
|
||||
@ -1937,6 +1940,25 @@ template <typename Val_t> inline Signum_match<Val_t> m_Signum(const Val_t &V) {
|
||||
return Signum_match<Val_t>(V);
|
||||
}
|
||||
|
||||
template <int Ind, typename Opnd_t> struct ExtractValue_match {
|
||||
Opnd_t Val;
|
||||
ExtractValue_match(const Opnd_t &V) : Val(V) {}
|
||||
|
||||
template <typename OpTy> bool match(OpTy *V) {
|
||||
if (auto *I = dyn_cast<ExtractValueInst>(V))
|
||||
return I->getNumIndices() == 1 && I->getIndices()[0] == Ind &&
|
||||
Val.match(I->getAggregateOperand());
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/// Match a single index ExtractValue instruction.
|
||||
/// For example m_ExtractValue<1>(...)
|
||||
template <int Ind, typename Val_t>
|
||||
inline ExtractValue_match<Ind, Val_t> m_ExtractValue(const Val_t &V) {
|
||||
return ExtractValue_match<Ind, Val_t>(V);
|
||||
}
|
||||
|
||||
} // end namespace PatternMatch
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -1109,6 +1109,30 @@ TEST_F(PatternMatchTest, CondBranchTest) {
|
||||
EXPECT_TRUE(match(Br2, m_Br(m_Value(), m_BasicBlock(A), m_Deferred(A))));
|
||||
}
|
||||
|
||||
TEST_F(PatternMatchTest, WithOverflowInst) {
|
||||
Value *Add = IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow,
|
||||
IRB.getInt32(0), IRB.getInt32(0));
|
||||
Value *Add0 = IRB.CreateExtractValue(Add, 0);
|
||||
Value *Add1 = IRB.CreateExtractValue(Add, 1);
|
||||
|
||||
EXPECT_TRUE(match(Add0, m_ExtractValue<0>(m_Value())));
|
||||
EXPECT_FALSE(match(Add0, m_ExtractValue<1>(m_Value())));
|
||||
EXPECT_FALSE(match(Add1, m_ExtractValue<0>(m_Value())));
|
||||
EXPECT_TRUE(match(Add1, m_ExtractValue<1>(m_Value())));
|
||||
EXPECT_FALSE(match(Add, m_ExtractValue<1>(m_Value())));
|
||||
EXPECT_FALSE(match(Add, m_ExtractValue<1>(m_Value())));
|
||||
|
||||
WithOverflowInst *WOI;
|
||||
EXPECT_FALSE(match(Add0, m_WithOverflowInst(WOI)));
|
||||
EXPECT_FALSE(match(Add1, m_WithOverflowInst(WOI)));
|
||||
EXPECT_TRUE(match(Add, m_WithOverflowInst(WOI)));
|
||||
|
||||
EXPECT_TRUE(match(Add0, m_ExtractValue<0>(m_WithOverflowInst(WOI))));
|
||||
EXPECT_EQ(Add, WOI);
|
||||
EXPECT_TRUE(match(Add1, m_ExtractValue<1>(m_WithOverflowInst(WOI))));
|
||||
EXPECT_EQ(Add, WOI);
|
||||
}
|
||||
|
||||
template <typename T> struct MutableConstTest : PatternMatchTest { };
|
||||
|
||||
typedef ::testing::Types<std::tuple<Value*, Instruction*>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user