summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Green <david.green@arm.com>2019-10-31 11:47:47 +0000
committerDavid Green <david.green@arm.com>2019-10-31 12:19:29 +0000
commit6cfbefbc4a7ebcf3f2ee38962ddcd8df54719692 (patch)
treedf3ea865996a83a176b6df98a4a4c2391e9c2b2f
parentfb4a55010ee9bd03720609c8542f770775576fc8 (diff)
downloadbcm5719-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.h22
-rw-r--r--llvm/unittests/IR/PatternMatch.cpp24
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*>,
OpenPOWER on IntegriCloud