xref: /llvm-project/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp (revision bacfdcd7e0989117a3c76b040fe9efe093fa8708)
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/CodeGen/MachineModuleInfo.h"
12 #include "llvm/CodeGen/SDPatternMatch.h"
13 #include "llvm/CodeGen/TargetLowering.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/MC/TargetRegistry.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "llvm/Support/TargetSelect.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "gtest/gtest.h"
20 
21 using namespace llvm;
22 
23 class SelectionDAGPatternMatchTest : public testing::Test {
24 protected:
25   static void SetUpTestCase() {
26     InitializeAllTargets();
27     InitializeAllTargetMCs();
28   }
29 
30   void SetUp() override {
31     StringRef Assembly = "@g = global i32 0\n"
32                          "@g_alias = alias i32, i32* @g\n"
33                          "define i32 @f() {\n"
34                          "  %1 = load i32, i32* @g\n"
35                          "  ret i32 %1\n"
36                          "}";
37 
38     Triple TargetTriple("riscv64--");
39     std::string Error;
40     const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
41     // FIXME: These tests do not depend on RISCV specifically, but we have to
42     // initialize a target. A skeleton Target for unittests would allow us to
43     // always run these tests.
44     if (!T)
45       GTEST_SKIP();
46 
47     TargetOptions Options;
48     TM = std::unique_ptr<TargetMachine>(T->createTargetMachine(
49         "riscv64", "", "+m,+f,+d,+v", Options, std::nullopt, std::nullopt,
50         CodeGenOptLevel::Aggressive));
51     if (!TM)
52       GTEST_SKIP();
53 
54     SMDiagnostic SMError;
55     M = parseAssemblyString(Assembly, SMError, Context);
56     if (!M)
57       report_fatal_error(SMError.getMessage());
58     M->setDataLayout(TM->createDataLayout());
59 
60     F = M->getFunction("f");
61     if (!F)
62       report_fatal_error("F?");
63     G = M->getGlobalVariable("g");
64     if (!G)
65       report_fatal_error("G?");
66     AliasedG = M->getNamedAlias("g_alias");
67     if (!AliasedG)
68       report_fatal_error("AliasedG?");
69 
70     MachineModuleInfo MMI(TM.get());
71 
72     MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F),
73                                            MMI.getContext(), 0);
74 
75     DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None);
76     if (!DAG)
77       report_fatal_error("DAG?");
78     OptimizationRemarkEmitter ORE(F);
79     DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, MMI,
80               nullptr);
81   }
82 
83   TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) {
84     return DAG->getTargetLoweringInfo().getTypeAction(Context, VT);
85   }
86 
87   EVT getTypeToTransformTo(EVT VT) {
88     return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT);
89   }
90 
91   LLVMContext Context;
92   std::unique_ptr<TargetMachine> TM;
93   std::unique_ptr<Module> M;
94   Function *F;
95   GlobalVariable *G;
96   GlobalAlias *AliasedG;
97   std::unique_ptr<MachineFunction> MF;
98   std::unique_ptr<SelectionDAG> DAG;
99 };
100 
101 TEST_F(SelectionDAGPatternMatchTest, matchValueType) {
102   SDLoc DL;
103   auto Int32VT = EVT::getIntegerVT(Context, 32);
104   auto Float32VT = EVT::getFloatingPointVT(32);
105   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
106 
107   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
108   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Float32VT);
109   SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);
110 
111   using namespace SDPatternMatch;
112   EXPECT_TRUE(sd_match(Op0, m_SpecificVT(Int32VT)));
113   EVT BindVT;
114   EXPECT_TRUE(sd_match(Op1, m_VT(BindVT)));
115   EXPECT_EQ(BindVT, Float32VT);
116   EXPECT_TRUE(sd_match(Op0, m_IntegerVT()));
117   EXPECT_TRUE(sd_match(Op1, m_FloatingPointVT()));
118   EXPECT_TRUE(sd_match(Op2, m_VectorVT()));
119   EXPECT_FALSE(sd_match(Op2, m_ScalableVectorVT()));
120 }
121 
122 TEST_F(SelectionDAGPatternMatchTest, matchVecShuffle) {
123   SDLoc DL;
124   auto Int32VT = EVT::getIntegerVT(Context, 32);
125   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
126   const std::array<int, 4> MaskData = {2, 0, 3, 1};
127   const std::array<int, 4> OtherMaskData = {1, 2, 3, 4};
128   ArrayRef<int> Mask;
129 
130   SDValue V0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, VInt32VT);
131   SDValue V1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);
132   SDValue VecShuffleWithMask =
133       DAG->getVectorShuffle(VInt32VT, DL, V0, V1, MaskData);
134 
135   using namespace SDPatternMatch;
136   EXPECT_TRUE(sd_match(VecShuffleWithMask, m_Shuffle(m_Value(), m_Value())));
137   EXPECT_TRUE(sd_match(VecShuffleWithMask,
138                        m_Shuffle(m_Value(), m_Value(), m_Mask(Mask))));
139   EXPECT_TRUE(
140       sd_match(VecShuffleWithMask,
141                m_Shuffle(m_Value(), m_Value(), m_SpecificMask(MaskData))));
142   EXPECT_FALSE(
143       sd_match(VecShuffleWithMask,
144                m_Shuffle(m_Value(), m_Value(), m_SpecificMask(OtherMaskData))));
145   EXPECT_TRUE(
146       std::equal(MaskData.begin(), MaskData.end(), Mask.begin(), Mask.end()));
147 }
148 
149 TEST_F(SelectionDAGPatternMatchTest, matchTernaryOp) {
150   SDLoc DL;
151   auto Int32VT = EVT::getIntegerVT(Context, 32);
152 
153   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
154   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
155   SDValue Op3 = DAG->getConstant(1, DL, Int32VT);
156 
157   SDValue ICMP_UGT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGT);
158   SDValue ICMP_EQ01 = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETEQ);
159   SDValue ICMP_EQ10 = DAG->getSetCC(DL, MVT::i1, Op1, Op0, ISD::SETEQ);
160 
161   auto Int1VT = EVT::getIntegerVT(Context, 1);
162   SDValue Cond = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int1VT);
163   SDValue T = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 4, Int1VT);
164   SDValue F = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 5, Int1VT);
165   SDValue Select = DAG->getSelect(DL, MVT::i1, Cond, T, F);
166 
167   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
168   auto SmallVInt32VT = EVT::getVectorVT(Context, Int32VT, 2);
169   auto Idx0 = DAG->getVectorIdxConstant(0, DL);
170   auto Idx3 = DAG->getVectorIdxConstant(3, DL);
171   SDValue V1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 6, VInt32VT);
172   SDValue V2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 7, VInt32VT);
173   SDValue V3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 8, SmallVInt32VT);
174   SDValue VSelect = DAG->getNode(ISD::VSELECT, DL, VInt32VT, Cond, V1, V2);
175   SDValue InsertSubvector =
176       DAG->getNode(ISD::INSERT_SUBVECTOR, DL, VInt32VT, V2, V3, Idx0);
177 
178   SDValue ExtractELT =
179       DAG->getNode(ISD::EXTRACT_VECTOR_ELT, DL, Int32VT, V1, Op3);
180 
181   using namespace SDPatternMatch;
182   ISD::CondCode CC;
183   EXPECT_TRUE(sd_match(ICMP_UGT, m_SetCC(m_Value(), m_Value(),
184                                          m_SpecificCondCode(ISD::SETUGT))));
185   EXPECT_TRUE(
186       sd_match(ICMP_UGT, m_SetCC(m_Value(), m_Value(), m_CondCode(CC))));
187   EXPECT_TRUE(CC == ISD::SETUGT);
188   EXPECT_FALSE(sd_match(
189       ICMP_UGT, m_SetCC(m_Value(), m_Value(), m_SpecificCondCode(ISD::SETLE))));
190 
191   EXPECT_TRUE(sd_match(ICMP_EQ01, m_SetCC(m_Specific(Op0), m_Specific(Op1),
192                                           m_SpecificCondCode(ISD::SETEQ))));
193   EXPECT_TRUE(sd_match(ICMP_EQ10, m_SetCC(m_Specific(Op1), m_Specific(Op0),
194                                           m_SpecificCondCode(ISD::SETEQ))));
195   EXPECT_FALSE(sd_match(ICMP_EQ01, m_SetCC(m_Specific(Op1), m_Specific(Op0),
196                                            m_SpecificCondCode(ISD::SETEQ))));
197   EXPECT_FALSE(sd_match(ICMP_EQ10, m_SetCC(m_Specific(Op0), m_Specific(Op1),
198                                            m_SpecificCondCode(ISD::SETEQ))));
199   EXPECT_TRUE(sd_match(ICMP_EQ01, m_c_SetCC(m_Specific(Op1), m_Specific(Op0),
200                                             m_SpecificCondCode(ISD::SETEQ))));
201   EXPECT_TRUE(sd_match(ICMP_EQ10, m_c_SetCC(m_Specific(Op0), m_Specific(Op1),
202                                             m_SpecificCondCode(ISD::SETEQ))));
203 
204   EXPECT_TRUE(sd_match(
205       Select, m_Select(m_Specific(Cond), m_Specific(T), m_Specific(F))));
206   EXPECT_FALSE(sd_match(
207       Select, m_Select(m_Specific(Cond), m_Specific(F), m_Specific(T))));
208   EXPECT_FALSE(sd_match(ICMP_EQ01, m_Select(m_Specific(Op0), m_Specific(Op1),
209                                             m_SpecificCondCode(ISD::SETEQ))));
210   EXPECT_TRUE(sd_match(
211       VSelect, m_VSelect(m_Specific(Cond), m_Specific(V1), m_Specific(V2))));
212   EXPECT_FALSE(sd_match(
213       Select, m_VSelect(m_Specific(Cond), m_Specific(V1), m_Specific(V2))));
214 
215   EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_Value())));
216   EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_ConstInt())));
217   EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_SpecificInt(1))));
218 
219   EXPECT_TRUE(sd_match(InsertSubvector,
220                        m_InsertSubvector(m_Value(), m_Value(), m_Value())));
221   EXPECT_TRUE(sd_match(
222       InsertSubvector,
223       m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_Specific(Idx0))));
224   EXPECT_TRUE(sd_match(
225       InsertSubvector,
226       m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_SpecificInt(0))));
227   EXPECT_FALSE(sd_match(
228       InsertSubvector,
229       m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_Specific(Idx3))));
230   EXPECT_FALSE(sd_match(
231       InsertSubvector,
232       m_InsertSubvector(m_Specific(V2), m_Specific(V3), m_SpecificInt(3))));
233 }
234 
235 TEST_F(SelectionDAGPatternMatchTest, matchBinaryOp) {
236   SDLoc DL;
237   auto Int32VT = EVT::getIntegerVT(Context, 32);
238   auto Float32VT = EVT::getFloatingPointVT(32);
239   auto BigVInt32VT = EVT::getVectorVT(Context, Int32VT, 8);
240   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
241 
242   SDValue V1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 6, VInt32VT);
243   auto Idx0 = DAG->getVectorIdxConstant(0, DL);
244   auto Idx1 = DAG->getVectorIdxConstant(1, DL);
245 
246   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
247   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
248   SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Float32VT);
249   SDValue Op3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 8, Int32VT);
250   SDValue Op4 = DAG->getConstant(1, DL, Int32VT);
251 
252   SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);
253   SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Add, Op0);
254   SDValue Mul = DAG->getNode(ISD::MUL, DL, Int32VT, Add, Sub);
255   SDValue And = DAG->getNode(ISD::AND, DL, Int32VT, Op0, Op1);
256   SDValue Xor = DAG->getNode(ISD::XOR, DL, Int32VT, Op1, Op0);
257   SDValue Or  = DAG->getNode(ISD::OR, DL, Int32VT, Op0, Op1);
258   SDValue DisOr =
259       DAG->getNode(ISD::OR, DL, Int32VT, Op0, Op3, SDNodeFlags::Disjoint);
260   SDValue SMax = DAG->getNode(ISD::SMAX, DL, Int32VT, Op0, Op1);
261   SDValue SMin = DAG->getNode(ISD::SMIN, DL, Int32VT, Op1, Op0);
262   SDValue UMax = DAG->getNode(ISD::UMAX, DL, Int32VT, Op0, Op1);
263   SDValue UMin = DAG->getNode(ISD::UMIN, DL, Int32VT, Op1, Op0);
264   SDValue Rotl = DAG->getNode(ISD::ROTL, DL, Int32VT, Op0, Op1);
265   SDValue Rotr = DAG->getNode(ISD::ROTR, DL, Int32VT, Op1, Op0);
266 
267   SDValue ICMP_GT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETGT);
268   SDValue ICMP_GE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETGE);
269   SDValue ICMP_UGT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGT);
270   SDValue ICMP_UGE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGE);
271   SDValue ICMP_LT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETLT);
272   SDValue ICMP_LE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETLE);
273   SDValue ICMP_ULT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETULT);
274   SDValue ICMP_ULE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETULE);
275   SDValue SMaxLikeGT = DAG->getSelect(DL, MVT::i32, ICMP_GT, Op0, Op1);
276   SDValue SMaxLikeGE = DAG->getSelect(DL, MVT::i32, ICMP_GE, Op0, Op1);
277   SDValue UMaxLikeUGT = DAG->getSelect(DL, MVT::i32, ICMP_UGT, Op0, Op1);
278   SDValue UMaxLikeUGE = DAG->getSelect(DL, MVT::i32, ICMP_UGE, Op0, Op1);
279   SDValue SMinLikeLT = DAG->getSelect(DL, MVT::i32, ICMP_LT, Op0, Op1);
280   SDValue SMinLikeLE = DAG->getSelect(DL, MVT::i32, ICMP_LE, Op0, Op1);
281   SDValue UMinLikeULT = DAG->getSelect(DL, MVT::i32, ICMP_ULT, Op0, Op1);
282   SDValue UMinLikeULE = DAG->getSelect(DL, MVT::i32, ICMP_ULE, Op0, Op1);
283 
284   SDValue SFAdd = DAG->getNode(ISD::STRICT_FADD, DL, {Float32VT, MVT::Other},
285                                {DAG->getEntryNode(), Op2, Op2});
286 
287   SDValue Vec = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 9, BigVInt32VT);
288   SDValue SubVec =
289       DAG->getNode(ISD::EXTRACT_SUBVECTOR, DL, VInt32VT, Vec, Idx0);
290 
291   SDValue InsertELT =
292       DAG->getNode(ISD::INSERT_VECTOR_ELT, DL, VInt32VT, V1, Op0, Op4);
293 
294   using namespace SDPatternMatch;
295   EXPECT_TRUE(sd_match(Sub, m_BinOp(ISD::SUB, m_Value(), m_Value())));
296   EXPECT_TRUE(sd_match(Sub, m_Sub(m_Value(), m_Value())));
297   EXPECT_TRUE(sd_match(Add, m_c_BinOp(ISD::ADD, m_Value(), m_Value())));
298   EXPECT_TRUE(sd_match(Add, m_Add(m_Value(), m_Value())));
299   EXPECT_TRUE(sd_match(Add, m_AddLike(m_Value(), m_Value())));
300   EXPECT_TRUE(sd_match(
301       Mul, m_Mul(m_OneUse(m_Opc(ISD::SUB)), m_NUses<2>(m_Specific(Add)))));
302   EXPECT_TRUE(
303       sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_SpecificVT(Float32VT),
304                                      m_SpecificVT(Float32VT))));
305 
306   EXPECT_TRUE(sd_match(And, m_c_BinOp(ISD::AND, m_Value(), m_Value())));
307   EXPECT_TRUE(sd_match(And, m_And(m_Value(), m_Value())));
308   EXPECT_TRUE(sd_match(Xor, m_c_BinOp(ISD::XOR, m_Value(), m_Value())));
309   EXPECT_TRUE(sd_match(Xor, m_Xor(m_Value(), m_Value())));
310   EXPECT_TRUE(sd_match(Or, m_c_BinOp(ISD::OR, m_Value(), m_Value())));
311   EXPECT_TRUE(sd_match(Or, m_Or(m_Value(), m_Value())));
312   EXPECT_FALSE(sd_match(Or, m_DisjointOr(m_Value(), m_Value())));
313 
314   EXPECT_TRUE(sd_match(DisOr, m_Or(m_Value(), m_Value())));
315   EXPECT_TRUE(sd_match(DisOr, m_DisjointOr(m_Value(), m_Value())));
316   EXPECT_FALSE(sd_match(DisOr, m_Add(m_Value(), m_Value())));
317   EXPECT_TRUE(sd_match(DisOr, m_AddLike(m_Value(), m_Value())));
318 
319   EXPECT_TRUE(sd_match(Rotl, m_Rotl(m_Value(), m_Value())));
320   EXPECT_TRUE(sd_match(Rotr, m_Rotr(m_Value(), m_Value())));
321   EXPECT_FALSE(sd_match(Rotl, m_Rotr(m_Value(), m_Value())));
322   EXPECT_FALSE(sd_match(Rotr, m_Rotl(m_Value(), m_Value())));
323 
324   EXPECT_TRUE(sd_match(SMax, m_c_BinOp(ISD::SMAX, m_Value(), m_Value())));
325   EXPECT_TRUE(sd_match(SMax, m_SMax(m_Value(), m_Value())));
326   EXPECT_TRUE(sd_match(SMax, m_SMaxLike(m_Value(), m_Value())));
327   EXPECT_TRUE(sd_match(SMaxLikeGT, m_SMaxLike(m_Value(), m_Value())));
328   EXPECT_TRUE(sd_match(SMaxLikeGE, m_SMaxLike(m_Value(), m_Value())));
329   EXPECT_TRUE(sd_match(SMin, m_c_BinOp(ISD::SMIN, m_Value(), m_Value())));
330   EXPECT_TRUE(sd_match(SMin, m_SMin(m_Value(), m_Value())));
331   EXPECT_TRUE(sd_match(SMin, m_SMinLike(m_Value(), m_Value())));
332   EXPECT_TRUE(sd_match(SMinLikeLT, m_SMinLike(m_Value(), m_Value())));
333   EXPECT_TRUE(sd_match(SMinLikeLE, m_SMinLike(m_Value(), m_Value())));
334   EXPECT_TRUE(sd_match(UMax, m_c_BinOp(ISD::UMAX, m_Value(), m_Value())));
335   EXPECT_TRUE(sd_match(UMax, m_UMax(m_Value(), m_Value())));
336   EXPECT_TRUE(sd_match(UMax, m_UMaxLike(m_Value(), m_Value())));
337   EXPECT_TRUE(sd_match(UMaxLikeUGT, m_UMaxLike(m_Value(), m_Value())));
338   EXPECT_TRUE(sd_match(UMaxLikeUGE, m_UMaxLike(m_Value(), m_Value())));
339   EXPECT_TRUE(sd_match(UMin, m_c_BinOp(ISD::UMIN, m_Value(), m_Value())));
340   EXPECT_TRUE(sd_match(UMin, m_UMin(m_Value(), m_Value())));
341   EXPECT_TRUE(sd_match(UMin, m_UMinLike(m_Value(), m_Value())));
342   EXPECT_TRUE(sd_match(UMinLikeULT, m_UMinLike(m_Value(), m_Value())));
343   EXPECT_TRUE(sd_match(UMinLikeULE, m_UMinLike(m_Value(), m_Value())));
344 
345   SDValue BindVal;
346   EXPECT_TRUE(sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_Value(BindVal),
347                                              m_Deferred(BindVal))));
348   EXPECT_FALSE(sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_OtherVT(),
349                                               m_SpecificVT(Float32VT))));
350 
351   EXPECT_TRUE(sd_match(SubVec, m_ExtractSubvector(m_Value(), m_Value())));
352   EXPECT_TRUE(
353       sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_Specific(Idx0))));
354   EXPECT_TRUE(
355       sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_SpecificInt(0))));
356   EXPECT_FALSE(
357       sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_Specific(Idx1))));
358   EXPECT_FALSE(
359       sd_match(SubVec, m_ExtractSubvector(m_Specific(Vec), m_SpecificInt(1))));
360 
361   EXPECT_TRUE(
362       sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_Value())));
363   EXPECT_TRUE(
364       sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_ConstInt())));
365   EXPECT_TRUE(
366       sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_SpecificInt(1))));
367 }
368 
369 TEST_F(SelectionDAGPatternMatchTest, matchUnaryOp) {
370   SDLoc DL;
371   auto Int32VT = EVT::getIntegerVT(Context, 32);
372   auto Int64VT = EVT::getIntegerVT(Context, 64);
373   auto FloatVT = EVT::getFloatingPointVT(32);
374 
375   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
376   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);
377   SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, FloatVT);
378   SDValue Op3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int32VT);
379 
380   SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op0);
381   SDValue ZExtNNeg =
382       DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op3, SDNodeFlags::NonNeg);
383   SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op0);
384   SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op1);
385 
386   SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Trunc, Op0);
387   SDValue Neg = DAG->getNegative(Op0, DL, Int32VT);
388   SDValue Not = DAG->getNOT(DL, Op0, Int32VT);
389 
390   SDValue VScale = DAG->getVScale(DL, Int32VT, APInt::getMaxValue(32));
391 
392   SDValue FPToSI = DAG->getNode(ISD::FP_TO_SINT, DL, FloatVT, Op2);
393   SDValue FPToUI = DAG->getNode(ISD::FP_TO_UINT, DL, FloatVT, Op2);
394 
395   SDValue Bcast = DAG->getNode(ISD::BITCAST, DL, FloatVT, Op0);
396   SDValue Brev = DAG->getNode(ISD::BITREVERSE, DL, Int32VT, Op0);
397   SDValue Bswap = DAG->getNode(ISD::BSWAP, DL, Int32VT, Op0);
398 
399   SDValue Ctpop = DAG->getNode(ISD::CTPOP, DL, Int32VT, Op0);
400   SDValue Ctlz = DAG->getNode(ISD::CTLZ, DL, Int32VT, Op0);
401   SDValue Cttz = DAG->getNode(ISD::CTTZ, DL, Int32VT, Op0);
402 
403   using namespace SDPatternMatch;
404   EXPECT_TRUE(sd_match(ZExt, m_UnaryOp(ISD::ZERO_EXTEND, m_Value())));
405   EXPECT_TRUE(sd_match(SExt, m_SExt(m_Value())));
406   EXPECT_TRUE(sd_match(SExt, m_SExtLike(m_Value())));
407   ASSERT_TRUE(ZExtNNeg->getFlags().hasNonNeg());
408   EXPECT_FALSE(sd_match(ZExtNNeg, m_SExt(m_Value())));
409   EXPECT_TRUE(sd_match(ZExtNNeg, m_NNegZExt(m_Value())));
410   EXPECT_FALSE(sd_match(ZExt, m_NNegZExt(m_Value())));
411   EXPECT_TRUE(sd_match(ZExtNNeg, m_SExtLike(m_Value())));
412   EXPECT_FALSE(sd_match(ZExt, m_SExtLike(m_Value())));
413   EXPECT_TRUE(sd_match(Trunc, m_Trunc(m_Specific(Op1))));
414 
415   EXPECT_TRUE(sd_match(Neg, m_Neg(m_Value())));
416   EXPECT_TRUE(sd_match(Not, m_Not(m_Value())));
417   EXPECT_FALSE(sd_match(ZExt, m_Neg(m_Value())));
418   EXPECT_FALSE(sd_match(Sub, m_Neg(m_Value())));
419   EXPECT_FALSE(sd_match(Neg, m_Not(m_Value())));
420   EXPECT_TRUE(sd_match(VScale, m_VScale(m_Value())));
421 
422   EXPECT_TRUE(sd_match(FPToUI, m_FPToUI(m_Value())));
423   EXPECT_TRUE(sd_match(FPToSI, m_FPToSI(m_Value())));
424   EXPECT_FALSE(sd_match(FPToUI, m_FPToSI(m_Value())));
425   EXPECT_FALSE(sd_match(FPToSI, m_FPToUI(m_Value())));
426 
427   EXPECT_TRUE(sd_match(Bcast, m_BitCast(m_Value())));
428   EXPECT_TRUE(sd_match(Bcast, m_BitCast(m_SpecificVT(MVT::i32))));
429   EXPECT_TRUE(sd_match(Brev, m_BitReverse(m_Value())));
430   EXPECT_TRUE(sd_match(Bswap, m_BSwap(m_Value())));
431   EXPECT_FALSE(sd_match(Bcast, m_BitReverse(m_Value())));
432   EXPECT_FALSE(sd_match(Bcast, m_BitCast(m_SpecificVT(MVT::f32))));
433   EXPECT_FALSE(sd_match(Brev, m_BSwap(m_Value())));
434   EXPECT_FALSE(sd_match(Bswap, m_BitReverse(m_Value())));
435 
436   EXPECT_TRUE(sd_match(Ctpop, m_Ctpop(m_Value())));
437   EXPECT_TRUE(sd_match(Ctlz, m_Ctlz(m_Value())));
438   EXPECT_TRUE(sd_match(Cttz, m_Cttz(m_Value())));
439   EXPECT_FALSE(sd_match(Ctpop, m_Ctlz(m_Value())));
440   EXPECT_FALSE(sd_match(Ctlz, m_Cttz(m_Value())));
441   EXPECT_FALSE(sd_match(Cttz, m_Ctlz(m_Value())));
442 }
443 
444 TEST_F(SelectionDAGPatternMatchTest, matchConstants) {
445   SDLoc DL;
446   auto Int32VT = EVT::getIntegerVT(Context, 32);
447   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
448 
449   SDValue Arg0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
450 
451   SDValue Const3 = DAG->getConstant(3, DL, Int32VT);
452   SDValue Const87 = DAG->getConstant(87, DL, Int32VT);
453   SDValue Splat = DAG->getSplat(VInt32VT, DL, Arg0);
454   SDValue ConstSplat = DAG->getSplat(VInt32VT, DL, Const3);
455   SDValue Zero = DAG->getConstant(0, DL, Int32VT);
456   SDValue One = DAG->getConstant(1, DL, Int32VT);
457   SDValue AllOnes = DAG->getConstant(APInt::getAllOnes(32), DL, Int32VT);
458   SDValue SetCC = DAG->getSetCC(DL, Int32VT, Arg0, Const3, ISD::SETULT);
459 
460   using namespace SDPatternMatch;
461   EXPECT_TRUE(sd_match(Const87, m_ConstInt()));
462   EXPECT_FALSE(sd_match(Arg0, m_ConstInt()));
463   APInt ConstVal;
464   EXPECT_TRUE(sd_match(ConstSplat, m_ConstInt(ConstVal)));
465   EXPECT_EQ(ConstVal, 3);
466   EXPECT_FALSE(sd_match(Splat, m_ConstInt()));
467 
468   EXPECT_TRUE(sd_match(Const87, m_SpecificInt(87)));
469   EXPECT_TRUE(sd_match(Const3, m_SpecificInt(ConstVal)));
470   EXPECT_TRUE(sd_match(AllOnes, m_AllOnes()));
471 
472   EXPECT_TRUE(sd_match(Zero, DAG.get(), m_False()));
473   EXPECT_TRUE(sd_match(One, DAG.get(), m_True()));
474   EXPECT_FALSE(sd_match(AllOnes, DAG.get(), m_True()));
475 
476   ISD::CondCode CC;
477   EXPECT_TRUE(sd_match(
478       SetCC, m_Node(ISD::SETCC, m_Value(), m_Value(), m_CondCode(CC))));
479   EXPECT_EQ(CC, ISD::SETULT);
480   EXPECT_TRUE(sd_match(SetCC, m_Node(ISD::SETCC, m_Value(), m_Value(),
481                                      m_SpecificCondCode(ISD::SETULT))));
482 
483   SDValue UndefInt32VT = DAG->getUNDEF(Int32VT);
484   SDValue UndefVInt32VT = DAG->getUNDEF(VInt32VT);
485   EXPECT_TRUE(sd_match(UndefInt32VT, m_Undef()));
486   EXPECT_TRUE(sd_match(UndefVInt32VT, m_Undef()));
487 }
488 
489 TEST_F(SelectionDAGPatternMatchTest, patternCombinators) {
490   SDLoc DL;
491   auto Int32VT = EVT::getIntegerVT(Context, 32);
492 
493   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
494   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
495 
496   SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);
497   SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Add, Op0);
498 
499   using namespace SDPatternMatch;
500   EXPECT_TRUE(sd_match(
501       Sub, m_AnyOf(m_Opc(ISD::ADD), m_Opc(ISD::SUB), m_Opc(ISD::MUL))));
502   EXPECT_TRUE(sd_match(Add, m_AllOf(m_Opc(ISD::ADD), m_OneUse())));
503   EXPECT_TRUE(sd_match(Add, m_NoneOf(m_Opc(ISD::SUB), m_Opc(ISD::MUL))));
504 }
505 
506 TEST_F(SelectionDAGPatternMatchTest, optionalResizing) {
507   SDLoc DL;
508   auto Int32VT = EVT::getIntegerVT(Context, 32);
509   auto Int64VT = EVT::getIntegerVT(Context, 64);
510 
511   SDValue Op32 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
512   SDValue Op64 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);
513   SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op32);
514   SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op32);
515   SDValue AExt = DAG->getNode(ISD::ANY_EXTEND, DL, Int64VT, Op32);
516   SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op64);
517 
518   using namespace SDPatternMatch;
519   SDValue A;
520   EXPECT_TRUE(sd_match(Op32, m_ZExtOrSelf(m_Value(A))));
521   EXPECT_TRUE(A == Op32);
522   EXPECT_TRUE(sd_match(ZExt, m_ZExtOrSelf(m_Value(A))));
523   EXPECT_TRUE(A == Op32);
524   EXPECT_TRUE(sd_match(Op64, m_SExtOrSelf(m_Value(A))));
525   EXPECT_TRUE(A == Op64);
526   EXPECT_TRUE(sd_match(SExt, m_SExtOrSelf(m_Value(A))));
527   EXPECT_TRUE(A == Op32);
528   EXPECT_TRUE(sd_match(Op32, m_AExtOrSelf(m_Value(A))));
529   EXPECT_TRUE(A == Op32);
530   EXPECT_TRUE(sd_match(AExt, m_AExtOrSelf(m_Value(A))));
531   EXPECT_TRUE(A == Op32);
532   EXPECT_TRUE(sd_match(Op64, m_TruncOrSelf(m_Value(A))));
533   EXPECT_TRUE(A == Op64);
534   EXPECT_TRUE(sd_match(Trunc, m_TruncOrSelf(m_Value(A))));
535   EXPECT_TRUE(A == Op64);
536 }
537 
538 TEST_F(SelectionDAGPatternMatchTest, matchNode) {
539   SDLoc DL;
540   auto Int32VT = EVT::getIntegerVT(Context, 32);
541 
542   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
543   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
544 
545   SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);
546 
547   using namespace SDPatternMatch;
548   EXPECT_TRUE(sd_match(Add, m_Node(ISD::ADD, m_Value(), m_Value())));
549   EXPECT_FALSE(sd_match(Add, m_Node(ISD::SUB, m_Value(), m_Value())));
550   EXPECT_FALSE(sd_match(Add, m_Node(ISD::ADD, m_Value())));
551   EXPECT_FALSE(
552       sd_match(Add, m_Node(ISD::ADD, m_Value(), m_Value(), m_Value())));
553   EXPECT_FALSE(sd_match(Add, m_Node(ISD::ADD, m_ConstInt(), m_Value())));
554 }
555 
556 namespace {
557 struct VPMatchContext : public SDPatternMatch::BasicMatchContext {
558   using SDPatternMatch::BasicMatchContext::BasicMatchContext;
559 
560   bool match(SDValue OpVal, unsigned Opc) const {
561     if (!OpVal->isVPOpcode())
562       return OpVal->getOpcode() == Opc;
563 
564     auto BaseOpc = ISD::getBaseOpcodeForVP(OpVal->getOpcode(), false);
565     return BaseOpc.has_value() && *BaseOpc == Opc;
566   }
567 
568   unsigned getNumOperands(SDValue N) const {
569     return N->isVPOpcode() ? N->getNumOperands() - 2 : N->getNumOperands();
570   }
571 };
572 } // anonymous namespace
573 TEST_F(SelectionDAGPatternMatchTest, matchContext) {
574   SDLoc DL;
575   auto BoolVT = EVT::getIntegerVT(Context, 1);
576   auto Int32VT = EVT::getIntegerVT(Context, 32);
577   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
578   auto MaskVT = EVT::getVectorVT(Context, BoolVT, 4);
579 
580   SDValue Scalar0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
581   SDValue Vector0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);
582   SDValue Mask0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, MaskVT);
583 
584   SDValue VPAdd = DAG->getNode(ISD::VP_ADD, DL, VInt32VT,
585                                {Vector0, Vector0, Mask0, Scalar0});
586   SDValue VPReduceAdd = DAG->getNode(ISD::VP_REDUCE_ADD, DL, Int32VT,
587                                      {Scalar0, VPAdd, Mask0, Scalar0});
588   SDValue Add = DAG->getNode(ISD::ADD, DL, VInt32VT, {Vector0, Vector0});
589 
590   using namespace SDPatternMatch;
591   VPMatchContext VPCtx(DAG.get());
592   EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_Opc(ISD::ADD)));
593   EXPECT_TRUE(
594       sd_context_match(VPAdd, VPCtx, m_Node(ISD::ADD, m_Value(), m_Value())));
595   // VPMatchContext can't match pattern using explicit VP Opcode
596   EXPECT_FALSE(sd_context_match(VPAdd, VPCtx,
597                                 m_Node(ISD::VP_ADD, m_Value(), m_Value())));
598   EXPECT_FALSE(sd_context_match(
599       VPAdd, VPCtx,
600       m_Node(ISD::VP_ADD, m_Value(), m_Value(), m_Value(), m_Value())));
601   // Check Binary Op Pattern
602   EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_Add(m_Value(), m_Value())));
603   // VP_REDUCE_ADD doesn't have a based opcode, so we use a normal
604   // sd_match before switching to VPMatchContext when checking VPAdd.
605   EXPECT_TRUE(sd_match(VPReduceAdd, m_Node(ISD::VP_REDUCE_ADD, m_Value(),
606                                            m_Context(VPCtx, m_Opc(ISD::ADD)),
607                                            m_Value(), m_Value())));
608   // non-vector predicated should match too
609   EXPECT_TRUE(sd_context_match(Add, VPCtx, m_Opc(ISD::ADD)));
610   EXPECT_TRUE(
611       sd_context_match(Add, VPCtx, m_Node(ISD::ADD, m_Value(), m_Value())));
612   EXPECT_FALSE(sd_context_match(
613       Add, VPCtx,
614       m_Node(ISD::ADD, m_Value(), m_Value(), m_Value(), m_Value())));
615   EXPECT_TRUE(sd_context_match(Add, VPCtx, m_Add(m_Value(), m_Value())));
616 }
617 
618 TEST_F(SelectionDAGPatternMatchTest, matchVPWithBasicContext) {
619   SDLoc DL;
620   auto BoolVT = EVT::getIntegerVT(Context, 1);
621   auto Int32VT = EVT::getIntegerVT(Context, 32);
622   auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
623   auto MaskVT = EVT::getVectorVT(Context, BoolVT, 4);
624 
625   SDValue Vector0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, VInt32VT);
626   SDValue Mask = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, MaskVT);
627   SDValue EL = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int32VT);
628 
629   SDValue VPAdd =
630       DAG->getNode(ISD::VP_ADD, DL, VInt32VT, Vector0, Vector0, Mask, EL);
631 
632   using namespace SDPatternMatch;
633   EXPECT_FALSE(sd_match(VPAdd, m_Node(ISD::VP_ADD, m_Value(), m_Value())));
634   EXPECT_TRUE(sd_match(
635       VPAdd, m_Node(ISD::VP_ADD, m_Value(), m_Value(), m_Value(), m_Value())));
636 }
637 
638 TEST_F(SelectionDAGPatternMatchTest, matchAdvancedProperties) {
639   SDLoc DL;
640   auto Int16VT = EVT::getIntegerVT(Context, 16);
641   auto Int64VT = EVT::getIntegerVT(Context, 64);
642 
643   SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);
644   SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int16VT);
645 
646   SDValue Add = DAG->getNode(ISD::ADD, DL, Int64VT, Op0, Op0);
647 
648   using namespace SDPatternMatch;
649   EXPECT_TRUE(sd_match(Op0, DAG.get(), m_LegalType(m_Value())));
650   EXPECT_FALSE(sd_match(Op1, DAG.get(), m_LegalType(m_Value())));
651   EXPECT_TRUE(sd_match(Add, DAG.get(),
652                        m_LegalOp(m_IntegerVT(m_Add(m_Value(), m_Value())))));
653 }
654