diff --git a/llvm/include/llvm/CodeGen/SDPatternMatch.h b/llvm/include/llvm/CodeGen/SDPatternMatch.h index 541c0ecb5be37..4cc7bb9c3b55a 100644 --- a/llvm/include/llvm/CodeGen/SDPatternMatch.h +++ b/llvm/include/llvm/CodeGen/SDPatternMatch.h @@ -632,6 +632,38 @@ template inline UnaryOpc_match m_Trunc(const Opnd &Op) { return UnaryOpc_match(ISD::TRUNCATE, Op); } +/// Match a zext or identity +/// Allows to peek through optional extensions +template +inline Or, Opnd> m_ZExtOrSelf(Opnd &&Op) { + return Or, Opnd>(m_ZExt(std::forward(Op)), + std::forward(Op)); +} + +/// Match a sext or identity +/// Allows to peek through optional extensions +template +inline Or, Opnd> m_SExtOrSelf(Opnd &&Op) { + return Or, Opnd>(m_SExt(std::forward(Op)), + std::forward(Op)); +} + +/// Match a aext or identity +/// Allows to peek through optional extensions +template +inline Or, Opnd> m_AExtOrSelf(Opnd &&Op) { + return Or, Opnd>(m_AnyExt(std::forward(Op)), + std::forward(Op)); +} + +/// Match a trunc or identity +/// Allows to peek through optional truncations +template +inline Or, Opnd> m_TruncOrSelf(Opnd &&Op) { + return Or, Opnd>(m_Trunc(std::forward(Op)), + std::forward(Op)); +} + // === Constants === struct ConstantInt_match { APInt *BindVal; @@ -737,6 +769,7 @@ template inline BinaryOpc_match m_Not(const ValTy &V) { return m_Xor(V, m_AllOnes()); } + } // namespace SDPatternMatch } // namespace llvm #endif diff --git a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp index 1967a62bbf9d1..a7112cfac63de 100644 --- a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp +++ b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp @@ -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);