diff options
author | David Green <david.green@arm.com> | 2019-10-31 11:47:47 +0000 |
---|---|---|
committer | David Green <david.green@arm.com> | 2019-10-31 12:19:29 +0000 |
commit | 6cfbefbc4a7ebcf3f2ee38962ddcd8df54719692 (patch) | |
tree | df3ea865996a83a176b6df98a4a4c2391e9c2b2f | |
parent | fb4a55010ee9bd03720609c8542f770775576fc8 (diff) | |
download | bcm5719-llvm-6cfbefbc4a7ebcf3f2ee38962ddcd8df54719692.tar.gz bcm5719-llvm-6cfbefbc4a7ebcf3f2ee38962ddcd8df54719692.zip |
[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.
-rw-r--r-- | llvm/include/llvm/IR/PatternMatch.h | 22 | ||||
-rw-r--r-- | llvm/unittests/IR/PatternMatch.cpp | 24 |
2 files changed, 46 insertions, 0 deletions
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index 2851b24c05a..37a2fe52ec1 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -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 diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp index c2c38b73a27..f624024d584 100644 --- a/llvm/unittests/IR/PatternMatch.cpp +++ b/llvm/unittests/IR/PatternMatch.cpp @@ -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*>, |