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) {