summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorSjoerd Meijer <sjoerd.meijer@arm.com>2018-06-20 07:27:45 +0000
committerSjoerd Meijer <sjoerd.meijer@arm.com>2018-06-20 07:27:45 +0000
commitc6079014468e5b09d79c9f4e08c49da71a57a735 (patch)
tree11b683acce9a01429396392646eb21d0499960ef /llvm
parentd23b6831deb70a7a3cce0d35b25dcfeaad206127 (diff)
downloadbcm5719-llvm-c6079014468e5b09d79c9f4e08c49da71a57a735.tar.gz
bcm5719-llvm-c6079014468e5b09d79c9f4e08c49da71a57a735.zip
[PatternMatch] Add m_Store pattern match helper
Differential Revision: https://reviews.llvm.org/D48279 llvm-svn: 335100
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/PatternMatch.h27
-rw-r--r--llvm/unittests/IR/PatternMatch.cpp36
2 files changed, 63 insertions, 0 deletions
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index dcca931b16d..191aa958a98 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -1193,6 +1193,33 @@ template <typename OpTy> inline LoadClass_match<OpTy> m_Load(const OpTy &Op) {
}
//===----------------------------------------------------------------------===//
+// Matcher for StoreInst classes
+//
+
+template <typename ValueOp_t, typename PointerOp_t> struct StoreClass_match {
+ ValueOp_t ValueOp;
+ PointerOp_t PointerOp;
+
+ StoreClass_match(const ValueOp_t &ValueOpMatch,
+ const PointerOp_t &PointerOpMatch) :
+ ValueOp(ValueOpMatch), PointerOp(PointerOpMatch) {}
+
+ template <typename OpTy> bool match(OpTy *V) {
+ if (auto *LI = dyn_cast<StoreInst>(V))
+ return ValueOp.match(LI->getValueOperand()) &&
+ PointerOp.match(LI->getPointerOperand());
+ return false;
+ }
+};
+
+/// Matches StoreInst.
+template <typename ValueOpTy, typename PointerOpTy>
+inline StoreClass_match<ValueOpTy, PointerOpTy>
+m_Store(const ValueOpTy &ValueOp, const PointerOpTy &PointerOp) {
+ return StoreClass_match<ValueOpTy, PointerOpTy>(ValueOp, PointerOp);
+}
+
+//===----------------------------------------------------------------------===//
// Matchers for unary operators
//
diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp
index 2c6da22298f..6b5686d53c6 100644
--- a/llvm/unittests/IR/PatternMatch.cpp
+++ b/llvm/unittests/IR/PatternMatch.cpp
@@ -390,6 +390,42 @@ TEST_F(PatternMatchTest, OverflowingBinOps) {
EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
}
+TEST_F(PatternMatchTest, LoadStoreOps) {
+ // Create this load/store sequence:
+ //
+ // %p = alloca i32*
+ // %0 = load i32*, i32** %p
+ // store i32 42, i32* %0
+
+ Value *Alloca = IRB.CreateAlloca(IRB.getInt32Ty());
+ Value *LoadInst = IRB.CreateLoad(Alloca);
+ Value *FourtyTwo = IRB.getInt32(42);
+ Value *StoreInst = IRB.CreateStore(FourtyTwo, Alloca);
+ Value *MatchLoad, *MatchStoreVal, *MatchStorePointer;
+
+ EXPECT_TRUE(m_Load(m_Value(MatchLoad)).match(LoadInst));
+ EXPECT_EQ(Alloca, MatchLoad);
+
+ EXPECT_TRUE(m_Load(m_Specific(Alloca)).match(LoadInst));
+
+ EXPECT_FALSE(m_Load(m_Value(MatchLoad)).match(Alloca));
+
+ EXPECT_TRUE(m_Store(m_Value(MatchStoreVal), m_Value(MatchStorePointer))
+ .match(StoreInst));
+ EXPECT_EQ(FourtyTwo, MatchStoreVal);
+ EXPECT_EQ(Alloca, MatchStorePointer);
+
+ EXPECT_FALSE(m_Store(m_Value(MatchStoreVal), m_Value(MatchStorePointer))
+ .match(Alloca));
+
+ EXPECT_TRUE(m_Store(m_SpecificInt(42), m_Specific(Alloca))
+ .match(StoreInst));
+ EXPECT_FALSE(m_Store(m_SpecificInt(42), m_Specific(FourtyTwo))
+ .match(StoreInst));
+ EXPECT_FALSE(m_Store(m_SpecificInt(43), m_Specific(Alloca))
+ .match(StoreInst));
+}
+
TEST_F(PatternMatchTest, VectorOps) {
// Build up small tree of vector operations
//
OpenPOWER on IntegriCloud