From 5c63b24ec8fde29023af1213a4685df1d4a58dde Mon Sep 17 00:00:00 2001 From: Jessica Paquette Date: Thu, 6 Oct 2022 10:30:10 -0700 Subject: [PATCH] [GlobalISel] Add a m_SpecificReg matcher Similar to the specific matchers for constants. The intention here is to make it easier to write combines which check if a specific register is used more than once. e.g. matching patterns like: ``` (X + Y) == Y ``` Differential Revision: https://reviews.llvm.org/D135378 --- llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h | 14 ++++++++++++++ llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h index 7eac0c1..b1795aa 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h @@ -237,6 +237,20 @@ inline SpecificConstantMatch m_AllOnesInt() { } ///} +/// Matcher for a specific register. +struct SpecificRegisterMatch { + Register RequestedReg; + SpecificRegisterMatch(Register RequestedReg) : RequestedReg(RequestedReg) {} + bool match(const MachineRegisterInfo &MRI, Register Reg) { + return Reg == RequestedReg; + } +}; + +/// Matches a register only if it is equal to \p RequestedReg. +inline SpecificRegisterMatch m_SpecificReg(Register RequestedReg) { + return SpecificRegisterMatch(RequestedReg); +} + // TODO: Rework this for different kinds of MachineOperand. // Currently assumes the Src for a match is a register. // We might want to support taking in some MachineOperands and call getReg on diff --git a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp index cb8c7b4..5821957 100644 --- a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp @@ -769,6 +769,23 @@ TEST_F(AArch64GISelMITest, MatchNot) { EXPECT_TRUE(mi_match(AddInst.getReg(2), *MRI, m_Not(m_Reg(NotReg)))); EXPECT_EQ(NotReg, Copies[0]); } + +TEST_F(AArch64GISelMITest, MatchSpecificReg) { + setUp(); + if (!TM) + return; + auto Cst1 = B.buildConstant(LLT::scalar(64), 42); + auto Cst2 = B.buildConstant(LLT::scalar(64), 314); + Register Reg = Cst1.getReg(0); + // Basic case: Same register twice. + EXPECT_TRUE(mi_match(Reg, *MRI, m_SpecificReg(Reg))); + // Basic case: Two explicitly different registers. + EXPECT_FALSE(mi_match(Reg, *MRI, m_SpecificReg(Cst2.getReg(0)))); + // Check that we can tell that an instruction uses a specific register. + auto Add = B.buildAdd(LLT::scalar(64), Cst1, Cst2); + EXPECT_TRUE(mi_match(Add.getReg(0), *MRI, m_GAdd(m_SpecificReg(Reg), m_Reg()))); +} + } // namespace int main(int argc, char **argv) { -- 2.7.4