xref: /llvm-project/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp (revision bacfdcd7e0989117a3c76b040fe9efe093fa8708)
15874874cSMin-Yih Hsu //===---- llvm/unittest/CodeGen/SelectionDAGPatternMatchTest.cpp  ---------===//
25874874cSMin-Yih Hsu //
35874874cSMin-Yih Hsu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45874874cSMin-Yih Hsu // See https://llvm.org/LICENSE.txt for license information.
55874874cSMin-Yih Hsu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65874874cSMin-Yih Hsu //
75874874cSMin-Yih Hsu //===----------------------------------------------------------------------===//
85874874cSMin-Yih Hsu 
95874874cSMin-Yih Hsu #include "llvm/Analysis/OptimizationRemarkEmitter.h"
105874874cSMin-Yih Hsu #include "llvm/AsmParser/Parser.h"
115874874cSMin-Yih Hsu #include "llvm/CodeGen/MachineModuleInfo.h"
125874874cSMin-Yih Hsu #include "llvm/CodeGen/SDPatternMatch.h"
135874874cSMin-Yih Hsu #include "llvm/CodeGen/TargetLowering.h"
144169338eSNikita Popov #include "llvm/IR/Module.h"
155874874cSMin-Yih Hsu #include "llvm/MC/TargetRegistry.h"
165874874cSMin-Yih Hsu #include "llvm/Support/SourceMgr.h"
175874874cSMin-Yih Hsu #include "llvm/Support/TargetSelect.h"
185874874cSMin-Yih Hsu #include "llvm/Target/TargetMachine.h"
195874874cSMin-Yih Hsu #include "gtest/gtest.h"
205874874cSMin-Yih Hsu 
215874874cSMin-Yih Hsu using namespace llvm;
225874874cSMin-Yih Hsu 
235874874cSMin-Yih Hsu class SelectionDAGPatternMatchTest : public testing::Test {
245874874cSMin-Yih Hsu protected:
255874874cSMin-Yih Hsu   static void SetUpTestCase() {
265874874cSMin-Yih Hsu     InitializeAllTargets();
275874874cSMin-Yih Hsu     InitializeAllTargetMCs();
285874874cSMin-Yih Hsu   }
295874874cSMin-Yih Hsu 
305874874cSMin-Yih Hsu   void SetUp() override {
315874874cSMin-Yih Hsu     StringRef Assembly = "@g = global i32 0\n"
325874874cSMin-Yih Hsu                          "@g_alias = alias i32, i32* @g\n"
335874874cSMin-Yih Hsu                          "define i32 @f() {\n"
345874874cSMin-Yih Hsu                          "  %1 = load i32, i32* @g\n"
355874874cSMin-Yih Hsu                          "  ret i32 %1\n"
365874874cSMin-Yih Hsu                          "}";
375874874cSMin-Yih Hsu 
385874874cSMin-Yih Hsu     Triple TargetTriple("riscv64--");
395874874cSMin-Yih Hsu     std::string Error;
405874874cSMin-Yih Hsu     const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
415874874cSMin-Yih Hsu     // FIXME: These tests do not depend on RISCV specifically, but we have to
425874874cSMin-Yih Hsu     // initialize a target. A skeleton Target for unittests would allow us to
435874874cSMin-Yih Hsu     // always run these tests.
445874874cSMin-Yih Hsu     if (!T)
455874874cSMin-Yih Hsu       GTEST_SKIP();
465874874cSMin-Yih Hsu 
475874874cSMin-Yih Hsu     TargetOptions Options;
48bb3f5e1fSMatin Raayai     TM = std::unique_ptr<TargetMachine>(T->createTargetMachine(
49bb3f5e1fSMatin Raayai         "riscv64", "", "+m,+f,+d,+v", Options, std::nullopt, std::nullopt,
50bb3f5e1fSMatin Raayai         CodeGenOptLevel::Aggressive));
515874874cSMin-Yih Hsu     if (!TM)
525874874cSMin-Yih Hsu       GTEST_SKIP();
535874874cSMin-Yih Hsu 
545874874cSMin-Yih Hsu     SMDiagnostic SMError;
555874874cSMin-Yih Hsu     M = parseAssemblyString(Assembly, SMError, Context);
565874874cSMin-Yih Hsu     if (!M)
575874874cSMin-Yih Hsu       report_fatal_error(SMError.getMessage());
585874874cSMin-Yih Hsu     M->setDataLayout(TM->createDataLayout());
595874874cSMin-Yih Hsu 
605874874cSMin-Yih Hsu     F = M->getFunction("f");
615874874cSMin-Yih Hsu     if (!F)
625874874cSMin-Yih Hsu       report_fatal_error("F?");
635874874cSMin-Yih Hsu     G = M->getGlobalVariable("g");
645874874cSMin-Yih Hsu     if (!G)
655874874cSMin-Yih Hsu       report_fatal_error("G?");
665874874cSMin-Yih Hsu     AliasedG = M->getNamedAlias("g_alias");
675874874cSMin-Yih Hsu     if (!AliasedG)
685874874cSMin-Yih Hsu       report_fatal_error("AliasedG?");
695874874cSMin-Yih Hsu 
705874874cSMin-Yih Hsu     MachineModuleInfo MMI(TM.get());
715874874cSMin-Yih Hsu 
725874874cSMin-Yih Hsu     MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F),
7363e16478SMatt Arsenault                                            MMI.getContext(), 0);
745874874cSMin-Yih Hsu 
755874874cSMin-Yih Hsu     DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None);
765874874cSMin-Yih Hsu     if (!DAG)
775874874cSMin-Yih Hsu       report_fatal_error("DAG?");
785874874cSMin-Yih Hsu     OptimizationRemarkEmitter ORE(F);
79455990d1SVitaly Buka     DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, MMI,
80455990d1SVitaly Buka               nullptr);
815874874cSMin-Yih Hsu   }
825874874cSMin-Yih Hsu 
835874874cSMin-Yih Hsu   TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) {
845874874cSMin-Yih Hsu     return DAG->getTargetLoweringInfo().getTypeAction(Context, VT);
855874874cSMin-Yih Hsu   }
865874874cSMin-Yih Hsu 
875874874cSMin-Yih Hsu   EVT getTypeToTransformTo(EVT VT) {
885874874cSMin-Yih Hsu     return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT);
895874874cSMin-Yih Hsu   }
905874874cSMin-Yih Hsu 
915874874cSMin-Yih Hsu   LLVMContext Context;
92bb3f5e1fSMatin Raayai   std::unique_ptr<TargetMachine> TM;
935874874cSMin-Yih Hsu   std::unique_ptr<Module> M;
945874874cSMin-Yih Hsu   Function *F;
955874874cSMin-Yih Hsu   GlobalVariable *G;
965874874cSMin-Yih Hsu   GlobalAlias *AliasedG;
975874874cSMin-Yih Hsu   std::unique_ptr<MachineFunction> MF;
985874874cSMin-Yih Hsu   std::unique_ptr<SelectionDAG> DAG;
995874874cSMin-Yih Hsu };
1005874874cSMin-Yih Hsu 
1015874874cSMin-Yih Hsu TEST_F(SelectionDAGPatternMatchTest, matchValueType) {
1025874874cSMin-Yih Hsu   SDLoc DL;
1035874874cSMin-Yih Hsu   auto Int32VT = EVT::getIntegerVT(Context, 32);
1045874874cSMin-Yih Hsu   auto Float32VT = EVT::getFloatingPointVT(32);
1055874874cSMin-Yih Hsu   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
1065874874cSMin-Yih Hsu 
1075874874cSMin-Yih Hsu   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
1085874874cSMin-Yih Hsu   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Float32VT);
1095874874cSMin-Yih Hsu   SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);
1105874874cSMin-Yih Hsu 
1115874874cSMin-Yih Hsu   using namespace SDPatternMatch;
1125874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Op0, m_SpecificVT(Int32VT)));
1135874874cSMin-Yih Hsu   EVT BindVT;
1145874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Op1, m_VT(BindVT)));
1155874874cSMin-Yih Hsu   EXPECT_EQ(BindVT, Float32VT);
1165874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Op0, m_IntegerVT()));
1175874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Op1, m_FloatingPointVT()));
1185874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Op2, m_VectorVT()));
1195874874cSMin-Yih Hsu   EXPECT_FALSE(sd_match(Op2, m_ScalableVectorVT()));
1205874874cSMin-Yih Hsu }
1215874874cSMin-Yih Hsu 
122f3bc8c34SAidan Goldfarb TEST_F(SelectionDAGPatternMatchTest, matchVecShuffle) {
123f3bc8c34SAidan Goldfarb   SDLoc DL;
124f3bc8c34SAidan Goldfarb   auto Int32VT = EVT::getIntegerVT(Context, 32);
125f3bc8c34SAidan Goldfarb   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
126f3bc8c34SAidan Goldfarb   const std::array<int, 4> MaskData = {2, 0, 3, 1};
127f3bc8c34SAidan Goldfarb   const std::array<int, 4> OtherMaskData = {1, 2, 3, 4};
128f3bc8c34SAidan Goldfarb   ArrayRef<int> Mask;
129f3bc8c34SAidan Goldfarb 
130f3bc8c34SAidan Goldfarb   SDValue V0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, VInt32VT);
131f3bc8c34SAidan Goldfarb   SDValue V1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);
132f3bc8c34SAidan Goldfarb   SDValue VecShuffleWithMask =
133f3bc8c34SAidan Goldfarb       DAG->getVectorShuffle(VInt32VT, DL, V0, V1, MaskData);
134f3bc8c34SAidan Goldfarb 
135f3bc8c34SAidan Goldfarb   using namespace SDPatternMatch;
136f3bc8c34SAidan Goldfarb   EXPECT_TRUE(sd_match(VecShuffleWithMask, m_Shuffle(m_Value(), m_Value())));
137f3bc8c34SAidan Goldfarb   EXPECT_TRUE(sd_match(VecShuffleWithMask,
138f3bc8c34SAidan Goldfarb                        m_Shuffle(m_Value(), m_Value(), m_Mask(Mask))));
139f3bc8c34SAidan Goldfarb   EXPECT_TRUE(
140f3bc8c34SAidan Goldfarb       sd_match(VecShuffleWithMask,
141f3bc8c34SAidan Goldfarb                m_Shuffle(m_Value(), m_Value(), m_SpecificMask(MaskData))));
142f3bc8c34SAidan Goldfarb   EXPECT_FALSE(
143f3bc8c34SAidan Goldfarb       sd_match(VecShuffleWithMask,
144f3bc8c34SAidan Goldfarb                m_Shuffle(m_Value(), m_Value(), m_SpecificMask(OtherMaskData))));
145f3bc8c34SAidan Goldfarb   EXPECT_TRUE(
146f3bc8c34SAidan Goldfarb       std::equal(MaskData.begin(), MaskData.end(), Mask.begin(), Mask.end()));
147f3bc8c34SAidan Goldfarb }
148f3bc8c34SAidan Goldfarb 
14961a4e1e7SSimon Pilgrim TEST_F(SelectionDAGPatternMatchTest, matchTernaryOp) {
15061a4e1e7SSimon Pilgrim   SDLoc DL;
15161a4e1e7SSimon Pilgrim   auto Int32VT = EVT::getIntegerVT(Context, 32);
15261a4e1e7SSimon Pilgrim 
15361a4e1e7SSimon Pilgrim   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
15461a4e1e7SSimon Pilgrim   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
155ecdf0dacSChris White   SDValue Op3 = DAG->getConstant(1, DL, Int32VT);
15661a4e1e7SSimon Pilgrim 
15761a4e1e7SSimon Pilgrim   SDValue ICMP_UGT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGT);
15861a4e1e7SSimon Pilgrim   SDValue ICMP_EQ01 = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETEQ);
15961a4e1e7SSimon Pilgrim   SDValue ICMP_EQ10 = DAG->getSetCC(DL, MVT::i1, Op1, Op0, ISD::SETEQ);
16061a4e1e7SSimon Pilgrim 
161862d837eSMichael Maitland   auto Int1VT = EVT::getIntegerVT(Context, 1);
162862d837eSMichael Maitland   SDValue Cond = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int1VT);
163862d837eSMichael Maitland   SDValue T = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 4, Int1VT);
164862d837eSMichael Maitland   SDValue F = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 5, Int1VT);
165862d837eSMichael Maitland   SDValue Select = DAG->getSelect(DL, MVT::i1, Cond, T, F);
166862d837eSMichael Maitland 
1670dd1128dSMichael Maitland   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
168c1c50c7aSThor Preimesberger   auto SmallVInt32VT = EVT::getVectorVT(Context, Int32VT, 2);
169c1c50c7aSThor Preimesberger   auto Idx0 = DAG->getVectorIdxConstant(0, DL);
170c1c50c7aSThor Preimesberger   auto Idx3 = DAG->getVectorIdxConstant(3, DL);
1710dd1128dSMichael Maitland   SDValue V1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 6, VInt32VT);
1720dd1128dSMichael Maitland   SDValue V2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 7, VInt32VT);
173c1c50c7aSThor Preimesberger   SDValue V3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 8, SmallVInt32VT);
1740dd1128dSMichael Maitland   SDValue VSelect = DAG->getNode(ISD::VSELECT, DL, VInt32VT, Cond, V1, V2);
175c1c50c7aSThor Preimesberger   SDValue InsertSubvector =
176c1c50c7aSThor Preimesberger       DAG->getNode(ISD::INSERT_SUBVECTOR, DL, VInt32VT, V2, V3, Idx0);
1770dd1128dSMichael Maitland 
178ecdf0dacSChris White   SDValue ExtractELT =
179ecdf0dacSChris White       DAG->getNode(ISD::EXTRACT_VECTOR_ELT, DL, Int32VT, V1, Op3);
180ecdf0dacSChris White 
18161a4e1e7SSimon Pilgrim   using namespace SDPatternMatch;
18261a4e1e7SSimon Pilgrim   ISD::CondCode CC;
18361a4e1e7SSimon Pilgrim   EXPECT_TRUE(sd_match(ICMP_UGT, m_SetCC(m_Value(), m_Value(),
18461a4e1e7SSimon Pilgrim                                          m_SpecificCondCode(ISD::SETUGT))));
18561a4e1e7SSimon Pilgrim   EXPECT_TRUE(
18661a4e1e7SSimon Pilgrim       sd_match(ICMP_UGT, m_SetCC(m_Value(), m_Value(), m_CondCode(CC))));
18761a4e1e7SSimon Pilgrim   EXPECT_TRUE(CC == ISD::SETUGT);
18861a4e1e7SSimon Pilgrim   EXPECT_FALSE(sd_match(
18961a4e1e7SSimon Pilgrim       ICMP_UGT, m_SetCC(m_Value(), m_Value(), m_SpecificCondCode(ISD::SETLE))));
19061a4e1e7SSimon Pilgrim 
19161a4e1e7SSimon Pilgrim   EXPECT_TRUE(sd_match(ICMP_EQ01, m_SetCC(m_Specific(Op0), m_Specific(Op1),
19261a4e1e7SSimon Pilgrim                                           m_SpecificCondCode(ISD::SETEQ))));
19361a4e1e7SSimon Pilgrim   EXPECT_TRUE(sd_match(ICMP_EQ10, m_SetCC(m_Specific(Op1), m_Specific(Op0),
19461a4e1e7SSimon Pilgrim                                           m_SpecificCondCode(ISD::SETEQ))));
19561a4e1e7SSimon Pilgrim   EXPECT_FALSE(sd_match(ICMP_EQ01, m_SetCC(m_Specific(Op1), m_Specific(Op0),
19661a4e1e7SSimon Pilgrim                                            m_SpecificCondCode(ISD::SETEQ))));
19761a4e1e7SSimon Pilgrim   EXPECT_FALSE(sd_match(ICMP_EQ10, m_SetCC(m_Specific(Op0), m_Specific(Op1),
19861a4e1e7SSimon Pilgrim                                            m_SpecificCondCode(ISD::SETEQ))));
19961a4e1e7SSimon Pilgrim   EXPECT_TRUE(sd_match(ICMP_EQ01, m_c_SetCC(m_Specific(Op1), m_Specific(Op0),
20061a4e1e7SSimon Pilgrim                                             m_SpecificCondCode(ISD::SETEQ))));
20161a4e1e7SSimon Pilgrim   EXPECT_TRUE(sd_match(ICMP_EQ10, m_c_SetCC(m_Specific(Op0), m_Specific(Op1),
20261a4e1e7SSimon Pilgrim                                             m_SpecificCondCode(ISD::SETEQ))));
203862d837eSMichael Maitland 
204862d837eSMichael Maitland   EXPECT_TRUE(sd_match(
205862d837eSMichael Maitland       Select, m_Select(m_Specific(Cond), m_Specific(T), m_Specific(F))));
206862d837eSMichael Maitland   EXPECT_FALSE(sd_match(
207862d837eSMichael Maitland       Select, m_Select(m_Specific(Cond), m_Specific(F), m_Specific(T))));
208862d837eSMichael Maitland   EXPECT_FALSE(sd_match(ICMP_EQ01, m_Select(m_Specific(Op0), m_Specific(Op1),
209862d837eSMichael Maitland                                             m_SpecificCondCode(ISD::SETEQ))));
2100dd1128dSMichael Maitland   EXPECT_TRUE(sd_match(
2110dd1128dSMichael Maitland       VSelect, m_VSelect(m_Specific(Cond), m_Specific(V1), m_Specific(V2))));
2120dd1128dSMichael Maitland   EXPECT_FALSE(sd_match(
2130dd1128dSMichael Maitland       Select, m_VSelect(m_Specific(Cond), m_Specific(V1), m_Specific(V2))));
214ecdf0dacSChris White 
215ecdf0dacSChris White   EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_Value())));
216ecdf0dacSChris White   EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_ConstInt())));
217ecdf0dacSChris White   EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_SpecificInt(1))));
218c1c50c7aSThor Preimesberger 
219c1c50c7aSThor Preimesberger   EXPECT_TRUE(sd_match(InsertSubvector,
220c1c50c7aSThor Preimesberger                        m_InsertSubvector(m_Value(), m_Value(), m_Value())));
221c1c50c7aSThor Preimesberger   EXPECT_TRUE(sd_match(
222c1c50c7aSThor Preimesberger       InsertSubvector,
223c1c50c7aSThor Preimesberger       m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_Specific(Idx0))));
224c1c50c7aSThor Preimesberger   EXPECT_TRUE(sd_match(
225c1c50c7aSThor Preimesberger       InsertSubvector,
226c1c50c7aSThor Preimesberger       m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_SpecificInt(0))));
227c1c50c7aSThor Preimesberger   EXPECT_FALSE(sd_match(
228c1c50c7aSThor Preimesberger       InsertSubvector,
229c1c50c7aSThor Preimesberger       m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_Specific(Idx3))));
230c1c50c7aSThor Preimesberger   EXPECT_FALSE(sd_match(
231c1c50c7aSThor Preimesberger       InsertSubvector,
232c1c50c7aSThor Preimesberger       m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_SpecificInt(3))));
23361a4e1e7SSimon Pilgrim }
23461a4e1e7SSimon Pilgrim 
2355874874cSMin-Yih Hsu TEST_F(SelectionDAGPatternMatchTest, matchBinaryOp) {
2365874874cSMin-Yih Hsu   SDLoc DL;
2375874874cSMin-Yih Hsu   auto Int32VT = EVT::getIntegerVT(Context, 32);
2385874874cSMin-Yih Hsu   auto Float32VT = EVT::getFloatingPointVT(32);
239c1c50c7aSThor Preimesberger   auto BigVInt32VT = EVT::getVectorVT(Context, Int32VT, 8);
240ecdf0dacSChris White   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
241ecdf0dacSChris White 
242ecdf0dacSChris White   SDValue V1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 6, VInt32VT);
243c1c50c7aSThor Preimesberger   auto Idx0 = DAG->getVectorIdxConstant(0, DL);
244c1c50c7aSThor Preimesberger   auto Idx1 = DAG->getVectorIdxConstant(1, DL);
2455874874cSMin-Yih Hsu 
2465874874cSMin-Yih Hsu   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
2475874874cSMin-Yih Hsu   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
2485874874cSMin-Yih Hsu   SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Float32VT);
24970f3863bSNoah Goldstein   SDValue Op3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 8, Int32VT);
250ecdf0dacSChris White   SDValue Op4 = DAG->getConstant(1, DL, Int32VT);
2515874874cSMin-Yih Hsu 
2525874874cSMin-Yih Hsu   SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);
2535874874cSMin-Yih Hsu   SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Add, Op0);
2545874874cSMin-Yih Hsu   SDValue Mul = DAG->getNode(ISD::MUL, DL, Int32VT, Add, Sub);
255560d7c51SSimon Pilgrim   SDValue And = DAG->getNode(ISD::AND, DL, Int32VT, Op0, Op1);
256560d7c51SSimon Pilgrim   SDValue Xor = DAG->getNode(ISD::XOR, DL, Int32VT, Op1, Op0);
257560d7c51SSimon Pilgrim   SDValue Or  = DAG->getNode(ISD::OR, DL, Int32VT, Op0, Op1);
258cf9d1c14SYingwei Zheng   SDValue DisOr =
259cf9d1c14SYingwei Zheng       DAG->getNode(ISD::OR, DL, Int32VT, Op0, Op3, SDNodeFlags::Disjoint);
260c9c23261SSimon Pilgrim   SDValue SMax = DAG->getNode(ISD::SMAX, DL, Int32VT, Op0, Op1);
261c9c23261SSimon Pilgrim   SDValue SMin = DAG->getNode(ISD::SMIN, DL, Int32VT, Op1, Op0);
262c9c23261SSimon Pilgrim   SDValue UMax = DAG->getNode(ISD::UMAX, DL, Int32VT, Op0, Op1);
263c9c23261SSimon Pilgrim   SDValue UMin = DAG->getNode(ISD::UMIN, DL, Int32VT, Op1, Op0);
26449fa91edSSimon Pilgrim   SDValue Rotl = DAG->getNode(ISD::ROTL, DL, Int32VT, Op0, Op1);
26549fa91edSSimon Pilgrim   SDValue Rotr = DAG->getNode(ISD::ROTR, DL, Int32VT, Op1, Op0);
2665874874cSMin-Yih Hsu 
267854ded9bSc8ef   SDValue ICMP_GT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETGT);
268854ded9bSc8ef   SDValue ICMP_GE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETGE);
269854ded9bSc8ef   SDValue ICMP_UGT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGT);
270854ded9bSc8ef   SDValue ICMP_UGE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGE);
271854ded9bSc8ef   SDValue ICMP_LT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETLT);
272854ded9bSc8ef   SDValue ICMP_LE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETLE);
273854ded9bSc8ef   SDValue ICMP_ULT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETULT);
274854ded9bSc8ef   SDValue ICMP_ULE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETULE);
275854ded9bSc8ef   SDValue SMaxLikeGT = DAG->getSelect(DL, MVT::i32, ICMP_GT, Op0, Op1);
276854ded9bSc8ef   SDValue SMaxLikeGE = DAG->getSelect(DL, MVT::i32, ICMP_GE, Op0, Op1);
277854ded9bSc8ef   SDValue UMaxLikeUGT = DAG->getSelect(DL, MVT::i32, ICMP_UGT, Op0, Op1);
278854ded9bSc8ef   SDValue UMaxLikeUGE = DAG->getSelect(DL, MVT::i32, ICMP_UGE, Op0, Op1);
279854ded9bSc8ef   SDValue SMinLikeLT = DAG->getSelect(DL, MVT::i32, ICMP_LT, Op0, Op1);
280854ded9bSc8ef   SDValue SMinLikeLE = DAG->getSelect(DL, MVT::i32, ICMP_LE, Op0, Op1);
281854ded9bSc8ef   SDValue UMinLikeULT = DAG->getSelect(DL, MVT::i32, ICMP_ULT, Op0, Op1);
282854ded9bSc8ef   SDValue UMinLikeULE = DAG->getSelect(DL, MVT::i32, ICMP_ULE, Op0, Op1);
283854ded9bSc8ef 
2845874874cSMin-Yih Hsu   SDValue SFAdd = DAG->getNode(ISD::STRICT_FADD, DL, {Float32VT, MVT::Other},
2855874874cSMin-Yih Hsu                                {DAG->getEntryNode(), Op2, Op2});
2865874874cSMin-Yih Hsu 
287c1c50c7aSThor Preimesberger   SDValue Vec = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 9, BigVInt32VT);
288c1c50c7aSThor Preimesberger   SDValue SubVec =
289c1c50c7aSThor Preimesberger       DAG->getNode(ISD::EXTRACT_SUBVECTOR, DL, VInt32VT, Vec, Idx0);
290c1c50c7aSThor Preimesberger 
291ecdf0dacSChris White   SDValue InsertELT =
292ecdf0dacSChris White       DAG->getNode(ISD::INSERT_VECTOR_ELT, DL, VInt32VT, V1, Op0, Op4);
293ecdf0dacSChris White 
2945874874cSMin-Yih Hsu   using namespace SDPatternMatch;
2955874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Sub, m_BinOp(ISD::SUB, m_Value(), m_Value())));
2965874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Sub, m_Sub(m_Value(), m_Value())));
2975874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Add, m_c_BinOp(ISD::ADD, m_Value(), m_Value())));
2985874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Add, m_Add(m_Value(), m_Value())));
29970f3863bSNoah Goldstein   EXPECT_TRUE(sd_match(Add, m_AddLike(m_Value(), m_Value())));
3005874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(
3015874874cSMin-Yih Hsu       Mul, m_Mul(m_OneUse(m_Opc(ISD::SUB)), m_NUses<2>(m_Specific(Add)))));
3025874874cSMin-Yih Hsu   EXPECT_TRUE(
3035874874cSMin-Yih Hsu       sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_SpecificVT(Float32VT),
3045874874cSMin-Yih Hsu                                      m_SpecificVT(Float32VT))));
305560d7c51SSimon Pilgrim 
306560d7c51SSimon Pilgrim   EXPECT_TRUE(sd_match(And, m_c_BinOp(ISD::AND, m_Value(), m_Value())));
307560d7c51SSimon Pilgrim   EXPECT_TRUE(sd_match(And, m_And(m_Value(), m_Value())));
308560d7c51SSimon Pilgrim   EXPECT_TRUE(sd_match(Xor, m_c_BinOp(ISD::XOR, m_Value(), m_Value())));
309560d7c51SSimon Pilgrim   EXPECT_TRUE(sd_match(Xor, m_Xor(m_Value(), m_Value())));
310560d7c51SSimon Pilgrim   EXPECT_TRUE(sd_match(Or, m_c_BinOp(ISD::OR, m_Value(), m_Value())));
311560d7c51SSimon Pilgrim   EXPECT_TRUE(sd_match(Or, m_Or(m_Value(), m_Value())));
31270f3863bSNoah Goldstein   EXPECT_FALSE(sd_match(Or, m_DisjointOr(m_Value(), m_Value())));
31370f3863bSNoah Goldstein 
31470f3863bSNoah Goldstein   EXPECT_TRUE(sd_match(DisOr, m_Or(m_Value(), m_Value())));
31570f3863bSNoah Goldstein   EXPECT_TRUE(sd_match(DisOr, m_DisjointOr(m_Value(), m_Value())));
31670f3863bSNoah Goldstein   EXPECT_FALSE(sd_match(DisOr, m_Add(m_Value(), m_Value())));
31770f3863bSNoah Goldstein   EXPECT_TRUE(sd_match(DisOr, m_AddLike(m_Value(), m_Value())));
318560d7c51SSimon Pilgrim 
31949fa91edSSimon Pilgrim   EXPECT_TRUE(sd_match(Rotl, m_Rotl(m_Value(), m_Value())));
32049fa91edSSimon Pilgrim   EXPECT_TRUE(sd_match(Rotr, m_Rotr(m_Value(), m_Value())));
32149fa91edSSimon Pilgrim   EXPECT_FALSE(sd_match(Rotl, m_Rotr(m_Value(), m_Value())));
32249fa91edSSimon Pilgrim   EXPECT_FALSE(sd_match(Rotr, m_Rotl(m_Value(), m_Value())));
32349fa91edSSimon Pilgrim 
324c9c23261SSimon Pilgrim   EXPECT_TRUE(sd_match(SMax, m_c_BinOp(ISD::SMAX, m_Value(), m_Value())));
325c9c23261SSimon Pilgrim   EXPECT_TRUE(sd_match(SMax, m_SMax(m_Value(), m_Value())));
326854ded9bSc8ef   EXPECT_TRUE(sd_match(SMax, m_SMaxLike(m_Value(), m_Value())));
327854ded9bSc8ef   EXPECT_TRUE(sd_match(SMaxLikeGT, m_SMaxLike(m_Value(), m_Value())));
328854ded9bSc8ef   EXPECT_TRUE(sd_match(SMaxLikeGE, m_SMaxLike(m_Value(), m_Value())));
329c9c23261SSimon Pilgrim   EXPECT_TRUE(sd_match(SMin, m_c_BinOp(ISD::SMIN, m_Value(), m_Value())));
330c9c23261SSimon Pilgrim   EXPECT_TRUE(sd_match(SMin, m_SMin(m_Value(), m_Value())));
331854ded9bSc8ef   EXPECT_TRUE(sd_match(SMin, m_SMinLike(m_Value(), m_Value())));
332854ded9bSc8ef   EXPECT_TRUE(sd_match(SMinLikeLT, m_SMinLike(m_Value(), m_Value())));
333854ded9bSc8ef   EXPECT_TRUE(sd_match(SMinLikeLE, m_SMinLike(m_Value(), m_Value())));
334c9c23261SSimon Pilgrim   EXPECT_TRUE(sd_match(UMax, m_c_BinOp(ISD::UMAX, m_Value(), m_Value())));
335c9c23261SSimon Pilgrim   EXPECT_TRUE(sd_match(UMax, m_UMax(m_Value(), m_Value())));
336854ded9bSc8ef   EXPECT_TRUE(sd_match(UMax, m_UMaxLike(m_Value(), m_Value())));
337854ded9bSc8ef   EXPECT_TRUE(sd_match(UMaxLikeUGT, m_UMaxLike(m_Value(), m_Value())));
338854ded9bSc8ef   EXPECT_TRUE(sd_match(UMaxLikeUGE, m_UMaxLike(m_Value(), m_Value())));
339c9c23261SSimon Pilgrim   EXPECT_TRUE(sd_match(UMin, m_c_BinOp(ISD::UMIN, m_Value(), m_Value())));
340c9c23261SSimon Pilgrim   EXPECT_TRUE(sd_match(UMin, m_UMin(m_Value(), m_Value())));
341854ded9bSc8ef   EXPECT_TRUE(sd_match(UMin, m_UMinLike(m_Value(), m_Value())));
342854ded9bSc8ef   EXPECT_TRUE(sd_match(UMinLikeULT, m_UMinLike(m_Value(), m_Value())));
343854ded9bSc8ef   EXPECT_TRUE(sd_match(UMinLikeULE, m_UMinLike(m_Value(), m_Value())));
344c9c23261SSimon Pilgrim 
3455874874cSMin-Yih Hsu   SDValue BindVal;
3465874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_Value(BindVal),
3475874874cSMin-Yih Hsu                                              m_Deferred(BindVal))));
3485874874cSMin-Yih Hsu   EXPECT_FALSE(sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_OtherVT(),
3495874874cSMin-Yih Hsu                                               m_SpecificVT(Float32VT))));
350ecdf0dacSChris White 
351c1c50c7aSThor Preimesberger   EXPECT_TRUE(sd_match(SubVec, m_ExtractSubvector(m_Value(), m_Value())));
352c1c50c7aSThor Preimesberger   EXPECT_TRUE(
353c1c50c7aSThor Preimesberger       sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_Specific(Idx0))));
354c1c50c7aSThor Preimesberger   EXPECT_TRUE(
355c1c50c7aSThor Preimesberger       sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_SpecificInt(0))));
356c1c50c7aSThor Preimesberger   EXPECT_FALSE(
357c1c50c7aSThor Preimesberger       sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_Specific(Idx1))));
358c1c50c7aSThor Preimesberger   EXPECT_FALSE(
359c1c50c7aSThor Preimesberger       sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_SpecificInt(1))));
360c1c50c7aSThor Preimesberger 
361ecdf0dacSChris White   EXPECT_TRUE(
362ecdf0dacSChris White       sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_Value())));
363ecdf0dacSChris White   EXPECT_TRUE(
364ecdf0dacSChris White       sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_ConstInt())));
365ecdf0dacSChris White   EXPECT_TRUE(
366ecdf0dacSChris White       sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_SpecificInt(1))));
3675874874cSMin-Yih Hsu }
3685874874cSMin-Yih Hsu 
3695874874cSMin-Yih Hsu TEST_F(SelectionDAGPatternMatchTest, matchUnaryOp) {
3705874874cSMin-Yih Hsu   SDLoc DL;
3715874874cSMin-Yih Hsu   auto Int32VT = EVT::getIntegerVT(Context, 32);
3725874874cSMin-Yih Hsu   auto Int64VT = EVT::getIntegerVT(Context, 64);
37305dfac23SJorge Botto   auto FloatVT = EVT::getFloatingPointVT(32);
3745874874cSMin-Yih Hsu 
3755874874cSMin-Yih Hsu   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
3765874874cSMin-Yih Hsu   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);
37705dfac23SJorge Botto   SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, FloatVT);
37870f3863bSNoah Goldstein   SDValue Op3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int32VT);
3795874874cSMin-Yih Hsu 
3805874874cSMin-Yih Hsu   SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op0);
38170f3863bSNoah Goldstein   SDValue ZExtNNeg =
382cf9d1c14SYingwei Zheng       DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op3, SDNodeFlags::NonNeg);
3835874874cSMin-Yih Hsu   SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op0);
3845874874cSMin-Yih Hsu   SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op1);
3855874874cSMin-Yih Hsu 
386bc70f604Szicwangupa   SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Trunc, Op0);
387bc70f604Szicwangupa   SDValue Neg = DAG->getNegative(Op0, DL, Int32VT);
388bc70f604Szicwangupa   SDValue Not = DAG->getNOT(DL, Op0, Int32VT);
389bc70f604Szicwangupa 
390ad778889SMichael Maitland   SDValue VScale = DAG->getVScale(DL, Int32VT, APInt::getMaxValue(32));
391ad778889SMichael Maitland 
39205dfac23SJorge Botto   SDValue FPToSI = DAG->getNode(ISD::FP_TO_SINT, DL, FloatVT, Op2);
39305dfac23SJorge Botto   SDValue FPToUI = DAG->getNode(ISD::FP_TO_UINT, DL, FloatVT, Op2);
39405dfac23SJorge Botto 
395*bacfdcd7SSimon Pilgrim   SDValue Bcast = DAG->getNode(ISD::BITCAST, DL, FloatVT, Op0);
396d3d2d725SSimon Pilgrim   SDValue Brev = DAG->getNode(ISD::BITREVERSE, DL, Int32VT, Op0);
397d3d2d725SSimon Pilgrim   SDValue Bswap = DAG->getNode(ISD::BSWAP, DL, Int32VT, Op0);
398d3d2d725SSimon Pilgrim 
399d3d2d725SSimon Pilgrim   SDValue Ctpop = DAG->getNode(ISD::CTPOP, DL, Int32VT, Op0);
4008837898bSRobert Dazi   SDValue Ctlz = DAG->getNode(ISD::CTLZ, DL, Int32VT, Op0);
401d3d2d725SSimon Pilgrim   SDValue Cttz = DAG->getNode(ISD::CTTZ, DL, Int32VT, Op0);
4028837898bSRobert Dazi 
4035874874cSMin-Yih Hsu   using namespace SDPatternMatch;
4045874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(ZExt, m_UnaryOp(ISD::ZERO_EXTEND, m_Value())));
4055874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(SExt, m_SExt(m_Value())));
40670f3863bSNoah Goldstein   EXPECT_TRUE(sd_match(SExt, m_SExtLike(m_Value())));
40770f3863bSNoah Goldstein   ASSERT_TRUE(ZExtNNeg->getFlags().hasNonNeg());
40870f3863bSNoah Goldstein   EXPECT_FALSE(sd_match(ZExtNNeg, m_SExt(m_Value())));
40970f3863bSNoah Goldstein   EXPECT_TRUE(sd_match(ZExtNNeg, m_NNegZExt(m_Value())));
41070f3863bSNoah Goldstein   EXPECT_FALSE(sd_match(ZExt, m_NNegZExt(m_Value())));
41170f3863bSNoah Goldstein   EXPECT_TRUE(sd_match(ZExtNNeg, m_SExtLike(m_Value())));
41270f3863bSNoah Goldstein   EXPECT_FALSE(sd_match(ZExt, m_SExtLike(m_Value())));
4135874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Trunc, m_Trunc(m_Specific(Op1))));
414bc70f604Szicwangupa 
415bc70f604Szicwangupa   EXPECT_TRUE(sd_match(Neg, m_Neg(m_Value())));
416bc70f604Szicwangupa   EXPECT_TRUE(sd_match(Not, m_Not(m_Value())));
417bc70f604Szicwangupa   EXPECT_FALSE(sd_match(ZExt, m_Neg(m_Value())));
418bc70f604Szicwangupa   EXPECT_FALSE(sd_match(Sub, m_Neg(m_Value())));
419bc70f604Szicwangupa   EXPECT_FALSE(sd_match(Neg, m_Not(m_Value())));
420ad778889SMichael Maitland   EXPECT_TRUE(sd_match(VScale, m_VScale(m_Value())));
42105dfac23SJorge Botto 
42205dfac23SJorge Botto   EXPECT_TRUE(sd_match(FPToUI, m_FPToUI(m_Value())));
42305dfac23SJorge Botto   EXPECT_TRUE(sd_match(FPToSI, m_FPToSI(m_Value())));
42405dfac23SJorge Botto   EXPECT_FALSE(sd_match(FPToUI, m_FPToSI(m_Value())));
42505dfac23SJorge Botto   EXPECT_FALSE(sd_match(FPToSI, m_FPToUI(m_Value())));
4268837898bSRobert Dazi 
427*bacfdcd7SSimon Pilgrim   EXPECT_TRUE(sd_match(Bcast, m_BitCast(m_Value())));
428*bacfdcd7SSimon Pilgrim   EXPECT_TRUE(sd_match(Bcast, m_BitCast(m_SpecificVT(MVT::i32))));
429d3d2d725SSimon Pilgrim   EXPECT_TRUE(sd_match(Brev, m_BitReverse(m_Value())));
430d3d2d725SSimon Pilgrim   EXPECT_TRUE(sd_match(Bswap, m_BSwap(m_Value())));
431*bacfdcd7SSimon Pilgrim   EXPECT_FALSE(sd_match(Bcast, m_BitReverse(m_Value())));
432*bacfdcd7SSimon Pilgrim   EXPECT_FALSE(sd_match(Bcast, m_BitCast(m_SpecificVT(MVT::f32))));
433d3d2d725SSimon Pilgrim   EXPECT_FALSE(sd_match(Brev, m_BSwap(m_Value())));
434d3d2d725SSimon Pilgrim   EXPECT_FALSE(sd_match(Bswap, m_BitReverse(m_Value())));
435d3d2d725SSimon Pilgrim 
436d3d2d725SSimon Pilgrim   EXPECT_TRUE(sd_match(Ctpop, m_Ctpop(m_Value())));
4378837898bSRobert Dazi   EXPECT_TRUE(sd_match(Ctlz, m_Ctlz(m_Value())));
438d3d2d725SSimon Pilgrim   EXPECT_TRUE(sd_match(Cttz, m_Cttz(m_Value())));
439d3d2d725SSimon Pilgrim   EXPECT_FALSE(sd_match(Ctpop, m_Ctlz(m_Value())));
440d3d2d725SSimon Pilgrim   EXPECT_FALSE(sd_match(Ctlz, m_Cttz(m_Value())));
441d3d2d725SSimon Pilgrim   EXPECT_FALSE(sd_match(Cttz, m_Ctlz(m_Value())));
4425874874cSMin-Yih Hsu }
4435874874cSMin-Yih Hsu 
4445874874cSMin-Yih Hsu TEST_F(SelectionDAGPatternMatchTest, matchConstants) {
4455874874cSMin-Yih Hsu   SDLoc DL;
4465874874cSMin-Yih Hsu   auto Int32VT = EVT::getIntegerVT(Context, 32);
4475874874cSMin-Yih Hsu   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
4485874874cSMin-Yih Hsu 
4495874874cSMin-Yih Hsu   SDValue Arg0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
4505874874cSMin-Yih Hsu 
4515874874cSMin-Yih Hsu   SDValue Const3 = DAG->getConstant(3, DL, Int32VT);
4525874874cSMin-Yih Hsu   SDValue Const87 = DAG->getConstant(87, DL, Int32VT);
4535874874cSMin-Yih Hsu   SDValue Splat = DAG->getSplat(VInt32VT, DL, Arg0);
4545874874cSMin-Yih Hsu   SDValue ConstSplat = DAG->getSplat(VInt32VT, DL, Const3);
4555874874cSMin-Yih Hsu   SDValue Zero = DAG->getConstant(0, DL, Int32VT);
4565874874cSMin-Yih Hsu   SDValue One = DAG->getConstant(1, DL, Int32VT);
4575874874cSMin-Yih Hsu   SDValue AllOnes = DAG->getConstant(APInt::getAllOnes(32), DL, Int32VT);
4580638e222SMin-Yih Hsu   SDValue SetCC = DAG->getSetCC(DL, Int32VT, Arg0, Const3, ISD::SETULT);
4595874874cSMin-Yih Hsu 
4605874874cSMin-Yih Hsu   using namespace SDPatternMatch;
4615874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Const87, m_ConstInt()));
4625874874cSMin-Yih Hsu   EXPECT_FALSE(sd_match(Arg0, m_ConstInt()));
4635874874cSMin-Yih Hsu   APInt ConstVal;
4645874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(ConstSplat, m_ConstInt(ConstVal)));
4655874874cSMin-Yih Hsu   EXPECT_EQ(ConstVal, 3);
4665874874cSMin-Yih Hsu   EXPECT_FALSE(sd_match(Splat, m_ConstInt()));
4675874874cSMin-Yih Hsu 
4685874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Const87, m_SpecificInt(87)));
4695874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Const3, m_SpecificInt(ConstVal)));
4705874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(AllOnes, m_AllOnes()));
4715874874cSMin-Yih Hsu 
4725874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Zero, DAG.get(), m_False()));
4735874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(One, DAG.get(), m_True()));
4745874874cSMin-Yih Hsu   EXPECT_FALSE(sd_match(AllOnes, DAG.get(), m_True()));
4750638e222SMin-Yih Hsu 
4760638e222SMin-Yih Hsu   ISD::CondCode CC;
4770638e222SMin-Yih Hsu   EXPECT_TRUE(sd_match(
4780638e222SMin-Yih Hsu       SetCC, m_Node(ISD::SETCC, m_Value(), m_Value(), m_CondCode(CC))));
4790638e222SMin-Yih Hsu   EXPECT_EQ(CC, ISD::SETULT);
4800638e222SMin-Yih Hsu   EXPECT_TRUE(sd_match(SetCC, m_Node(ISD::SETCC, m_Value(), m_Value(),
4810638e222SMin-Yih Hsu                                      m_SpecificCondCode(ISD::SETULT))));
4821d58699fSAmr Hesham 
4831d58699fSAmr Hesham   SDValue UndefInt32VT = DAG->getUNDEF(Int32VT);
4841d58699fSAmr Hesham   SDValue UndefVInt32VT = DAG->getUNDEF(VInt32VT);
4851d58699fSAmr Hesham   EXPECT_TRUE(sd_match(UndefInt32VT, m_Undef()));
4861d58699fSAmr Hesham   EXPECT_TRUE(sd_match(UndefVInt32VT, m_Undef()));
4875874874cSMin-Yih Hsu }
4885874874cSMin-Yih Hsu 
4895874874cSMin-Yih Hsu TEST_F(SelectionDAGPatternMatchTest, patternCombinators) {
4905874874cSMin-Yih Hsu   SDLoc DL;
4915874874cSMin-Yih Hsu   auto Int32VT = EVT::getIntegerVT(Context, 32);
4925874874cSMin-Yih Hsu 
4935874874cSMin-Yih Hsu   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
4945874874cSMin-Yih Hsu   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
4955874874cSMin-Yih Hsu 
4965874874cSMin-Yih Hsu   SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);
4975874874cSMin-Yih Hsu   SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Add, Op0);
4985874874cSMin-Yih Hsu 
4995874874cSMin-Yih Hsu   using namespace SDPatternMatch;
5005874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(
5015874874cSMin-Yih Hsu       Sub, m_AnyOf(m_Opc(ISD::ADD), m_Opc(ISD::SUB), m_Opc(ISD::MUL))));
5025874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Add, m_AllOf(m_Opc(ISD::ADD), m_OneUse())));
5030638e222SMin-Yih Hsu   EXPECT_TRUE(sd_match(Add, m_NoneOf(m_Opc(ISD::SUB), m_Opc(ISD::MUL))));
5045874874cSMin-Yih Hsu }
5055874874cSMin-Yih Hsu 
50617af9addSMarc Auberer TEST_F(SelectionDAGPatternMatchTest, optionalResizing) {
50717af9addSMarc Auberer   SDLoc DL;
50817af9addSMarc Auberer   auto Int32VT = EVT::getIntegerVT(Context, 32);
50917af9addSMarc Auberer   auto Int64VT = EVT::getIntegerVT(Context, 64);
51017af9addSMarc Auberer 
51117af9addSMarc Auberer   SDValue Op32 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
51217af9addSMarc Auberer   SDValue Op64 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);
51317af9addSMarc Auberer   SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op32);
51417af9addSMarc Auberer   SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op32);
51517af9addSMarc Auberer   SDValue AExt = DAG->getNode(ISD::ANY_EXTEND, DL, Int64VT, Op32);
51617af9addSMarc Auberer   SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op64);
51717af9addSMarc Auberer 
51817af9addSMarc Auberer   using namespace SDPatternMatch;
51917af9addSMarc Auberer   SDValue A;
52017af9addSMarc Auberer   EXPECT_TRUE(sd_match(Op32, m_ZExtOrSelf(m_Value(A))));
52117af9addSMarc Auberer   EXPECT_TRUE(A == Op32);
52217af9addSMarc Auberer   EXPECT_TRUE(sd_match(ZExt, m_ZExtOrSelf(m_Value(A))));
52317af9addSMarc Auberer   EXPECT_TRUE(A == Op32);
52417af9addSMarc Auberer   EXPECT_TRUE(sd_match(Op64, m_SExtOrSelf(m_Value(A))));
52517af9addSMarc Auberer   EXPECT_TRUE(A == Op64);
52617af9addSMarc Auberer   EXPECT_TRUE(sd_match(SExt, m_SExtOrSelf(m_Value(A))));
52717af9addSMarc Auberer   EXPECT_TRUE(A == Op32);
52817af9addSMarc Auberer   EXPECT_TRUE(sd_match(Op32, m_AExtOrSelf(m_Value(A))));
52917af9addSMarc Auberer   EXPECT_TRUE(A == Op32);
53017af9addSMarc Auberer   EXPECT_TRUE(sd_match(AExt, m_AExtOrSelf(m_Value(A))));
53117af9addSMarc Auberer   EXPECT_TRUE(A == Op32);
53217af9addSMarc Auberer   EXPECT_TRUE(sd_match(Op64, m_TruncOrSelf(m_Value(A))));
53317af9addSMarc Auberer   EXPECT_TRUE(A == Op64);
53417af9addSMarc Auberer   EXPECT_TRUE(sd_match(Trunc, m_TruncOrSelf(m_Value(A))));
53517af9addSMarc Auberer   EXPECT_TRUE(A == Op64);
53617af9addSMarc Auberer }
53717af9addSMarc Auberer 
5385874874cSMin-Yih Hsu TEST_F(SelectionDAGPatternMatchTest, matchNode) {
5395874874cSMin-Yih Hsu   SDLoc DL;
5405874874cSMin-Yih Hsu   auto Int32VT = EVT::getIntegerVT(Context, 32);
5415874874cSMin-Yih Hsu 
5425874874cSMin-Yih Hsu   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
5435874874cSMin-Yih Hsu   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
5445874874cSMin-Yih Hsu 
5455874874cSMin-Yih Hsu   SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);
5465874874cSMin-Yih Hsu 
5475874874cSMin-Yih Hsu   using namespace SDPatternMatch;
5485874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Add, m_Node(ISD::ADD, m_Value(), m_Value())));
5495874874cSMin-Yih Hsu   EXPECT_FALSE(sd_match(Add, m_Node(ISD::SUB, m_Value(), m_Value())));
5505874874cSMin-Yih Hsu   EXPECT_FALSE(sd_match(Add, m_Node(ISD::ADD, m_Value())));
5515874874cSMin-Yih Hsu   EXPECT_FALSE(
5525874874cSMin-Yih Hsu       sd_match(Add, m_Node(ISD::ADD, m_Value(), m_Value(), m_Value())));
5535874874cSMin-Yih Hsu   EXPECT_FALSE(sd_match(Add, m_Node(ISD::ADD, m_ConstInt(), m_Value())));
5545874874cSMin-Yih Hsu }
5555874874cSMin-Yih Hsu 
5565874874cSMin-Yih Hsu namespace {
5575874874cSMin-Yih Hsu struct VPMatchContext : public SDPatternMatch::BasicMatchContext {
5585874874cSMin-Yih Hsu   using SDPatternMatch::BasicMatchContext::BasicMatchContext;
5595874874cSMin-Yih Hsu 
5605874874cSMin-Yih Hsu   bool match(SDValue OpVal, unsigned Opc) const {
5615874874cSMin-Yih Hsu     if (!OpVal->isVPOpcode())
5625874874cSMin-Yih Hsu       return OpVal->getOpcode() == Opc;
5635874874cSMin-Yih Hsu 
5645874874cSMin-Yih Hsu     auto BaseOpc = ISD::getBaseOpcodeForVP(OpVal->getOpcode(), false);
5655874874cSMin-Yih Hsu     return BaseOpc.has_value() && *BaseOpc == Opc;
5665874874cSMin-Yih Hsu   }
567fc1b0196Sv01dXYZ 
568fc1b0196Sv01dXYZ   unsigned getNumOperands(SDValue N) const {
569fc1b0196Sv01dXYZ     return N->isVPOpcode() ? N->getNumOperands() - 2 : N->getNumOperands();
570fc1b0196Sv01dXYZ   }
5715874874cSMin-Yih Hsu };
5725874874cSMin-Yih Hsu } // anonymous namespace
5735874874cSMin-Yih Hsu TEST_F(SelectionDAGPatternMatchTest, matchContext) {
5745874874cSMin-Yih Hsu   SDLoc DL;
5755874874cSMin-Yih Hsu   auto BoolVT = EVT::getIntegerVT(Context, 1);
5765874874cSMin-Yih Hsu   auto Int32VT = EVT::getIntegerVT(Context, 32);
5775874874cSMin-Yih Hsu   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
5785874874cSMin-Yih Hsu   auto MaskVT = EVT::getVectorVT(Context, BoolVT, 4);
5795874874cSMin-Yih Hsu 
5805874874cSMin-Yih Hsu   SDValue Scalar0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
5815874874cSMin-Yih Hsu   SDValue Vector0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);
5825874874cSMin-Yih Hsu   SDValue Mask0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, MaskVT);
5835874874cSMin-Yih Hsu 
5845874874cSMin-Yih Hsu   SDValue VPAdd = DAG->getNode(ISD::VP_ADD, DL, VInt32VT,
5855874874cSMin-Yih Hsu                                {Vector0, Vector0, Mask0, Scalar0});
5865874874cSMin-Yih Hsu   SDValue VPReduceAdd = DAG->getNode(ISD::VP_REDUCE_ADD, DL, Int32VT,
5875874874cSMin-Yih Hsu                                      {Scalar0, VPAdd, Mask0, Scalar0});
588fc1b0196Sv01dXYZ   SDValue Add = DAG->getNode(ISD::ADD, DL, VInt32VT, {Vector0, Vector0});
5895874874cSMin-Yih Hsu 
5905874874cSMin-Yih Hsu   using namespace SDPatternMatch;
5915874874cSMin-Yih Hsu   VPMatchContext VPCtx(DAG.get());
5925874874cSMin-Yih Hsu   EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_Opc(ISD::ADD)));
593fc1b0196Sv01dXYZ   EXPECT_TRUE(
594fc1b0196Sv01dXYZ       sd_context_match(VPAdd, VPCtx, m_Node(ISD::ADD, m_Value(), m_Value())));
595fc1b0196Sv01dXYZ   // VPMatchContext can't match pattern using explicit VP Opcode
596fc1b0196Sv01dXYZ   EXPECT_FALSE(sd_context_match(VPAdd, VPCtx,
597fc1b0196Sv01dXYZ                                 m_Node(ISD::VP_ADD, m_Value(), m_Value())));
598fc1b0196Sv01dXYZ   EXPECT_FALSE(sd_context_match(
599fc1b0196Sv01dXYZ       VPAdd, VPCtx,
600fc1b0196Sv01dXYZ       m_Node(ISD::VP_ADD, m_Value(), m_Value(), m_Value(), m_Value())));
601fc1b0196Sv01dXYZ   // Check Binary Op Pattern
602fc1b0196Sv01dXYZ   EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_Add(m_Value(), m_Value())));
6035874874cSMin-Yih Hsu   // VP_REDUCE_ADD doesn't have a based opcode, so we use a normal
6045874874cSMin-Yih Hsu   // sd_match before switching to VPMatchContext when checking VPAdd.
6055874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(VPReduceAdd, m_Node(ISD::VP_REDUCE_ADD, m_Value(),
6065874874cSMin-Yih Hsu                                            m_Context(VPCtx, m_Opc(ISD::ADD)),
6075874874cSMin-Yih Hsu                                            m_Value(), m_Value())));
608fc1b0196Sv01dXYZ   // non-vector predicated should match too
609fc1b0196Sv01dXYZ   EXPECT_TRUE(sd_context_match(Add, VPCtx, m_Opc(ISD::ADD)));
610fc1b0196Sv01dXYZ   EXPECT_TRUE(
611fc1b0196Sv01dXYZ       sd_context_match(Add, VPCtx, m_Node(ISD::ADD, m_Value(), m_Value())));
612fc1b0196Sv01dXYZ   EXPECT_FALSE(sd_context_match(
613fc1b0196Sv01dXYZ       Add, VPCtx,
614fc1b0196Sv01dXYZ       m_Node(ISD::ADD, m_Value(), m_Value(), m_Value(), m_Value())));
615fc1b0196Sv01dXYZ   EXPECT_TRUE(sd_context_match(Add, VPCtx, m_Add(m_Value(), m_Value())));
616fc1b0196Sv01dXYZ }
617fc1b0196Sv01dXYZ 
618fc1b0196Sv01dXYZ TEST_F(SelectionDAGPatternMatchTest, matchVPWithBasicContext) {
619fc1b0196Sv01dXYZ   SDLoc DL;
620fc1b0196Sv01dXYZ   auto BoolVT = EVT::getIntegerVT(Context, 1);
621fc1b0196Sv01dXYZ   auto Int32VT = EVT::getIntegerVT(Context, 32);
622fc1b0196Sv01dXYZ   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
623fc1b0196Sv01dXYZ   auto MaskVT = EVT::getVectorVT(Context, BoolVT, 4);
624fc1b0196Sv01dXYZ 
625fc1b0196Sv01dXYZ   SDValue Vector0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, VInt32VT);
626fc1b0196Sv01dXYZ   SDValue Mask = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, MaskVT);
627fc1b0196Sv01dXYZ   SDValue EL = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int32VT);
628fc1b0196Sv01dXYZ 
629fc1b0196Sv01dXYZ   SDValue VPAdd =
630fc1b0196Sv01dXYZ       DAG->getNode(ISD::VP_ADD, DL, VInt32VT, Vector0, Vector0, Mask, EL);
631fc1b0196Sv01dXYZ 
632fc1b0196Sv01dXYZ   using namespace SDPatternMatch;
633fc1b0196Sv01dXYZ   EXPECT_FALSE(sd_match(VPAdd, m_Node(ISD::VP_ADD, m_Value(), m_Value())));
634fc1b0196Sv01dXYZ   EXPECT_TRUE(sd_match(
635fc1b0196Sv01dXYZ       VPAdd, m_Node(ISD::VP_ADD, m_Value(), m_Value(), m_Value(), m_Value())));
6365874874cSMin-Yih Hsu }
6375874874cSMin-Yih Hsu 
6385874874cSMin-Yih Hsu TEST_F(SelectionDAGPatternMatchTest, matchAdvancedProperties) {
6395874874cSMin-Yih Hsu   SDLoc DL;
6405874874cSMin-Yih Hsu   auto Int16VT = EVT::getIntegerVT(Context, 16);
6415874874cSMin-Yih Hsu   auto Int64VT = EVT::getIntegerVT(Context, 64);
6425874874cSMin-Yih Hsu 
6435874874cSMin-Yih Hsu   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);
6445874874cSMin-Yih Hsu   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int16VT);
6455874874cSMin-Yih Hsu 
6465874874cSMin-Yih Hsu   SDValue Add = DAG->getNode(ISD::ADD, DL, Int64VT, Op0, Op0);
6475874874cSMin-Yih Hsu 
6485874874cSMin-Yih Hsu   using namespace SDPatternMatch;
6495874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Op0, DAG.get(), m_LegalType(m_Value())));
6505874874cSMin-Yih Hsu   EXPECT_FALSE(sd_match(Op1, DAG.get(), m_LegalType(m_Value())));
6515874874cSMin-Yih Hsu   EXPECT_TRUE(sd_match(Add, DAG.get(),
6525874874cSMin-Yih Hsu                        m_LegalOp(m_IntegerVT(m_Add(m_Value(), m_Value())))));
6535874874cSMin-Yih Hsu }
654