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