brintos

brintos / llvm-project-archived public Read only

0
0
Text · 46.4 KiB · c32ceee Raw
1031 lines · cpp
1//===---- llvm/unittest/CodeGen/SelectionDAGPatternMatchTest.cpp  ---------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "SelectionDAGTestBase.h"10#include "llvm/CodeGen/SDPatternMatch.h"11 12using namespace llvm;13 14class SelectionDAGPatternMatchTest : public SelectionDAGTestBase {};15 16TEST_F(SelectionDAGPatternMatchTest, matchValueType) {17  SDLoc DL;18  auto Int32VT = EVT::getIntegerVT(Context, 32);19  auto Float32VT = EVT::getFloatingPointVT(32);20  auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);21 22  SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);23  SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Float32VT);24  SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);25 26  using namespace SDPatternMatch;27  EXPECT_TRUE(sd_match(Op0, m_SpecificVT(Int32VT)));28  EXPECT_TRUE(sd_match(Op0, m_SpecificScalarVT(Int32VT)));29  EXPECT_TRUE(sd_match(Op0, m_SpecificScalarVT(Int32VT, m_Value())));30  EXPECT_FALSE(sd_match(Op0, m_SpecificScalarVT(Float32VT)));31  EXPECT_FALSE(sd_match(Op0, m_SpecificScalarVT(Float32VT, m_Value())));32  EXPECT_TRUE(sd_match(Op2, m_SpecificVectorElementVT(Int32VT)));33  EXPECT_TRUE(sd_match(Op2, m_SpecificVectorElementVT(Int32VT, m_Value())));34  EXPECT_FALSE(sd_match(Op2, m_SpecificVectorElementVT(Float32VT)));35  EXPECT_FALSE(sd_match(Op2, m_SpecificVectorElementVT(Float32VT, m_Value())));36  EVT BindVT;37  EXPECT_TRUE(sd_match(Op1, m_VT(BindVT)));38  EXPECT_EQ(BindVT, Float32VT);39  EXPECT_TRUE(sd_match(Op0, m_IntegerVT()));40  EXPECT_TRUE(sd_match(Op1, m_FloatingPointVT()));41  EXPECT_TRUE(sd_match(Op2, m_VectorVT()));42  EXPECT_FALSE(sd_match(Op2, m_ScalableVectorVT()));43}44 45TEST_F(SelectionDAGPatternMatchTest, matchVecShuffle) {46  SDLoc DL;47  auto Int32VT = EVT::getIntegerVT(Context, 32);48  auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);49  const std::array<int, 4> MaskData = {2, 0, 3, 1};50  const std::array<int, 4> OtherMaskData = {1, 2, 3, 4};51  ArrayRef<int> Mask;52 53  SDValue V0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, VInt32VT);54  SDValue V1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);55  SDValue VecShuffleWithMask =56      DAG->getVectorShuffle(VInt32VT, DL, V0, V1, MaskData);57 58  using namespace SDPatternMatch;59  EXPECT_TRUE(sd_match(VecShuffleWithMask, m_Shuffle(m_Value(), m_Value())));60  EXPECT_TRUE(sd_match(VecShuffleWithMask,61                       m_Shuffle(m_Value(), m_Value(), m_Mask(Mask))));62  EXPECT_TRUE(63      sd_match(VecShuffleWithMask,64               m_Shuffle(m_Value(), m_Value(), m_SpecificMask(MaskData))));65  EXPECT_FALSE(66      sd_match(VecShuffleWithMask,67               m_Shuffle(m_Value(), m_Value(), m_SpecificMask(OtherMaskData))));68  EXPECT_TRUE(69      std::equal(MaskData.begin(), MaskData.end(), Mask.begin(), Mask.end()));70}71 72TEST_F(SelectionDAGPatternMatchTest, matchTernaryOp) {73  SDLoc DL;74  auto Int32VT = EVT::getIntegerVT(Context, 32);75 76  SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);77  SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);78  SDValue Op3 = DAG->getConstant(1, DL, Int32VT);79 80  SDValue ICMP_UGT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGT);81  SDValue ICMP_EQ01 = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETEQ);82  SDValue ICMP_EQ10 = DAG->getSetCC(DL, MVT::i1, Op1, Op0, ISD::SETEQ);83 84  auto Int1VT = EVT::getIntegerVT(Context, 1);85  SDValue Cond = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int1VT);86  SDValue T = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 4, Int1VT);87  SDValue F = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 5, Int1VT);88  SDValue Select = DAG->getSelect(DL, MVT::i1, Cond, T, F);89 90  auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);91  auto SmallVInt32VT = EVT::getVectorVT(Context, Int32VT, 2);92  auto Idx0 = DAG->getVectorIdxConstant(0, DL);93  auto Idx3 = DAG->getVectorIdxConstant(3, DL);94  SDValue V1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 6, VInt32VT);95  SDValue V2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 7, VInt32VT);96  SDValue V3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 8, SmallVInt32VT);97  SDValue VSelect = DAG->getNode(ISD::VSELECT, DL, VInt32VT, Cond, V1, V2);98  SDValue InsertSubvector =99      DAG->getNode(ISD::INSERT_SUBVECTOR, DL, VInt32VT, V2, V3, Idx0);100 101  SDValue ExtractELT =102      DAG->getNode(ISD::EXTRACT_VECTOR_ELT, DL, Int32VT, V1, Op3);103 104  SDValue Ch = DAG->getEntryNode();105  SDValue BasePtr = DAG->getRegister(1, MVT::i64);106  SDValue Offset = DAG->getUNDEF(MVT::i64);107  MachinePointerInfo PtrInfo;108  SDValue Load = DAG->getLoad(MVT::i32, DL, Ch, BasePtr, PtrInfo);109 110  using namespace SDPatternMatch;111  ISD::CondCode CC;112  EXPECT_TRUE(sd_match(ICMP_UGT, m_SetCC(m_Value(), m_Value(),113                                         m_SpecificCondCode(ISD::SETUGT))));114  EXPECT_TRUE(115      sd_match(ICMP_UGT, m_SetCC(m_Value(), m_Value(), m_CondCode(CC))));116  EXPECT_TRUE(CC == ISD::SETUGT);117  EXPECT_FALSE(sd_match(118      ICMP_UGT, m_SetCC(m_Value(), m_Value(), m_SpecificCondCode(ISD::SETLE))));119 120  EXPECT_TRUE(sd_match(ICMP_EQ01, m_SetCC(m_Specific(Op0), m_Specific(Op1),121                                          m_SpecificCondCode(ISD::SETEQ))));122  EXPECT_TRUE(sd_match(ICMP_EQ10, m_SetCC(m_Specific(Op1), m_Specific(Op0),123                                          m_SpecificCondCode(ISD::SETEQ))));124  EXPECT_FALSE(sd_match(ICMP_EQ01, m_SetCC(m_Specific(Op1), m_Specific(Op0),125                                           m_SpecificCondCode(ISD::SETEQ))));126  EXPECT_FALSE(sd_match(ICMP_EQ10, m_SetCC(m_Specific(Op0), m_Specific(Op1),127                                           m_SpecificCondCode(ISD::SETEQ))));128  EXPECT_TRUE(sd_match(ICMP_EQ01, m_c_SetCC(m_Specific(Op1), m_Specific(Op0),129                                            m_SpecificCondCode(ISD::SETEQ))));130  EXPECT_TRUE(sd_match(ICMP_EQ10, m_c_SetCC(m_Specific(Op0), m_Specific(Op1),131                                            m_SpecificCondCode(ISD::SETEQ))));132 133  EXPECT_TRUE(sd_match(134      Select, m_Select(m_Specific(Cond), m_Specific(T), m_Specific(F))));135  EXPECT_FALSE(sd_match(136      Select, m_Select(m_Specific(Cond), m_Specific(F), m_Specific(T))));137  EXPECT_FALSE(sd_match(ICMP_EQ01, m_Select(m_Specific(Op0), m_Specific(Op1),138                                            m_SpecificCondCode(ISD::SETEQ))));139  EXPECT_TRUE(sd_match(140      VSelect, m_VSelect(m_Specific(Cond), m_Specific(V1), m_Specific(V2))));141  EXPECT_FALSE(sd_match(142      Select, m_VSelect(m_Specific(Cond), m_Specific(V1), m_Specific(V2))));143 144  EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_Value())));145  EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_ConstInt())));146  EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_SpecificInt(1))));147 148  EXPECT_TRUE(sd_match(InsertSubvector,149                       m_InsertSubvector(m_Value(), m_Value(), m_Value())));150  EXPECT_TRUE(sd_match(151      InsertSubvector,152      m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_Specific(Idx0))));153  EXPECT_TRUE(sd_match(154      InsertSubvector,155      m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_SpecificInt(0))));156  EXPECT_FALSE(sd_match(157      InsertSubvector,158      m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_Specific(Idx3))));159  EXPECT_FALSE(sd_match(160      InsertSubvector,161      m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_SpecificInt(3))));162 163  EXPECT_TRUE(sd_match(164      Load, m_Load(m_Specific(Ch), m_Specific(BasePtr), m_Specific(Offset))));165 166  EXPECT_FALSE(167      sd_match(Load.getValue(1), m_Load(m_Specific(Ch), m_Specific(BasePtr),168                                        m_Specific(Offset))));169}170 171TEST_F(SelectionDAGPatternMatchTest, matchBinaryOp) {172  SDLoc DL;173  auto Int32VT = EVT::getIntegerVT(Context, 32);174  auto Float32VT = EVT::getFloatingPointVT(32);175  auto BigVInt32VT = EVT::getVectorVT(Context, Int32VT, 8);176  auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);177 178  SDValue V1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 6, VInt32VT);179  auto Idx0 = DAG->getVectorIdxConstant(0, DL);180  auto Idx1 = DAG->getVectorIdxConstant(1, DL);181 182  SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);183  SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);184  SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Float32VT);185  SDValue Op3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 8, Int32VT);186  SDValue Op4 = DAG->getConstant(1, DL, Int32VT);187 188  SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);189  SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Add, Op0);190  SDValue Mul = DAG->getNode(ISD::MUL, DL, Int32VT, Add, Sub);191  SDValue And = DAG->getNode(ISD::AND, DL, Int32VT, Op0, Op1);192  SDValue Xor = DAG->getNode(ISD::XOR, DL, Int32VT, Op1, Op0);193  SDValue Or  = DAG->getNode(ISD::OR, DL, Int32VT, Op0, Op1);194  SDValue DisOr =195      DAG->getNode(ISD::OR, DL, Int32VT, Op0, Op3, SDNodeFlags::Disjoint);196  SDValue SMax = DAG->getNode(ISD::SMAX, DL, Int32VT, Op0, Op1);197  SDValue SMin = DAG->getNode(ISD::SMIN, DL, Int32VT, Op1, Op0);198  SDValue UMax = DAG->getNode(ISD::UMAX, DL, Int32VT, Op0, Op1);199  SDValue UMin = DAG->getNode(ISD::UMIN, DL, Int32VT, Op1, Op0);200  SDValue Rotl = DAG->getNode(ISD::ROTL, DL, Int32VT, Op0, Op1);201  SDValue Rotr = DAG->getNode(ISD::ROTR, DL, Int32VT, Op1, Op0);202 203  SDValue SMulLoHi = DAG->getNode(ISD::SMUL_LOHI, DL,204                                  DAG->getVTList(Int32VT, Int32VT), Op0, Op1);205  SDValue PartsDiff =206      DAG->getNode(ISD::SUB, DL, Int32VT, SMulLoHi, SMulLoHi.getValue(1));207 208  SDValue ICMP_GT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETGT);209  SDValue ICMP_GE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETGE);210  SDValue ICMP_UGT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGT);211  SDValue ICMP_UGE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGE);212  SDValue ICMP_LT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETLT);213  SDValue ICMP_LE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETLE);214  SDValue ICMP_ULT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETULT);215  SDValue ICMP_ULE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETULE);216  SDValue SMaxLikeGT = DAG->getSelect(DL, MVT::i32, ICMP_GT, Op0, Op1);217  SDValue SMaxLikeGE = DAG->getSelect(DL, MVT::i32, ICMP_GE, Op0, Op1);218  SDValue UMaxLikeUGT = DAG->getSelect(DL, MVT::i32, ICMP_UGT, Op0, Op1);219  SDValue UMaxLikeUGE = DAG->getSelect(DL, MVT::i32, ICMP_UGE, Op0, Op1);220  SDValue SMinLikeLT = DAG->getSelect(DL, MVT::i32, ICMP_LT, Op0, Op1);221  SDValue SMinLikeLE = DAG->getSelect(DL, MVT::i32, ICMP_LE, Op0, Op1);222  SDValue UMinLikeULT = DAG->getSelect(DL, MVT::i32, ICMP_ULT, Op0, Op1);223  SDValue UMinLikeULE = DAG->getSelect(DL, MVT::i32, ICMP_ULE, Op0, Op1);224 225  SDValue CCSMaxLikeGT = DAG->getSelectCC(DL, Op0, Op1, Op0, Op1, ISD::SETGT);226  SDValue CCSMaxLikeGE = DAG->getSelectCC(DL, Op0, Op1, Op0, Op1, ISD::SETGE);227  SDValue CCSMaxLikeLT = DAG->getSelectCC(DL, Op0, Op1, Op1, Op0, ISD::SETLT);228  SDValue CCSMaxLikeLE = DAG->getSelectCC(DL, Op0, Op1, Op1, Op0, ISD::SETLE);229  SDValue CCUMaxLikeUGT = DAG->getSelectCC(DL, Op0, Op1, Op0, Op1, ISD::SETUGT);230  SDValue CCUMaxLikeUGE = DAG->getSelectCC(DL, Op0, Op1, Op0, Op1, ISD::SETUGE);231  SDValue CCUMaxLikeULT = DAG->getSelectCC(DL, Op0, Op1, Op1, Op0, ISD::SETULT);232  SDValue CCUMaxLikeULE = DAG->getSelectCC(DL, Op0, Op1, Op1, Op0, ISD::SETULE);233  SDValue CCSMinLikeLT = DAG->getSelectCC(DL, Op0, Op1, Op0, Op1, ISD::SETLT);234  SDValue CCSMinLikeGT = DAG->getSelectCC(DL, Op0, Op1, Op1, Op0, ISD::SETGT);235  SDValue CCSMinLikeLE = DAG->getSelectCC(DL, Op0, Op1, Op0, Op1, ISD::SETLE);236  SDValue CCSMinLikeGE = DAG->getSelectCC(DL, Op0, Op1, Op1, Op0, ISD::SETGE);237  SDValue CCUMinLikeULT = DAG->getSelectCC(DL, Op0, Op1, Op0, Op1, ISD::SETULT);238  SDValue CCUMinLikeUGT = DAG->getSelectCC(DL, Op0, Op1, Op1, Op0, ISD::SETUGT);239  SDValue CCUMinLikeULE = DAG->getSelectCC(DL, Op0, Op1, Op0, Op1, ISD::SETULE);240  SDValue CCUMinLikeUGE = DAG->getSelectCC(DL, Op0, Op1, Op1, Op0, ISD::SETUGE);241 242  SDValue SFAdd = DAG->getNode(ISD::STRICT_FADD, DL, {Float32VT, MVT::Other},243                               {DAG->getEntryNode(), Op2, Op2});244 245  SDValue Vec = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 9, BigVInt32VT);246  SDValue SubVec =247      DAG->getNode(ISD::EXTRACT_SUBVECTOR, DL, VInt32VT, Vec, Idx0);248 249  SDValue InsertELT =250      DAG->getNode(ISD::INSERT_VECTOR_ELT, DL, VInt32VT, V1, Op0, Op4);251 252  using namespace SDPatternMatch;253  EXPECT_TRUE(sd_match(Sub, m_BinOp(ISD::SUB, m_Value(), m_Value())));254  EXPECT_TRUE(sd_match(Sub, m_Sub(m_Value(), m_Value())));255  EXPECT_TRUE(sd_match(Add, m_c_BinOp(ISD::ADD, m_Value(), m_Value())));256  EXPECT_TRUE(sd_match(Add, m_Add(m_Value(), m_Value())));257  EXPECT_TRUE(sd_match(Add, m_AddLike(m_Value(), m_Value())));258  EXPECT_TRUE(sd_match(259      Mul, m_Mul(m_OneUse(m_Opc(ISD::SUB)), m_NUses<2>(m_Specific(Add)))));260  EXPECT_TRUE(261      sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_SpecificVT(Float32VT),262                                     m_SpecificVT(Float32VT))));263  EXPECT_FALSE(sd_match(Add, m_BitwiseLogic(m_Value(), m_Value())));264  EXPECT_FALSE(sd_match(Sub, m_BitwiseLogic(m_Value(), m_Value())));265 266  EXPECT_TRUE(sd_match(And, m_c_BinOp(ISD::AND, m_Value(), m_Value())));267  EXPECT_TRUE(sd_match(And, m_And(m_Value(), m_Value())));268  EXPECT_TRUE(sd_match(And, m_BitwiseLogic(m_Value(), m_Value())));269  EXPECT_TRUE(sd_match(Xor, m_c_BinOp(ISD::XOR, m_Value(), m_Value())));270  EXPECT_TRUE(sd_match(Xor, m_Xor(m_Value(), m_Value())));271  EXPECT_TRUE(sd_match(Xor, m_BitwiseLogic(m_Value(), m_Value())));272  EXPECT_TRUE(sd_match(Or, m_c_BinOp(ISD::OR, m_Value(), m_Value())));273  EXPECT_TRUE(sd_match(Or, m_Or(m_Value(), m_Value())));274  EXPECT_TRUE(sd_match(Or, m_BitwiseLogic(m_Value(), m_Value())));275  EXPECT_FALSE(sd_match(Or, m_DisjointOr(m_Value(), m_Value())));276 277  EXPECT_TRUE(sd_match(DisOr, m_Or(m_Value(), m_Value())));278  EXPECT_TRUE(sd_match(DisOr, m_DisjointOr(m_Value(), m_Value())));279  EXPECT_FALSE(sd_match(DisOr, m_Add(m_Value(), m_Value())));280  EXPECT_TRUE(sd_match(DisOr, m_AddLike(m_Value(), m_Value())));281 282  EXPECT_TRUE(sd_match(Rotl, m_Rotl(m_Value(), m_Value())));283  EXPECT_TRUE(sd_match(Rotr, m_Rotr(m_Value(), m_Value())));284  EXPECT_FALSE(sd_match(Rotl, m_Rotr(m_Value(), m_Value())));285  EXPECT_FALSE(sd_match(Rotr, m_Rotl(m_Value(), m_Value())));286 287  EXPECT_TRUE(sd_match(SMax, m_c_BinOp(ISD::SMAX, m_Value(), m_Value())));288  EXPECT_TRUE(sd_match(SMax, m_SMax(m_Value(), m_Value())));289  EXPECT_TRUE(sd_match(SMax, m_SMaxLike(m_Value(), m_Value())));290  EXPECT_TRUE(sd_match(SMaxLikeGT, m_SMaxLike(m_Value(), m_Value())));291  EXPECT_TRUE(sd_match(SMaxLikeGE, m_SMaxLike(m_Value(), m_Value())));292  EXPECT_TRUE(sd_match(CCSMaxLikeGT, m_SMaxLike(m_Value(), m_Value())));293  EXPECT_TRUE(sd_match(CCSMaxLikeGE, m_SMaxLike(m_Value(), m_Value())));294  EXPECT_TRUE(sd_match(CCSMaxLikeLT, m_SMaxLike(m_Value(), m_Value())));295  EXPECT_TRUE(sd_match(CCSMaxLikeLE, m_SMaxLike(m_Value(), m_Value())));296  EXPECT_TRUE(sd_match(SMin, m_c_BinOp(ISD::SMIN, m_Value(), m_Value())));297  EXPECT_TRUE(sd_match(SMin, m_SMin(m_Value(), m_Value())));298  EXPECT_TRUE(sd_match(SMin, m_SMinLike(m_Value(), m_Value())));299  EXPECT_TRUE(sd_match(SMinLikeLT, m_SMinLike(m_Value(), m_Value())));300  EXPECT_TRUE(sd_match(SMinLikeLE, m_SMinLike(m_Value(), m_Value())));301  EXPECT_TRUE(sd_match(CCSMinLikeGT, m_SMinLike(m_Value(), m_Value())));302  EXPECT_TRUE(sd_match(CCSMinLikeGE, m_SMinLike(m_Value(), m_Value())));303  EXPECT_TRUE(sd_match(CCSMinLikeLT, m_SMinLike(m_Value(), m_Value())));304  EXPECT_TRUE(sd_match(CCSMinLikeLE, m_SMinLike(m_Value(), m_Value())));305  EXPECT_TRUE(sd_match(UMax, m_c_BinOp(ISD::UMAX, m_Value(), m_Value())));306  EXPECT_TRUE(sd_match(UMax, m_UMax(m_Value(), m_Value())));307  EXPECT_TRUE(sd_match(UMax, m_UMaxLike(m_Value(), m_Value())));308  EXPECT_TRUE(sd_match(UMaxLikeUGT, m_UMaxLike(m_Value(), m_Value())));309  EXPECT_TRUE(sd_match(UMaxLikeUGE, m_UMaxLike(m_Value(), m_Value())));310  EXPECT_TRUE(sd_match(CCUMaxLikeUGT, m_UMaxLike(m_Value(), m_Value())));311  EXPECT_TRUE(sd_match(CCUMaxLikeUGE, m_UMaxLike(m_Value(), m_Value())));312  EXPECT_TRUE(sd_match(CCUMaxLikeULT, m_UMaxLike(m_Value(), m_Value())));313  EXPECT_TRUE(sd_match(CCUMaxLikeULE, m_UMaxLike(m_Value(), m_Value())));314  EXPECT_TRUE(sd_match(UMin, m_c_BinOp(ISD::UMIN, m_Value(), m_Value())));315  EXPECT_TRUE(sd_match(UMin, m_UMin(m_Value(), m_Value())));316  EXPECT_TRUE(sd_match(UMin, m_UMinLike(m_Value(), m_Value())));317  EXPECT_TRUE(sd_match(UMinLikeULT, m_UMinLike(m_Value(), m_Value())));318  EXPECT_TRUE(sd_match(UMinLikeULE, m_UMinLike(m_Value(), m_Value())));319  EXPECT_TRUE(sd_match(CCUMinLikeUGT, m_UMinLike(m_Value(), m_Value())));320  EXPECT_TRUE(sd_match(CCUMinLikeUGE, m_UMinLike(m_Value(), m_Value())));321  EXPECT_TRUE(sd_match(CCUMinLikeULT, m_UMinLike(m_Value(), m_Value())));322  EXPECT_TRUE(sd_match(CCUMinLikeULE, m_UMinLike(m_Value(), m_Value())));323 324  // By default, it matches any of the results.325  EXPECT_TRUE(326      sd_match(PartsDiff, m_Sub(m_Opc(ISD::SMUL_LOHI), m_Opc(ISD::SMUL_LOHI))));327  // Matching a specific result.328  EXPECT_TRUE(sd_match(PartsDiff, m_Sub(m_Opc(ISD::SMUL_LOHI),329                                        m_Result<1>(m_Opc(ISD::SMUL_LOHI)))));330  EXPECT_FALSE(sd_match(PartsDiff, m_Sub(m_Opc(ISD::SMUL_LOHI),331                                         m_Result<0>(m_Opc(ISD::SMUL_LOHI)))));332 333  SDValue BindVal;334  EXPECT_TRUE(sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_Value(BindVal),335                                             m_Deferred(BindVal))));336  EXPECT_FALSE(sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_OtherVT(),337                                              m_SpecificVT(Float32VT))));338 339  EXPECT_TRUE(sd_match(SubVec, m_ExtractSubvector(m_Value(), m_Value())));340  EXPECT_TRUE(341      sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_Specific(Idx0))));342  EXPECT_TRUE(343      sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_SpecificInt(0))));344  EXPECT_FALSE(345      sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_Specific(Idx1))));346  EXPECT_FALSE(347      sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_SpecificInt(1))));348 349  EXPECT_TRUE(350      sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_Value())));351  EXPECT_TRUE(352      sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_ConstInt())));353  EXPECT_TRUE(354      sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_SpecificInt(1))));355}356 357TEST_F(SelectionDAGPatternMatchTest, matchSpecificFpOp) {358  SDLoc DL;359  APFloat Value(1.5f);360  auto Float32VT = EVT::getFloatingPointVT(32);361  SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Float32VT);362  SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Float32VT);363  SDValue Op2 = DAG->getConstantFP(Value, DL, Float32VT);364  SDValue FAdd0 = DAG->getNode(ISD::FADD, DL, Float32VT, Op0, Op1);365  SDValue FAdd1 = DAG->getNode(ISD::FADD, DL, Float32VT, Op1, Op2);366 367  using namespace SDPatternMatch;368 369  EXPECT_FALSE(sd_match(Op1, m_SpecificFP(Value)));370  EXPECT_TRUE(sd_match(Op2, m_SpecificFP(Value)));371 372  EXPECT_FALSE(sd_match(373      FAdd0, m_BinOp(ISD::FADD, m_Specific(Op0), m_SpecificFP(Value))));374  EXPECT_TRUE(sd_match(375      FAdd1, m_BinOp(ISD::FADD, m_Specific(Op1), m_SpecificFP(Value))));376  EXPECT_TRUE(sd_match(377      FAdd1, m_c_BinOp(ISD::FADD, m_SpecificFP(Value), m_Specific(Op1))));378 379  auto VFloat32VT = EVT::getVectorVT(Context, Float32VT, 2);380  SDValue VOp0 = DAG->getSplat(VFloat32VT, DL, Op0);381  SDValue VOp1 = DAG->getSplat(VFloat32VT, DL, Op1);382  SDValue VOp2 = DAG->getSplat(VFloat32VT, DL, Op2);383 384  EXPECT_FALSE(sd_match(VOp0, m_SpecificFP(Value)));385  EXPECT_TRUE(sd_match(VOp2, m_SpecificFP(Value)));386 387  SDValue VFAdd0 = DAG->getNode(ISD::FADD, DL, VFloat32VT, VOp0, VOp1);388  SDValue VFAdd1 = DAG->getNode(ISD::FADD, DL, VFloat32VT, VOp1, VOp2);389  EXPECT_FALSE(sd_match(390      VFAdd0, m_BinOp(ISD::FADD, m_Specific(VOp0), m_SpecificFP(Value))));391  EXPECT_TRUE(sd_match(392      VFAdd1, m_BinOp(ISD::FADD, m_Specific(VOp1), m_SpecificFP(Value))));393  EXPECT_TRUE(sd_match(394      VFAdd1, m_c_BinOp(ISD::FADD, m_SpecificFP(Value), m_Specific(VOp1))));395}396 397TEST_F(SelectionDAGPatternMatchTest, matchGenericTernaryOp) {398  SDLoc DL;399  auto Float32VT = EVT::getFloatingPointVT(32);400 401  SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Float32VT);402  SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Float32VT);403  SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Float32VT);404 405  SDValue FMA = DAG->getNode(ISD::FMA, DL, Float32VT, Op0, Op1, Op2);406  SDValue FAdd = DAG->getNode(ISD::FADD, DL, Float32VT, Op0, Op1);407 408  using namespace SDPatternMatch;409  SDValue A, B, C;410 411  EXPECT_TRUE(sd_match(FMA, m_TernaryOp(ISD::FMA, m_Specific(Op0),412                                        m_Specific(Op1), m_Specific(Op2))));413  EXPECT_FALSE(sd_match(FMA, m_TernaryOp(ISD::FADD, m_Specific(Op0),414                                         m_Specific(Op1), m_Specific(Op2))));415  EXPECT_FALSE(416      sd_match(FAdd, m_TernaryOp(ISD::FMA, m_Value(), m_Value(), m_Value())));417  EXPECT_FALSE(sd_match(FMA, m_TernaryOp(ISD::FMA, m_Specific(Op1),418                                         m_Specific(Op0), m_Specific(Op2))));419 420  EXPECT_TRUE(421      sd_match(FMA, m_TernaryOp(ISD::FMA, m_Value(A), m_Value(B), m_Value(C))));422  EXPECT_EQ(A, Op0);423  EXPECT_EQ(B, Op1);424  EXPECT_EQ(C, Op2);425 426  A = B = C = SDValue();427 428  EXPECT_TRUE(sd_match(FMA, m_c_TernaryOp(ISD::FMA, m_Specific(Op0),429                                          m_Specific(Op1), m_Specific(Op2))));430  EXPECT_TRUE(sd_match(FMA, m_c_TernaryOp(ISD::FMA, m_Specific(Op1),431                                          m_Specific(Op0), m_Specific(Op2))));432 433  EXPECT_FALSE(sd_match(FMA, m_c_TernaryOp(ISD::FMA, m_Specific(Op2),434                                           m_Specific(Op1), m_Specific(Op0))));435  EXPECT_FALSE(sd_match(FMA, m_c_TernaryOp(ISD::FMA, m_Specific(Op2),436                                           m_Specific(Op0), m_Specific(Op1))));437 438  EXPECT_FALSE(sd_match(FMA, m_c_TernaryOp(ISD::FMA, m_Specific(Op0),439                                           m_Specific(Op2), m_Specific(Op1))));440  EXPECT_FALSE(sd_match(FMA, m_c_TernaryOp(ISD::FMA, m_Specific(Op1),441                                           m_Specific(Op2), m_Specific(Op0))));442 443  EXPECT_TRUE(sd_match(444      FMA, m_c_TernaryOp(ISD::FMA, m_Value(A), m_Value(B), m_Value(C))));445  EXPECT_EQ(A, Op0);446  EXPECT_EQ(B, Op1);447  EXPECT_EQ(C, Op2);448 449  A = B = C = SDValue();450  EXPECT_TRUE(sd_match(451      FMA, m_c_TernaryOp(ISD::FMA, m_Value(B), m_Value(A), m_Value(C))));452  EXPECT_EQ(A, Op1);453  EXPECT_EQ(B, Op0);454  EXPECT_EQ(C, Op2);455 456  A = B = C = SDValue();457  EXPECT_TRUE(sd_match(458      FMA, m_c_TernaryOp(ISD::FMA, m_Value(A), m_Value(B), m_Value(C))));459  EXPECT_EQ(A, Op0);460  EXPECT_EQ(B, Op1);461  EXPECT_EQ(C, Op2);462 463  EXPECT_FALSE(464      sd_match(FAdd, m_c_TernaryOp(ISD::FMA, m_Value(), m_Value(), m_Value())));465}466 467TEST_F(SelectionDAGPatternMatchTest, matchUnaryOp) {468  SDLoc DL;469  auto Int32VT = EVT::getIntegerVT(Context, 32);470  auto Int64VT = EVT::getIntegerVT(Context, 64);471  auto FloatVT = EVT::getFloatingPointVT(32);472 473  SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);474  SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);475  SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, FloatVT);  476  SDValue Op3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int32VT);477 478  SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op0);479  SDValue ZExtNNeg =480      DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op3, SDNodeFlags::NonNeg);481  SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op0);482  SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op1);483 484  SDValue Abs = DAG->getNode(ISD::ABS, DL, Int32VT, Op0);485 486  SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Trunc, Op0);487  SDValue Neg = DAG->getNegative(Op0, DL, Int32VT);488  SDValue Not = DAG->getNOT(DL, Op0, Int32VT);489 490  SDValue VScale = DAG->getVScale(DL, Int32VT, APInt::getMaxValue(32));491 492  SDValue FPToSI = DAG->getNode(ISD::FP_TO_SINT, DL, FloatVT, Op2);493  SDValue FPToUI = DAG->getNode(ISD::FP_TO_UINT, DL, FloatVT, Op2);494 495  SDValue Bcast = DAG->getNode(ISD::BITCAST, DL, FloatVT, Op0);496  SDValue Brev = DAG->getNode(ISD::BITREVERSE, DL, Int32VT, Op0);497  SDValue Bswap = DAG->getNode(ISD::BSWAP, DL, Int32VT, Op0);498 499  SDValue Ctpop = DAG->getNode(ISD::CTPOP, DL, Int32VT, Op0);500  SDValue Ctlz = DAG->getNode(ISD::CTLZ, DL, Int32VT, Op0);501  SDValue Cttz = DAG->getNode(ISD::CTTZ, DL, Int32VT, Op0);502 503  using namespace SDPatternMatch;504  EXPECT_TRUE(sd_match(ZExt, m_UnaryOp(ISD::ZERO_EXTEND, m_Value())));505  EXPECT_TRUE(sd_match(SExt, m_SExt(m_Value())));506  EXPECT_TRUE(sd_match(SExt, m_SExtLike(m_Value())));507  ASSERT_TRUE(ZExtNNeg->getFlags().hasNonNeg());508  EXPECT_FALSE(sd_match(ZExtNNeg, m_SExt(m_Value())));509  EXPECT_TRUE(sd_match(ZExtNNeg, m_NNegZExt(m_Value())));510  EXPECT_FALSE(sd_match(ZExt, m_NNegZExt(m_Value())));511  EXPECT_TRUE(sd_match(ZExtNNeg, m_SExtLike(m_Value())));512  EXPECT_FALSE(sd_match(ZExt, m_SExtLike(m_Value())));513  EXPECT_TRUE(sd_match(Trunc, m_Trunc(m_Specific(Op1))));514 515  EXPECT_TRUE(sd_match(Abs, m_Abs(m_Specific(Op0))));516 517  EXPECT_TRUE(sd_match(Neg, m_Neg(m_Value())));518  EXPECT_TRUE(sd_match(Not, m_Not(m_Value())));519  EXPECT_FALSE(sd_match(ZExt, m_Neg(m_Value())));520  EXPECT_FALSE(sd_match(Sub, m_Neg(m_Value())));521  EXPECT_FALSE(sd_match(Neg, m_Not(m_Value())));522  EXPECT_TRUE(sd_match(VScale, m_VScale(m_Value())));523 524  EXPECT_TRUE(sd_match(FPToUI, m_FPToUI(m_Value())));525  EXPECT_TRUE(sd_match(FPToSI, m_FPToSI(m_Value())));526  EXPECT_FALSE(sd_match(FPToUI, m_FPToSI(m_Value())));527  EXPECT_FALSE(sd_match(FPToSI, m_FPToUI(m_Value())));528 529  EXPECT_TRUE(sd_match(Bcast, m_BitCast(m_Value())));530  EXPECT_TRUE(sd_match(Bcast, m_BitCast(m_SpecificVT(MVT::i32))));531  EXPECT_TRUE(sd_match(Brev, m_BitReverse(m_Value())));532  EXPECT_TRUE(sd_match(Bswap, m_BSwap(m_Value())));533  EXPECT_FALSE(sd_match(Bcast, m_BitReverse(m_Value())));534  EXPECT_FALSE(sd_match(Bcast, m_BitCast(m_SpecificVT(MVT::f32))));535  EXPECT_FALSE(sd_match(Brev, m_BSwap(m_Value())));536  EXPECT_FALSE(sd_match(Bswap, m_BitReverse(m_Value())));537 538  EXPECT_TRUE(sd_match(Ctpop, m_Ctpop(m_Value())));539  EXPECT_TRUE(sd_match(Ctlz, m_Ctlz(m_Value())));540  EXPECT_TRUE(sd_match(Cttz, m_Cttz(m_Value())));541  EXPECT_FALSE(sd_match(Ctpop, m_Ctlz(m_Value())));542  EXPECT_FALSE(sd_match(Ctlz, m_Cttz(m_Value())));543  EXPECT_FALSE(sd_match(Cttz, m_Ctlz(m_Value())));544}545 546TEST_F(SelectionDAGPatternMatchTest, matchConstants) {547  SDLoc DL;548  auto Int32VT = EVT::getIntegerVT(Context, 32);549  auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);550 551  SDValue Arg0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);552 553  SDValue Const3 = DAG->getConstant(3, DL, Int32VT);554  SDValue Const87 = DAG->getConstant(87, DL, Int32VT);555  SDValue Splat = DAG->getSplat(VInt32VT, DL, Arg0);556  SDValue ConstSplat = DAG->getSplat(VInt32VT, DL, Const3);557  SDValue Zero = DAG->getConstant(0, DL, Int32VT);558  SDValue One = DAG->getConstant(1, DL, Int32VT);559  SDValue AllOnes = DAG->getConstant(APInt::getAllOnes(32), DL, Int32VT);560  SDValue SetCC = DAG->getSetCC(DL, Int32VT, Arg0, Const3, ISD::SETULT);561 562  using namespace SDPatternMatch;563  EXPECT_TRUE(sd_match(Const87, m_ConstInt()));564  EXPECT_FALSE(sd_match(Arg0, m_ConstInt()));565  APInt ConstVal;566  EXPECT_TRUE(sd_match(ConstSplat, m_ConstInt(ConstVal)));567  EXPECT_EQ(ConstVal, 3);568  EXPECT_FALSE(sd_match(Splat, m_ConstInt()));569 570  EXPECT_TRUE(sd_match(Const87, m_SpecificInt(87)));571  EXPECT_TRUE(sd_match(Const3, m_SpecificInt(ConstVal)));572  EXPECT_TRUE(sd_match(AllOnes, m_AllOnes()));573 574  EXPECT_TRUE(sd_match(Zero, DAG.get(), m_False()));575  EXPECT_TRUE(sd_match(One, DAG.get(), m_True()));576  EXPECT_FALSE(sd_match(AllOnes, DAG.get(), m_True()));577 578  ISD::CondCode CC;579  EXPECT_TRUE(sd_match(580      SetCC, m_Node(ISD::SETCC, m_Value(), m_Value(), m_CondCode(CC))));581  EXPECT_EQ(CC, ISD::SETULT);582  EXPECT_TRUE(sd_match(SetCC, m_Node(ISD::SETCC, m_Value(), m_Value(),583                                     m_SpecificCondCode(ISD::SETULT))));584 585  SDValue UndefInt32VT = DAG->getUNDEF(Int32VT);586  SDValue UndefVInt32VT = DAG->getUNDEF(VInt32VT);587  EXPECT_TRUE(sd_match(UndefInt32VT, m_Undef()));588  EXPECT_TRUE(sd_match(UndefVInt32VT, m_Undef()));589 590  SDValue PoisonInt32VT = DAG->getPOISON(Int32VT);591  SDValue PoisonVInt32VT = DAG->getPOISON(VInt32VT);592  EXPECT_TRUE(sd_match(PoisonInt32VT, m_Poison()));593  EXPECT_TRUE(sd_match(PoisonVInt32VT, m_Poison()));594  EXPECT_TRUE(sd_match(PoisonInt32VT, m_Undef()));595  EXPECT_TRUE(sd_match(PoisonVInt32VT, m_Undef()));596}597 598TEST_F(SelectionDAGPatternMatchTest, patternCombinators) {599  SDLoc DL;600  auto Int32VT = EVT::getIntegerVT(Context, 32);601 602  SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);603  SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);604 605  SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);606  SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Add, Op0);607 608  using namespace SDPatternMatch;609  EXPECT_TRUE(sd_match(610      Sub, m_AnyOf(m_Opc(ISD::ADD), m_Opc(ISD::SUB), m_Opc(ISD::MUL))));611  EXPECT_TRUE(sd_match(Add, m_AllOf(m_Opc(ISD::ADD), m_OneUse())));612  EXPECT_TRUE(sd_match(Add, m_NoneOf(m_Opc(ISD::SUB), m_Opc(ISD::MUL))));613}614 615TEST_F(SelectionDAGPatternMatchTest, optionalResizing) {616  SDLoc DL;617  auto Int32VT = EVT::getIntegerVT(Context, 32);618  auto Int64VT = EVT::getIntegerVT(Context, 64);619 620  SDValue Op32 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);621  SDValue Op64 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);622  SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op32);623  SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op32);624  SDValue AExt = DAG->getNode(ISD::ANY_EXTEND, DL, Int64VT, Op32);625  SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op64);626 627  using namespace SDPatternMatch;628  SDValue A;629  EXPECT_TRUE(sd_match(Op32, m_ZExtOrSelf(m_Value(A))));630  EXPECT_TRUE(A == Op32);631  EXPECT_TRUE(sd_match(ZExt, m_ZExtOrSelf(m_Value(A))));632  EXPECT_TRUE(A == Op32);633  EXPECT_TRUE(sd_match(Op64, m_SExtOrSelf(m_Value(A))));634  EXPECT_TRUE(A == Op64);635  EXPECT_TRUE(sd_match(SExt, m_SExtOrSelf(m_Value(A))));636  EXPECT_TRUE(A == Op32);637  EXPECT_TRUE(sd_match(Op32, m_AExtOrSelf(m_Value(A))));638  EXPECT_TRUE(A == Op32);639  EXPECT_TRUE(sd_match(AExt, m_AExtOrSelf(m_Value(A))));640  EXPECT_TRUE(A == Op32);641  EXPECT_TRUE(sd_match(Op64, m_TruncOrSelf(m_Value(A))));642  EXPECT_TRUE(A == Op64);643  EXPECT_TRUE(sd_match(Trunc, m_TruncOrSelf(m_Value(A))));644  EXPECT_TRUE(A == Op64);645}646 647TEST_F(SelectionDAGPatternMatchTest, matchNode) {648  SDLoc DL;649  auto Int32VT = EVT::getIntegerVT(Context, 32);650 651  SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);652  SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);653 654  SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);655 656  using namespace SDPatternMatch;657  EXPECT_TRUE(sd_match(Add, m_Node(ISD::ADD, m_Value(), m_Value())));658  EXPECT_FALSE(sd_match(Add, m_Node(ISD::SUB, m_Value(), m_Value())));659  EXPECT_FALSE(sd_match(Add, m_Node(ISD::ADD, m_Value())));660  EXPECT_FALSE(661      sd_match(Add, m_Node(ISD::ADD, m_Value(), m_Value(), m_Value())));662  EXPECT_FALSE(sd_match(Add, m_Node(ISD::ADD, m_ConstInt(), m_Value())));663}664 665TEST_F(SelectionDAGPatternMatchTest, matchSelectLike) {666  SDLoc DL;667  auto Int32VT = EVT::getIntegerVT(Context, 32);668  auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);669 670  SDValue Cond = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 0, Int32VT);671  SDValue TVal = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);672  SDValue FVal = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);673 674  SDValue VCond = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 0, VInt32VT);675  SDValue VTVal = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, VInt32VT);676  SDValue VFVal = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);677 678  SDValue Select = DAG->getNode(ISD::SELECT, DL, Int32VT, Cond, TVal, FVal);679  SDValue VSelect =680      DAG->getNode(ISD::VSELECT, DL, Int32VT, VCond, VTVal, VFVal);681 682  using namespace SDPatternMatch;683  EXPECT_TRUE(sd_match(Select, m_SelectLike(m_Specific(Cond), m_Specific(TVal),684                                            m_Specific(FVal))));685  EXPECT_TRUE(686      sd_match(VSelect, m_SelectLike(m_Specific(VCond), m_Specific(VTVal),687                                     m_Specific(VFVal))));688}689 690namespace {691struct VPMatchContext : public SDPatternMatch::BasicMatchContext {692  using SDPatternMatch::BasicMatchContext::BasicMatchContext;693 694  bool match(SDValue OpVal, unsigned Opc) const {695    if (!OpVal->isVPOpcode())696      return OpVal->getOpcode() == Opc;697 698    auto BaseOpc = ISD::getBaseOpcodeForVP(OpVal->getOpcode(), false);699    return BaseOpc == Opc;700  }701 702  unsigned getNumOperands(SDValue N) const {703    return N->isVPOpcode() ? N->getNumOperands() - 2 : N->getNumOperands();704  }705};706} // anonymous namespace707TEST_F(SelectionDAGPatternMatchTest, matchContext) {708  SDLoc DL;709  auto BoolVT = EVT::getIntegerVT(Context, 1);710  auto Int32VT = EVT::getIntegerVT(Context, 32);711  auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);712  auto MaskVT = EVT::getVectorVT(Context, BoolVT, 4);713 714  SDValue Scalar0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);715  SDValue Vector0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);716  SDValue Mask0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, MaskVT);717 718  SDValue VPAdd = DAG->getNode(ISD::VP_ADD, DL, VInt32VT,719                               {Vector0, Vector0, Mask0, Scalar0});720  SDValue VPReduceAdd = DAG->getNode(ISD::VP_REDUCE_ADD, DL, Int32VT,721                                     {Scalar0, VPAdd, Mask0, Scalar0});722  SDValue Add = DAG->getNode(ISD::ADD, DL, VInt32VT, {Vector0, Vector0});723 724  using namespace SDPatternMatch;725  VPMatchContext VPCtx(DAG.get());726  EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_Opc(ISD::ADD)));727  EXPECT_TRUE(728      sd_context_match(VPAdd, VPCtx, m_Node(ISD::ADD, m_Value(), m_Value())));729  // VPMatchContext can't match pattern using explicit VP Opcode730  EXPECT_FALSE(sd_context_match(VPAdd, VPCtx,731                                m_Node(ISD::VP_ADD, m_Value(), m_Value())));732  EXPECT_FALSE(sd_context_match(733      VPAdd, VPCtx,734      m_Node(ISD::VP_ADD, m_Value(), m_Value(), m_Value(), m_Value())));735  // Check Binary Op Pattern736  EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_Add(m_Value(), m_Value())));737  // VP_REDUCE_ADD doesn't have a based opcode, so we use a normal738  // sd_match before switching to VPMatchContext when checking VPAdd.739  EXPECT_TRUE(sd_match(VPReduceAdd, m_Node(ISD::VP_REDUCE_ADD, m_Value(),740                                           m_Context(VPCtx, m_Opc(ISD::ADD)),741                                           m_Value(), m_Value())));742  // non-vector predicated should match too743  EXPECT_TRUE(sd_context_match(Add, VPCtx, m_Opc(ISD::ADD)));744  EXPECT_TRUE(745      sd_context_match(Add, VPCtx, m_Node(ISD::ADD, m_Value(), m_Value())));746  EXPECT_FALSE(sd_context_match(747      Add, VPCtx,748      m_Node(ISD::ADD, m_Value(), m_Value(), m_Value(), m_Value())));749  EXPECT_TRUE(sd_context_match(Add, VPCtx, m_Add(m_Value(), m_Value())));750}751 752TEST_F(SelectionDAGPatternMatchTest, matchVPWithBasicContext) {753  SDLoc DL;754  auto BoolVT = EVT::getIntegerVT(Context, 1);755  auto Int32VT = EVT::getIntegerVT(Context, 32);756  auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);757  auto MaskVT = EVT::getVectorVT(Context, BoolVT, 4);758 759  SDValue Vector0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, VInt32VT);760  SDValue Mask = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, MaskVT);761  SDValue EL = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int32VT);762 763  SDValue VPAdd =764      DAG->getNode(ISD::VP_ADD, DL, VInt32VT, Vector0, Vector0, Mask, EL);765 766  using namespace SDPatternMatch;767  EXPECT_FALSE(sd_match(VPAdd, m_Node(ISD::VP_ADD, m_Value(), m_Value())));768  EXPECT_TRUE(sd_match(769      VPAdd, m_Node(ISD::VP_ADD, m_Value(), m_Value(), m_Value(), m_Value())));770}771 772TEST_F(SelectionDAGPatternMatchTest, matchAdvancedProperties) {773  SDLoc DL;774  auto Int16VT = EVT::getIntegerVT(Context, 16);775  auto Int64VT = EVT::getIntegerVT(Context, 64);776 777  SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);778  SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int16VT);779 780  SDValue Add = DAG->getNode(ISD::ADD, DL, Int64VT, Op0, Op0);781 782  using namespace SDPatternMatch;783  EXPECT_TRUE(sd_match(Op0, DAG.get(), m_LegalType(m_Value())));784  EXPECT_FALSE(sd_match(Op1, DAG.get(), m_LegalType(m_Value())));785  EXPECT_TRUE(sd_match(Add, DAG.get(),786                       m_LegalOp(m_IntegerVT(m_Add(m_Value(), m_Value())))));787}788 789TEST_F(SelectionDAGPatternMatchTest, matchReassociatableOp) {790  using namespace SDPatternMatch;791 792  SDLoc DL;793  auto Int32VT = EVT::getIntegerVT(Context, 32);794 795  SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);796  SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);797  SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int32VT);798  SDValue Op3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 8, Int32VT);799 800  // (Op0 + Op1) + (Op2 + Op3)801  SDValue ADD01 = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);802  SDValue ADD23 = DAG->getNode(ISD::ADD, DL, Int32VT, Op2, Op3);803  SDValue ADD = DAG->getNode(ISD::ADD, DL, Int32VT, ADD01, ADD23);804 805  EXPECT_FALSE(sd_match(ADD01, m_ReassociatableAdd(m_Value())));806  EXPECT_TRUE(sd_match(ADD01, m_ReassociatableAdd(m_Value(), m_Value())));807  EXPECT_TRUE(sd_match(ADD23, m_ReassociatableAdd(m_Value(), m_Value())));808  EXPECT_TRUE(sd_match(809      ADD, m_ReassociatableAdd(m_Value(), m_Value(), m_Value(), m_Value())));810 811  // Op0 + (Op1 + (Op2 + Op3))812  SDValue ADD123 = DAG->getNode(ISD::ADD, DL, Int32VT, Op1, ADD23);813  SDValue ADD0123 = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, ADD123);814  EXPECT_TRUE(815      sd_match(ADD123, m_ReassociatableAdd(m_Value(), m_Value(), m_Value())));816  EXPECT_TRUE(sd_match(ADD0123, m_ReassociatableAdd(m_Value(), m_Value(),817                                                    m_Value(), m_Value())));818 819  // (Op0 - Op1) + (Op2 - Op3)820  SDValue SUB01 = DAG->getNode(ISD::SUB, DL, Int32VT, Op0, Op1);821  SDValue SUB23 = DAG->getNode(ISD::SUB, DL, Int32VT, Op2, Op3);822  SDValue ADDS0123 = DAG->getNode(ISD::ADD, DL, Int32VT, SUB01, SUB23);823 824  EXPECT_FALSE(sd_match(SUB01, m_ReassociatableAdd(m_Value(), m_Value())));825  EXPECT_FALSE(sd_match(ADDS0123, m_ReassociatableAdd(m_Value(), m_Value(),826                                                      m_Value(), m_Value())));827 828  // SUB + SUB matches (Op0 - Op1) + (Op2 - Op3)829  EXPECT_TRUE(830      sd_match(ADDS0123, m_ReassociatableAdd(m_Sub(m_Value(), m_Value()),831                                             m_Sub(m_Value(), m_Value()))));832  EXPECT_FALSE(sd_match(ADDS0123, m_ReassociatableAdd(m_Value(), m_Value(),833                                                      m_Value(), m_Value())));834 835  // (Op0 * Op1) * (Op2 * Op3)836  SDValue MUL01 = DAG->getNode(ISD::MUL, DL, Int32VT, Op0, Op1);837  SDValue MUL23 = DAG->getNode(ISD::MUL, DL, Int32VT, Op2, Op3);838  SDValue MUL = DAG->getNode(ISD::MUL, DL, Int32VT, MUL01, MUL23);839 840  EXPECT_TRUE(sd_match(MUL01, m_ReassociatableMul(m_Value(), m_Value())));841  EXPECT_TRUE(sd_match(MUL23, m_ReassociatableMul(m_Value(), m_Value())));842  EXPECT_TRUE(sd_match(843      MUL, m_ReassociatableMul(m_Value(), m_Value(), m_Value(), m_Value())));844 845  // Op0 * (Op1 * (Op2 * Op3))846  SDValue MUL123 = DAG->getNode(ISD::MUL, DL, Int32VT, Op1, MUL23);847  SDValue MUL0123 = DAG->getNode(ISD::MUL, DL, Int32VT, Op0, MUL123);848  EXPECT_TRUE(849      sd_match(MUL123, m_ReassociatableMul(m_Value(), m_Value(), m_Value())));850  EXPECT_TRUE(sd_match(MUL0123, m_ReassociatableMul(m_Value(), m_Value(),851                                                    m_Value(), m_Value())));852 853  // (Op0 - Op1) * (Op2 - Op3)854  SDValue MULS0123 = DAG->getNode(ISD::MUL, DL, Int32VT, SUB01, SUB23);855  EXPECT_TRUE(856      sd_match(MULS0123, m_ReassociatableMul(m_Sub(m_Value(), m_Value()),857                                             m_Sub(m_Value(), m_Value()))));858  EXPECT_FALSE(sd_match(MULS0123, m_ReassociatableMul(m_Value(), m_Value(),859                                                      m_Value(), m_Value())));860 861  // (Op0 && Op1) && (Op2 && Op3)862  SDValue AND01 = DAG->getNode(ISD::AND, DL, Int32VT, Op0, Op1);863  SDValue AND23 = DAG->getNode(ISD::AND, DL, Int32VT, Op2, Op3);864  SDValue AND = DAG->getNode(ISD::AND, DL, Int32VT, AND01, AND23);865 866  EXPECT_TRUE(sd_match(AND01, m_ReassociatableAnd(m_Value(), m_Value())));867  EXPECT_TRUE(sd_match(AND23, m_ReassociatableAnd(m_Value(), m_Value())));868  EXPECT_TRUE(sd_match(869      AND, m_ReassociatableAnd(m_Value(), m_Value(), m_Value(), m_Value())));870 871  // Op0 && (Op1 && (Op2 && Op3))872  SDValue AND123 = DAG->getNode(ISD::AND, DL, Int32VT, Op1, AND23);873  SDValue AND0123 = DAG->getNode(ISD::AND, DL, Int32VT, Op0, AND123);874  EXPECT_TRUE(875      sd_match(AND123, m_ReassociatableAnd(m_Value(), m_Value(), m_Value())));876  EXPECT_TRUE(sd_match(AND0123, m_ReassociatableAnd(m_Value(), m_Value(),877                                                    m_Value(), m_Value())));878 879  // (Op0 - Op1) && (Op2 - Op3)880  SDValue ANDS0123 = DAG->getNode(ISD::AND, DL, Int32VT, SUB01, SUB23);881  EXPECT_TRUE(882      sd_match(ANDS0123, m_ReassociatableAnd(m_Sub(m_Value(), m_Value()),883                                             m_Sub(m_Value(), m_Value()))));884  EXPECT_FALSE(sd_match(ANDS0123, m_ReassociatableAnd(m_Value(), m_Value(),885                                                      m_Value(), m_Value())));886 887  // (Op0 || Op1) || (Op2 || Op3)888  SDValue OR01 = DAG->getNode(ISD::OR, DL, Int32VT, Op0, Op1);889  SDValue OR23 = DAG->getNode(ISD::OR, DL, Int32VT, Op2, Op3);890  SDValue OR = DAG->getNode(ISD::OR, DL, Int32VT, OR01, OR23);891 892  EXPECT_TRUE(sd_match(OR01, m_ReassociatableOr(m_Value(), m_Value())));893  EXPECT_TRUE(sd_match(OR23, m_ReassociatableOr(m_Value(), m_Value())));894  EXPECT_TRUE(sd_match(895      OR, m_ReassociatableOr(m_Value(), m_Value(), m_Value(), m_Value())));896 897  // Op0 || (Op1 || (Op2 || Op3))898  SDValue OR123 = DAG->getNode(ISD::OR, DL, Int32VT, Op1, OR23);899  SDValue OR0123 = DAG->getNode(ISD::OR, DL, Int32VT, Op0, OR123);900  EXPECT_TRUE(901      sd_match(OR123, m_ReassociatableOr(m_Value(), m_Value(), m_Value())));902  EXPECT_TRUE(sd_match(903      OR0123, m_ReassociatableOr(m_Value(), m_Value(), m_Value(), m_Value())));904 905  // (Op0 - Op1) || (Op2 - Op3)906  SDValue ORS0123 = DAG->getNode(ISD::OR, DL, Int32VT, SUB01, SUB23);907  EXPECT_TRUE(908      sd_match(ORS0123, m_ReassociatableOr(m_Sub(m_Value(), m_Value()),909                                           m_Sub(m_Value(), m_Value()))));910  EXPECT_FALSE(sd_match(911      ORS0123, m_ReassociatableOr(m_Value(), m_Value(), m_Value(), m_Value())));912}913 914TEST_F(SelectionDAGPatternMatchTest, MatchZeroOneAllOnes) {915  using namespace SDPatternMatch;916 917  SDLoc DL;918  EVT VT = EVT::getIntegerVT(Context, 32);919 920  // Scalar constant 0921  SDValue Zero = DAG->getConstant(0, DL, VT);922  EXPECT_TRUE(sd_match(Zero, DAG.get(), m_Zero()));923  EXPECT_FALSE(sd_match(Zero, DAG.get(), m_One()));924  EXPECT_FALSE(sd_match(Zero, DAG.get(), m_AllOnes()));925 926  // Scalar constant 1927  SDValue One = DAG->getConstant(1, DL, VT);928  EXPECT_FALSE(sd_match(One, DAG.get(), m_Zero()));929  EXPECT_TRUE(sd_match(One, DAG.get(), m_One()));930  EXPECT_FALSE(sd_match(One, DAG.get(), m_AllOnes()));931 932  // Scalar constant -1933  SDValue AllOnes =934      DAG->getConstant(APInt::getAllOnes(VT.getSizeInBits()), DL, VT);935  EXPECT_FALSE(sd_match(AllOnes, DAG.get(), m_Zero()));936  EXPECT_FALSE(sd_match(AllOnes, DAG.get(), m_One()));937  EXPECT_TRUE(sd_match(AllOnes, DAG.get(), m_AllOnes()));938 939  EVT VecF32 = EVT::getVectorVT(Context, MVT::f32, 4);940  EVT VecVT = EVT::getVectorVT(Context, MVT::i32, 4);941 942  // m_Zero: splat vector of 0 → bitcast943  {944    SDValue SplatVal = DAG->getConstant(0, DL, MVT::i32);945    SDValue VecSplat = DAG->getSplatBuildVector(VecVT, DL, SplatVal);946    SDValue Bitcasted = DAG->getNode(ISD::BITCAST, DL, VecF32, VecSplat);947    EXPECT_TRUE(sd_match(Bitcasted, DAG.get(), m_Zero()));948  }949 950  // m_One: splat vector of 1 → bitcast951  {952    SDValue SplatVal = DAG->getConstant(1, DL, MVT::i32);953    SDValue VecSplat = DAG->getSplatBuildVector(VecVT, DL, SplatVal);954    SDValue Bitcasted = DAG->getNode(ISD::BITCAST, DL, VecF32, VecSplat);955    EXPECT_FALSE(sd_match(Bitcasted, DAG.get(), m_One()));956  }957 958  // m_AllOnes: splat vector of -1 → bitcast959  {960    SDValue SplatVal = DAG->getConstant(APInt::getAllOnes(32), DL, MVT::i32);961    SDValue VecSplat = DAG->getSplatBuildVector(VecVT, DL, SplatVal);962    SDValue Bitcasted = DAG->getNode(ISD::BITCAST, DL, VecF32, VecSplat);963    EXPECT_TRUE(sd_match(Bitcasted, DAG.get(), m_AllOnes()));964  }965 966  // splat vector with one undef → default should NOT match967  SDValue Undef = DAG->getUNDEF(MVT::i32);968 969  {970    // m_Zero: Undef + constant 0971    SDValue Zero = DAG->getConstant(0, DL, MVT::i32);972    SmallVector<SDValue, 4> Ops(4, Zero);973    Ops[2] = Undef;974    SDValue Vec = DAG->getBuildVector(VecVT, DL, Ops);975    EXPECT_FALSE(sd_match(Vec, DAG.get(), m_Zero()));976    EXPECT_TRUE(sd_match(Vec, DAG.get(), m_Zero(true)));977  }978 979  {980    // m_One: Undef + constant 1981    SDValue One = DAG->getConstant(1, DL, MVT::i32);982    SmallVector<SDValue, 4> Ops(4, One);983    Ops[1] = Undef;984    SDValue Vec = DAG->getBuildVector(VecVT, DL, Ops);985    EXPECT_FALSE(sd_match(Vec, DAG.get(), m_One()));986    EXPECT_TRUE(sd_match(Vec, DAG.get(), m_One(true)));987  }988 989  {990    // m_AllOnes: Undef + constant -1991    SDValue AllOnes = DAG->getConstant(APInt::getAllOnes(32), DL, MVT::i32);992    SmallVector<SDValue, 4> Ops(4, AllOnes);993    Ops[0] = Undef;994    SDValue Vec = DAG->getBuildVector(VecVT, DL, Ops);995    EXPECT_FALSE(sd_match(Vec, DAG.get(), m_AllOnes()));996    EXPECT_TRUE(sd_match(Vec, DAG.get(), m_AllOnes(true)));997  }998}999 1000TEST_F(SelectionDAGPatternMatchTest, MatchSelectCCLike) {1001  using namespace SDPatternMatch;1002 1003  SDValue LHS = DAG->getConstant(1, SDLoc(), MVT::i32);1004  SDValue RHS = DAG->getConstant(2, SDLoc(), MVT::i32);1005  SDValue TVal = DAG->getConstant(3, SDLoc(), MVT::i32);1006  SDValue FVal = DAG->getConstant(4, SDLoc(), MVT::i32);1007  SDValue Select = DAG->getNode(ISD::SELECT_CC, SDLoc(), MVT::i32, LHS, RHS,1008                                TVal, FVal, DAG->getCondCode(ISD::SETLT));1009 1010  ISD::CondCode CC = ISD::SETLT;1011  EXPECT_TRUE(sd_match(1012      Select, m_SelectCCLike(m_Specific(LHS), m_Specific(RHS), m_Specific(TVal),1013                             m_Specific(FVal), m_CondCode(CC))));1014}1015 1016TEST_F(SelectionDAGPatternMatchTest, MatchSelectCC) {1017  using namespace SDPatternMatch;1018 1019  SDValue LHS = DAG->getConstant(1, SDLoc(), MVT::i32);1020  SDValue RHS = DAG->getConstant(2, SDLoc(), MVT::i32);1021  SDValue TVal = DAG->getConstant(3, SDLoc(), MVT::i32);1022  SDValue FVal = DAG->getConstant(4, SDLoc(), MVT::i32);1023  SDValue Select = DAG->getNode(ISD::SELECT_CC, SDLoc(), MVT::i32, LHS, RHS,1024                                TVal, FVal, DAG->getCondCode(ISD::SETLT));1025 1026  ISD::CondCode CC = ISD::SETLT;1027  EXPECT_TRUE(sd_match(Select, m_SelectCC(m_Specific(LHS), m_Specific(RHS),1028                                          m_Specific(TVal), m_Specific(FVal),1029                                          m_CondCode(CC))));1030}1031