Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DAG] Add SDPatternMatch m_ZExtOrSelf/m_SExtOrSelf/m_AExtOrSelf/m_TruncOrSelf matchers #85480

Merged
merged 1 commit into from Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 33 additions & 0 deletions llvm/include/llvm/CodeGen/SDPatternMatch.h
Expand Up @@ -632,6 +632,38 @@ template <typename Opnd> inline UnaryOpc_match<Opnd> m_Trunc(const Opnd &Op) {
return UnaryOpc_match<Opnd>(ISD::TRUNCATE, Op);
}

/// Match a zext or identity
/// Allows to peek through optional extensions
template <typename Opnd>
inline Or<UnaryOpc_match<Opnd>, Opnd> m_ZExtOrSelf(Opnd &&Op) {
return Or<UnaryOpc_match<Opnd>, Opnd>(m_ZExt(std::forward<Opnd>(Op)),
std::forward<Opnd>(Op));
}

/// Match a sext or identity
/// Allows to peek through optional extensions
template <typename Opnd>
inline Or<UnaryOpc_match<Opnd>, Opnd> m_SExtOrSelf(Opnd &&Op) {
return Or<UnaryOpc_match<Opnd>, Opnd>(m_SExt(std::forward<Opnd>(Op)),
std::forward<Opnd>(Op));
}

/// Match a aext or identity
/// Allows to peek through optional extensions
template <typename Opnd>
inline Or<UnaryOpc_match<Opnd>, Opnd> m_AExtOrSelf(Opnd &&Op) {
return Or<UnaryOpc_match<Opnd>, Opnd>(m_AnyExt(std::forward<Opnd>(Op)),
std::forward<Opnd>(Op));
}

/// Match a trunc or identity
/// Allows to peek through optional truncations
template <typename Opnd>
inline Or<UnaryOpc_match<Opnd>, Opnd> m_TruncOrSelf(Opnd &&Op) {
return Or<UnaryOpc_match<Opnd>, Opnd>(m_Trunc(std::forward<Opnd>(Op)),
std::forward<Opnd>(Op));
}

// === Constants ===
struct ConstantInt_match {
APInt *BindVal;
Expand Down Expand Up @@ -737,6 +769,7 @@ template <typename ValTy>
inline BinaryOpc_match<ValTy, SpecificInt_match, true> m_Not(const ValTy &V) {
return m_Xor(V, m_AllOnes());
}

} // namespace SDPatternMatch
} // namespace llvm
#endif
32 changes: 32 additions & 0 deletions llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
Expand Up @@ -251,6 +251,38 @@ TEST_F(SelectionDAGPatternMatchTest, patternCombinators) {
EXPECT_TRUE(sd_match(Add, m_AllOf(m_Opc(ISD::ADD), m_OneUse())));
}

TEST_F(SelectionDAGPatternMatchTest, optionalResizing) {
SDLoc DL;
auto Int32VT = EVT::getIntegerVT(Context, 32);
auto Int64VT = EVT::getIntegerVT(Context, 64);

SDValue Op32 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
SDValue Op64 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);
SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op32);
SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op32);
SDValue AExt = DAG->getNode(ISD::ANY_EXTEND, DL, Int64VT, Op32);
SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op64);

using namespace SDPatternMatch;
SDValue A;
EXPECT_TRUE(sd_match(Op32, m_ZExtOrSelf(m_Value(A))));
EXPECT_TRUE(A == Op32);
EXPECT_TRUE(sd_match(ZExt, m_ZExtOrSelf(m_Value(A))));
EXPECT_TRUE(A == Op32);
EXPECT_TRUE(sd_match(Op64, m_SExtOrSelf(m_Value(A))));
EXPECT_TRUE(A == Op64);
EXPECT_TRUE(sd_match(SExt, m_SExtOrSelf(m_Value(A))));
EXPECT_TRUE(A == Op32);
EXPECT_TRUE(sd_match(Op32, m_AExtOrSelf(m_Value(A))));
EXPECT_TRUE(A == Op32);
EXPECT_TRUE(sd_match(AExt, m_AExtOrSelf(m_Value(A))));
EXPECT_TRUE(A == Op32);
EXPECT_TRUE(sd_match(Op64, m_TruncOrSelf(m_Value(A))));
EXPECT_TRUE(A == Op64);
EXPECT_TRUE(sd_match(Trunc, m_TruncOrSelf(m_Value(A))));
EXPECT_TRUE(A == Op64);
}

TEST_F(SelectionDAGPatternMatchTest, matchNode) {
SDLoc DL;
auto Int32VT = EVT::getIntegerVT(Context, 32);
Expand Down