Skip to content

Commit f0c1a9a

Browse files
authored
[DAG] Add SDPatternMatch::m_Result to match a specific SDValue result (#145775)
`m_Result<N>` matches a SDValue that is the N-th result of the defining SDNode. This is useful for creating a more fine-grained matching on SDNode with multiple results. ----- Inspired by #145481
1 parent 720d7e0 commit f0c1a9a

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

llvm/include/llvm/CodeGen/SDPatternMatch.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,23 @@ inline Value_match m_Specific(SDValue N) {
108108
return Value_match(N);
109109
}
110110

111+
template <unsigned ResNo, typename Pattern> struct Result_match {
112+
Pattern P;
113+
114+
explicit Result_match(const Pattern &P) : P(P) {}
115+
116+
template <typename MatchContext>
117+
bool match(const MatchContext &Ctx, SDValue N) {
118+
return N.getResNo() == ResNo && P.match(Ctx, N);
119+
}
120+
};
121+
122+
/// Match only if the SDValue is a certain result at ResNo.
123+
template <unsigned ResNo, typename Pattern>
124+
inline Result_match<ResNo, Pattern> m_Result(const Pattern &P) {
125+
return Result_match<ResNo, Pattern>(P);
126+
}
127+
111128
struct DeferredValue_match {
112129
SDValue &MatchVal;
113130

llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,11 @@ TEST_F(SelectionDAGPatternMatchTest, matchBinaryOp) {
264264
SDValue Rotl = DAG->getNode(ISD::ROTL, DL, Int32VT, Op0, Op1);
265265
SDValue Rotr = DAG->getNode(ISD::ROTR, DL, Int32VT, Op1, Op0);
266266

267+
SDValue SMulLoHi = DAG->getNode(ISD::SMUL_LOHI, DL,
268+
DAG->getVTList(Int32VT, Int32VT), Op0, Op1);
269+
SDValue PartsDiff =
270+
DAG->getNode(ISD::SUB, DL, Int32VT, SMulLoHi, SMulLoHi.getValue(1));
271+
267272
SDValue ICMP_GT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETGT);
268273
SDValue ICMP_GE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETGE);
269274
SDValue ICMP_UGT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGT);
@@ -347,6 +352,15 @@ TEST_F(SelectionDAGPatternMatchTest, matchBinaryOp) {
347352
EXPECT_TRUE(sd_match(UMinLikeULT, m_UMinLike(m_Value(), m_Value())));
348353
EXPECT_TRUE(sd_match(UMinLikeULE, m_UMinLike(m_Value(), m_Value())));
349354

355+
// By default, it matches any of the results.
356+
EXPECT_TRUE(
357+
sd_match(PartsDiff, m_Sub(m_Opc(ISD::SMUL_LOHI), m_Opc(ISD::SMUL_LOHI))));
358+
// Matching a specific result.
359+
EXPECT_TRUE(sd_match(PartsDiff, m_Sub(m_Opc(ISD::SMUL_LOHI),
360+
m_Result<1>(m_Opc(ISD::SMUL_LOHI)))));
361+
EXPECT_FALSE(sd_match(PartsDiff, m_Sub(m_Opc(ISD::SMUL_LOHI),
362+
m_Result<0>(m_Opc(ISD::SMUL_LOHI)))));
363+
350364
SDValue BindVal;
351365
EXPECT_TRUE(sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_Value(BindVal),
352366
m_Deferred(BindVal))));

0 commit comments

Comments
 (0)