From 2d7fe6a565c073739e01eab012faaf83e1c20b67 Mon Sep 17 00:00:00 2001 From: Jessica Paquette Date: Thu, 14 Jan 2021 11:09:46 -0800 Subject: [PATCH] [MIPatternMatch] Add m_OneNonDBGUse Add a matcher that checks if the given subpattern has only one non-debug use. Also improve existing m_OneUse testcase. Differential Revision: https://reviews.llvm.org/D94705 --- .../llvm/CodeGen/GlobalISel/MIPatternMatch.h | 14 +++++++++++++ .../CodeGen/GlobalISel/PatternMatchTest.cpp | 21 ++++++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h index ed93dae24c0..55d6d365fbb 100644 --- a/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h +++ b/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h @@ -39,6 +39,20 @@ inline OneUse_match m_OneUse(const SubPat &SP) { return SP; } +template struct OneNonDBGUse_match { + SubPatternT SubPat; + OneNonDBGUse_match(const SubPatternT &SP) : SubPat(SP) {} + + bool match(const MachineRegisterInfo &MRI, Register Reg) { + return MRI.hasOneNonDBGUse(Reg) && SubPat.match(MRI, Reg); + } +}; + +template +inline OneNonDBGUse_match m_OneNonDBGUse(const SubPat &SP) { + return SP; +} + struct ConstantMatch { int64_t &CR; ConstantMatch(int64_t &C) : CR(C) {} diff --git a/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp b/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp index a63a34f9154..8a5d8e78339 100644 --- a/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp +++ b/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp @@ -392,13 +392,24 @@ TEST_F(AArch64GISelMITest, MatchMiscellaneous) { LLT s64 = LLT::scalar(64); auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]); - // Make multiple uses of this add. + Register Reg = MIBAdd.getReg(0); + + // Only one use of Reg. B.buildCast(LLT::pointer(0, 32), MIBAdd); + EXPECT_TRUE(mi_match(Reg, *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg())))); + EXPECT_TRUE(mi_match(Reg, *MRI, m_OneNonDBGUse(m_GAdd(m_Reg(), m_Reg())))); + + // Add multiple debug uses of Reg. + B.buildInstr(TargetOpcode::DBG_VALUE, {}, {Reg})->getOperand(0).setIsDebug(); + B.buildInstr(TargetOpcode::DBG_VALUE, {}, {Reg})->getOperand(0).setIsDebug(); + + EXPECT_FALSE(mi_match(Reg, *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg())))); + EXPECT_TRUE(mi_match(Reg, *MRI, m_OneNonDBGUse(m_GAdd(m_Reg(), m_Reg())))); + + // Multiple non-debug uses of Reg. B.buildCast(LLT::pointer(1, 32), MIBAdd); - bool match = mi_match(MIBAdd.getReg(0), *MRI, m_GAdd(m_Reg(), m_Reg())); - EXPECT_TRUE(match); - match = mi_match(MIBAdd.getReg(0), *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg()))); - EXPECT_FALSE(match); + EXPECT_FALSE(mi_match(Reg, *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg())))); + EXPECT_FALSE(mi_match(Reg, *MRI, m_OneNonDBGUse(m_GAdd(m_Reg(), m_Reg())))); } TEST_F(AArch64GISelMITest, MatchSpecificConstant) {