1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02: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:
David Green 2019-10-31 11:47:47 +00:00
parent ad6a78daf8
commit e4307f1811
2 changed files with 46 additions and 0 deletions

View File

@ -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

View File

@ -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*>,