[PatternMatch] Make m_Br more flexible, add matchers for BB values.
Currently m_Br only takes references to BasicBlock*, which limits its
flexibility. For example, you have to declare a variable, even if you
ignore the result or you have to have additional checks to make sure the
matched BB matches an expected one.
This patch adds m_BasicBlock and m_SpecificBB matchers, which can be
used like the existing matchers for constants or values.
I also had a look at the existing uses and updated a few. IMO it makes
the code a bit more explicit.
Reviewers: spatel, craig.topper, RKSimon, majnemer, lebedev.ri
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D68013
llvm-svn: 372885
diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp
index fe8c518..d52d4fe 100644
--- a/llvm/unittests/IR/PatternMatch.cpp
+++ b/llvm/unittests/IR/PatternMatch.cpp
@@ -1045,6 +1045,34 @@
EXPECT_FALSE(match(V3, m_FNeg(m_Value(Match))));
}
+TEST_F(PatternMatchTest, CondBranchTest) {
+ BasicBlock *TrueBB = BasicBlock::Create(Ctx, "TrueBB", F);
+ BasicBlock *FalseBB = BasicBlock::Create(Ctx, "FalseBB", F);
+ Value *Br1 = IRB.CreateCondBr(IRB.getTrue(), TrueBB, FalseBB);
+
+ EXPECT_TRUE(match(Br1, m_Br(m_Value(), m_BasicBlock(), m_BasicBlock())));
+
+ BasicBlock *A, *B;
+ EXPECT_TRUE(match(Br1, m_Br(m_Value(), m_BasicBlock(A), m_BasicBlock(B))));
+ EXPECT_EQ(TrueBB, A);
+ EXPECT_EQ(FalseBB, B);
+
+ EXPECT_FALSE(
+ match(Br1, m_Br(m_Value(), m_SpecificBB(FalseBB), m_BasicBlock())));
+ EXPECT_FALSE(
+ match(Br1, m_Br(m_Value(), m_BasicBlock(), m_SpecificBB(TrueBB))));
+ EXPECT_FALSE(
+ match(Br1, m_Br(m_Value(), m_SpecificBB(FalseBB), m_BasicBlock(TrueBB))));
+ EXPECT_TRUE(
+ match(Br1, m_Br(m_Value(), m_SpecificBB(TrueBB), m_BasicBlock(FalseBB))));
+
+ // Check we can use m_Deferred with branches.
+ EXPECT_FALSE(match(Br1, m_Br(m_Value(), m_BasicBlock(A), m_Deferred(A))));
+ Value *Br2 = IRB.CreateCondBr(IRB.getTrue(), TrueBB, TrueBB);
+ A = nullptr;
+ EXPECT_TRUE(match(Br2, m_Br(m_Value(), m_BasicBlock(A), m_Deferred(A))));
+}
+
template <typename T> struct MutableConstTest : PatternMatchTest { };
typedef ::testing::Types<std::tuple<Value*, Instruction*>,