[llvm] [PatternMatch] Add matchers for `m_{I,F,}Cmp` and `m_{I,F,}SpecificCmp`; NFC (PR #98282)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 10 02:41:45 PDT 2024
https://github.com/goldsteinn updated https://github.com/llvm/llvm-project/pull/98282
>From 8842117ff409adceb0a4b67b4c1d0368e017b653 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Wed, 10 Jul 2024 16:13:31 +0800
Subject: [PATCH] [PatternMatch] Add matchers for `m_{I,F,}Cmp` and
`m_{I,F,}SpecificCmp`; NFC
These matchers either take no predicate argument or match a specific
predicate respectively.
We have a lot of cases where the Pred argument is either unused and
requiring the argument reduces code clarity.
Likewise we have a lot of cases where we only pass in Pred to test
equality which the new `*Specific*` helpers can simplify.
---
llvm/include/llvm/IR/PatternMatch.h | 69 +++++++++++++
llvm/unittests/IR/PatternMatch.cpp | 144 +++++++++++++++++++++++++++-
2 files changed, 212 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index d4e355431a27a..8ae47fb556b25 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -1592,6 +1592,67 @@ m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
return CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>(Pred, L, R);
}
+template <typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, CmpInst, CmpInst::Predicate>
+m_Cmp(const LHS &L, const RHS &R) {
+ CmpInst::Predicate Unused;
+ return CmpClass_match<LHS, RHS, CmpInst, CmpInst::Predicate>(Unused, L, R);
+}
+
+template <typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
+m_ICmp(const LHS &L, const RHS &R) {
+ ICmpInst::Predicate Unused;
+ return CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>(Unused, L, R);
+}
+
+template <typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
+m_FCmp(const LHS &L, const RHS &R) {
+ FCmpInst::Predicate Unused;
+ return CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>(Unused, L, R);
+}
+
+// Same as CmpClass, but instead of saving Pred as out output variable, match a
+// specific input pred for equality.
+template <typename LHS_t, typename RHS_t, typename Class, typename PredicateTy>
+struct SpecificCmpClass_match {
+ const PredicateTy Predicate;
+ LHS_t L;
+ RHS_t R;
+
+ SpecificCmpClass_match(PredicateTy Pred, const LHS_t &LHS, const RHS_t &RHS)
+ : Predicate(Pred), L(LHS), R(RHS) {}
+
+ template <typename OpTy> bool match(OpTy *V) {
+ if (auto *I = dyn_cast<Class>(V))
+ return I->getPredicate() == Predicate && L.match(I->getOperand(0)) &&
+ R.match(I->getOperand(1));
+ return false;
+ }
+};
+
+template <typename LHS, typename RHS>
+inline SpecificCmpClass_match<LHS, RHS, CmpInst, CmpInst::Predicate>
+m_SpecificCmp(CmpInst::Predicate MatchPred, const LHS &L, const RHS &R) {
+ return SpecificCmpClass_match<LHS, RHS, CmpInst, CmpInst::Predicate>(
+ MatchPred, L, R);
+}
+
+template <typename LHS, typename RHS>
+inline SpecificCmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
+m_SpecificICmp(ICmpInst::Predicate MatchPred, const LHS &L, const RHS &R) {
+ return SpecificCmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>(
+ MatchPred, L, R);
+}
+
+template <typename LHS, typename RHS>
+inline SpecificCmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
+m_SpecificFCmp(FCmpInst::Predicate MatchPred, const LHS &L, const RHS &R) {
+ return SpecificCmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>(
+ MatchPred, L, R);
+}
+
//===----------------------------------------------------------------------===//
// Matchers for instructions with a given opcode and number of operands.
//
@@ -2617,6 +2678,14 @@ m_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
R);
}
+template <typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate, true>
+m_c_ICmp(const LHS &L, const RHS &R) {
+ ICmpInst::Predicate Unused;
+ return CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate, true>(Unused,
+ L, R);
+}
+
/// Matches a specific opcode with LHS and RHS in either order.
template <typename LHS, typename RHS>
inline SpecificBinaryOp_match<LHS, RHS, true>
diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp
index 9f91b4f3f9939..309fcc93996bc 100644
--- a/llvm/unittests/IR/PatternMatch.cpp
+++ b/llvm/unittests/IR/PatternMatch.cpp
@@ -2250,9 +2250,151 @@ TYPED_TEST(MutableConstTest, ICmp) {
ICmpInst::Predicate MatchPred;
EXPECT_TRUE(m_ICmp(MatchPred, m_Value(MatchL), m_Value(MatchR))
- .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
EXPECT_EQ(L, MatchL);
EXPECT_EQ(R, MatchR);
+
+ EXPECT_TRUE(m_Cmp(MatchPred, m_Value(MatchL), m_Value(MatchR))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+
+ EXPECT_TRUE(m_ICmp(m_Specific(L), m_Specific(R))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+
+ EXPECT_TRUE(m_Cmp(m_Specific(L), m_Specific(R))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+
+ EXPECT_FALSE(m_ICmp(m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+ EXPECT_FALSE(m_Cmp(m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+
+ EXPECT_TRUE(m_c_ICmp(m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+
+ EXPECT_FALSE(m_c_ICmp(m_Specific(R), m_Specific(R))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+
+ EXPECT_TRUE(m_SpecificICmp(Pred, m_Specific(L), m_Specific(R))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+ EXPECT_TRUE(m_SpecificCmp(Pred, m_Specific(L), m_Specific(R))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+
+ EXPECT_FALSE(m_SpecificICmp(Pred, m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+ EXPECT_FALSE(m_SpecificCmp(Pred, m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+
+ MatchL = nullptr;
+ MatchR = nullptr;
+ EXPECT_TRUE(m_SpecificICmp(Pred, m_Value(MatchL), m_Value(MatchR))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ MatchL = nullptr;
+ MatchR = nullptr;
+ EXPECT_TRUE(m_SpecificCmp(Pred, m_Value(MatchL), m_Value(MatchR))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+
+ EXPECT_FALSE(m_SpecificICmp(Pred, m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+ EXPECT_FALSE(m_SpecificCmp(Pred, m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+
+ EXPECT_FALSE(m_SpecificICmp(ICmpInst::getInversePredicate(Pred),
+ m_Specific(L), m_Specific(R))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+ EXPECT_FALSE(m_SpecificCmp(ICmpInst::getInversePredicate(Pred), m_Specific(L),
+ m_Specific(R))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+
+ EXPECT_FALSE(m_SpecificICmp(ICmpInst::getInversePredicate(Pred),
+ m_Value(MatchL), m_Value(MatchR))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+ EXPECT_FALSE(m_SpecificCmp(ICmpInst::getInversePredicate(Pred),
+ m_Value(MatchL), m_Value(MatchR))
+ .match((InstructionType)IRB.CreateICmp(Pred, L, R)));
+}
+
+TYPED_TEST(MutableConstTest, FCmp) {
+ auto &IRB = PatternMatchTest::IRB;
+
+ typedef std::tuple_element_t<0, TypeParam> ValueType;
+ typedef std::tuple_element_t<1, TypeParam> InstructionType;
+
+ Value *L = Constant::getNullValue(IRB.getFloatTy());
+ Value *R = ConstantFP::getInfinity(IRB.getFloatTy(), true);
+ FCmpInst::Predicate Pred = FCmpInst::FCMP_OGT;
+
+ ValueType MatchL;
+ ValueType MatchR;
+ FCmpInst::Predicate MatchPred;
+
+ EXPECT_TRUE(m_FCmp(MatchPred, m_Value(MatchL), m_Value(MatchR))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+
+ EXPECT_TRUE(m_Cmp(MatchPred, m_Value(MatchL), m_Value(MatchR))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+
+ EXPECT_TRUE(m_FCmp(m_Specific(L), m_Specific(R))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+
+ EXPECT_TRUE(m_Cmp(m_Specific(L), m_Specific(R))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+
+ EXPECT_FALSE(m_FCmp(m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+ EXPECT_FALSE(m_Cmp(m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+
+ EXPECT_TRUE(m_SpecificFCmp(Pred, m_Specific(L), m_Specific(R))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+ EXPECT_TRUE(m_SpecificCmp(Pred, m_Specific(L), m_Specific(R))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+
+ EXPECT_FALSE(m_SpecificFCmp(Pred, m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+ EXPECT_FALSE(m_SpecificCmp(Pred, m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+
+ MatchL = nullptr;
+ MatchR = nullptr;
+ EXPECT_TRUE(m_SpecificFCmp(Pred, m_Value(MatchL), m_Value(MatchR))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ MatchL = nullptr;
+ MatchR = nullptr;
+ EXPECT_TRUE(m_SpecificCmp(Pred, m_Value(MatchL), m_Value(MatchR))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+
+ EXPECT_FALSE(m_SpecificFCmp(Pred, m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+ EXPECT_FALSE(m_SpecificCmp(Pred, m_Specific(R), m_Specific(L))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+
+ EXPECT_FALSE(m_SpecificFCmp(FCmpInst::getInversePredicate(Pred),
+ m_Specific(L), m_Specific(R))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+ EXPECT_FALSE(m_SpecificCmp(FCmpInst::getInversePredicate(Pred), m_Specific(L),
+ m_Specific(R))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+
+ EXPECT_FALSE(m_SpecificFCmp(FCmpInst::getInversePredicate(Pred),
+ m_Value(MatchL), m_Value(MatchR))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
+ EXPECT_FALSE(m_SpecificCmp(FCmpInst::getInversePredicate(Pred),
+ m_Value(MatchL), m_Value(MatchR))
+ .match((InstructionType)IRB.CreateFCmp(Pred, L, R)));
}
TEST_F(PatternMatchTest, ConstExpr) {
More information about the llvm-commits
mailing list