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