[gcov] Bump default version to 11.1
[llvm-project.git] / llvm / unittests / CodeGen / SelectionDAGPatternMatchTest.cpp
blob259bdad0ab2723c0b4f0a673d58c379840b7cc0b
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 //===----------------------------------------------------------------------===//
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"
21 using namespace llvm;
23 class SelectionDAGPatternMatchTest : public testing::Test {
24 protected:
25 static void SetUpTestCase() {
26 InitializeAllTargets();
27 InitializeAllTargetMCs();
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 "}";
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();
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();
54 SMDiagnostic SMError;
55 M = parseAssemblyString(Assembly, SMError, Context);
56 if (!M)
57 report_fatal_error(SMError.getMessage());
58 M->setDataLayout(TM->createDataLayout());
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?");
70 MachineModuleInfo MMI(TM.get());
72 MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F),
73 MMI.getContext(), 0);
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);
83 TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) {
84 return DAG->getTargetLoweringInfo().getTypeAction(Context, VT);
87 EVT getTypeToTransformTo(EVT VT) {
88 return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT);
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;
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);
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);
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()));
122 TEST_F(SelectionDAGPatternMatchTest, matchTernaryOp) {
123 SDLoc DL;
124 auto Int32VT = EVT::getIntegerVT(Context, 32);
126 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
127 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
128 SDValue Op3 = DAG->getConstant(1, DL, Int32VT);
130 SDValue ICMP_UGT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGT);
131 SDValue ICMP_EQ01 = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETEQ);
132 SDValue ICMP_EQ10 = DAG->getSetCC(DL, MVT::i1, Op1, Op0, ISD::SETEQ);
134 auto Int1VT = EVT::getIntegerVT(Context, 1);
135 SDValue Cond = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int1VT);
136 SDValue T = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 4, Int1VT);
137 SDValue F = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 5, Int1VT);
138 SDValue Select = DAG->getSelect(DL, MVT::i1, Cond, T, F);
140 auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
141 SDValue V1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 6, VInt32VT);
142 SDValue V2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 7, VInt32VT);
143 SDValue VSelect = DAG->getNode(ISD::VSELECT, DL, VInt32VT, Cond, V1, V2);
145 SDValue ExtractELT =
146 DAG->getNode(ISD::EXTRACT_VECTOR_ELT, DL, Int32VT, V1, Op3);
148 using namespace SDPatternMatch;
149 ISD::CondCode CC;
150 EXPECT_TRUE(sd_match(ICMP_UGT, m_SetCC(m_Value(), m_Value(),
151 m_SpecificCondCode(ISD::SETUGT))));
152 EXPECT_TRUE(
153 sd_match(ICMP_UGT, m_SetCC(m_Value(), m_Value(), m_CondCode(CC))));
154 EXPECT_TRUE(CC == ISD::SETUGT);
155 EXPECT_FALSE(sd_match(
156 ICMP_UGT, m_SetCC(m_Value(), m_Value(), m_SpecificCondCode(ISD::SETLE))));
158 EXPECT_TRUE(sd_match(ICMP_EQ01, m_SetCC(m_Specific(Op0), m_Specific(Op1),
159 m_SpecificCondCode(ISD::SETEQ))));
160 EXPECT_TRUE(sd_match(ICMP_EQ10, m_SetCC(m_Specific(Op1), m_Specific(Op0),
161 m_SpecificCondCode(ISD::SETEQ))));
162 EXPECT_FALSE(sd_match(ICMP_EQ01, m_SetCC(m_Specific(Op1), m_Specific(Op0),
163 m_SpecificCondCode(ISD::SETEQ))));
164 EXPECT_FALSE(sd_match(ICMP_EQ10, m_SetCC(m_Specific(Op0), m_Specific(Op1),
165 m_SpecificCondCode(ISD::SETEQ))));
166 EXPECT_TRUE(sd_match(ICMP_EQ01, m_c_SetCC(m_Specific(Op1), m_Specific(Op0),
167 m_SpecificCondCode(ISD::SETEQ))));
168 EXPECT_TRUE(sd_match(ICMP_EQ10, m_c_SetCC(m_Specific(Op0), m_Specific(Op1),
169 m_SpecificCondCode(ISD::SETEQ))));
171 EXPECT_TRUE(sd_match(
172 Select, m_Select(m_Specific(Cond), m_Specific(T), m_Specific(F))));
173 EXPECT_FALSE(sd_match(
174 Select, m_Select(m_Specific(Cond), m_Specific(F), m_Specific(T))));
175 EXPECT_FALSE(sd_match(ICMP_EQ01, m_Select(m_Specific(Op0), m_Specific(Op1),
176 m_SpecificCondCode(ISD::SETEQ))));
177 EXPECT_TRUE(sd_match(
178 VSelect, m_VSelect(m_Specific(Cond), m_Specific(V1), m_Specific(V2))));
179 EXPECT_FALSE(sd_match(
180 Select, m_VSelect(m_Specific(Cond), m_Specific(V1), m_Specific(V2))));
182 EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_Value())));
183 EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_ConstInt())));
184 EXPECT_TRUE(sd_match(ExtractELT, m_ExtractElt(m_Value(), m_SpecificInt(1))));
187 TEST_F(SelectionDAGPatternMatchTest, matchBinaryOp) {
188 SDLoc DL;
189 auto Int32VT = EVT::getIntegerVT(Context, 32);
190 auto Float32VT = EVT::getFloatingPointVT(32);
191 auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
193 SDValue V1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 6, VInt32VT);
195 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
196 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
197 SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Float32VT);
198 SDValue Op3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 8, Int32VT);
199 SDValue Op4 = DAG->getConstant(1, DL, Int32VT);
201 SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);
202 SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Add, Op0);
203 SDValue Mul = DAG->getNode(ISD::MUL, DL, Int32VT, Add, Sub);
204 SDValue And = DAG->getNode(ISD::AND, DL, Int32VT, Op0, Op1);
205 SDValue Xor = DAG->getNode(ISD::XOR, DL, Int32VT, Op1, Op0);
206 SDValue Or = DAG->getNode(ISD::OR, DL, Int32VT, Op0, Op1);
207 SDValue DisOr =
208 DAG->getNode(ISD::OR, DL, Int32VT, Op0, Op3, SDNodeFlags::Disjoint);
209 SDValue SMax = DAG->getNode(ISD::SMAX, DL, Int32VT, Op0, Op1);
210 SDValue SMin = DAG->getNode(ISD::SMIN, DL, Int32VT, Op1, Op0);
211 SDValue UMax = DAG->getNode(ISD::UMAX, DL, Int32VT, Op0, Op1);
212 SDValue UMin = DAG->getNode(ISD::UMIN, DL, Int32VT, Op1, Op0);
213 SDValue Rotl = DAG->getNode(ISD::ROTL, DL, Int32VT, Op0, Op1);
214 SDValue Rotr = DAG->getNode(ISD::ROTR, DL, Int32VT, Op1, Op0);
216 SDValue ICMP_GT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETGT);
217 SDValue ICMP_GE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETGE);
218 SDValue ICMP_UGT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGT);
219 SDValue ICMP_UGE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETUGE);
220 SDValue ICMP_LT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETLT);
221 SDValue ICMP_LE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETLE);
222 SDValue ICMP_ULT = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETULT);
223 SDValue ICMP_ULE = DAG->getSetCC(DL, MVT::i1, Op0, Op1, ISD::SETULE);
224 SDValue SMaxLikeGT = DAG->getSelect(DL, MVT::i32, ICMP_GT, Op0, Op1);
225 SDValue SMaxLikeGE = DAG->getSelect(DL, MVT::i32, ICMP_GE, Op0, Op1);
226 SDValue UMaxLikeUGT = DAG->getSelect(DL, MVT::i32, ICMP_UGT, Op0, Op1);
227 SDValue UMaxLikeUGE = DAG->getSelect(DL, MVT::i32, ICMP_UGE, Op0, Op1);
228 SDValue SMinLikeLT = DAG->getSelect(DL, MVT::i32, ICMP_LT, Op0, Op1);
229 SDValue SMinLikeLE = DAG->getSelect(DL, MVT::i32, ICMP_LE, Op0, Op1);
230 SDValue UMinLikeULT = DAG->getSelect(DL, MVT::i32, ICMP_ULT, Op0, Op1);
231 SDValue UMinLikeULE = DAG->getSelect(DL, MVT::i32, ICMP_ULE, Op0, Op1);
233 SDValue SFAdd = DAG->getNode(ISD::STRICT_FADD, DL, {Float32VT, MVT::Other},
234 {DAG->getEntryNode(), Op2, Op2});
236 SDValue InsertELT =
237 DAG->getNode(ISD::INSERT_VECTOR_ELT, DL, VInt32VT, V1, Op0, Op4);
239 using namespace SDPatternMatch;
240 EXPECT_TRUE(sd_match(Sub, m_BinOp(ISD::SUB, m_Value(), m_Value())));
241 EXPECT_TRUE(sd_match(Sub, m_Sub(m_Value(), m_Value())));
242 EXPECT_TRUE(sd_match(Add, m_c_BinOp(ISD::ADD, m_Value(), m_Value())));
243 EXPECT_TRUE(sd_match(Add, m_Add(m_Value(), m_Value())));
244 EXPECT_TRUE(sd_match(Add, m_AddLike(m_Value(), m_Value())));
245 EXPECT_TRUE(sd_match(
246 Mul, m_Mul(m_OneUse(m_Opc(ISD::SUB)), m_NUses<2>(m_Specific(Add)))));
247 EXPECT_TRUE(
248 sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_SpecificVT(Float32VT),
249 m_SpecificVT(Float32VT))));
251 EXPECT_TRUE(sd_match(And, m_c_BinOp(ISD::AND, m_Value(), m_Value())));
252 EXPECT_TRUE(sd_match(And, m_And(m_Value(), m_Value())));
253 EXPECT_TRUE(sd_match(Xor, m_c_BinOp(ISD::XOR, m_Value(), m_Value())));
254 EXPECT_TRUE(sd_match(Xor, m_Xor(m_Value(), m_Value())));
255 EXPECT_TRUE(sd_match(Or, m_c_BinOp(ISD::OR, m_Value(), m_Value())));
256 EXPECT_TRUE(sd_match(Or, m_Or(m_Value(), m_Value())));
257 EXPECT_FALSE(sd_match(Or, m_DisjointOr(m_Value(), m_Value())));
259 EXPECT_TRUE(sd_match(DisOr, m_Or(m_Value(), m_Value())));
260 EXPECT_TRUE(sd_match(DisOr, m_DisjointOr(m_Value(), m_Value())));
261 EXPECT_FALSE(sd_match(DisOr, m_Add(m_Value(), m_Value())));
262 EXPECT_TRUE(sd_match(DisOr, m_AddLike(m_Value(), m_Value())));
264 EXPECT_TRUE(sd_match(Rotl, m_Rotl(m_Value(), m_Value())));
265 EXPECT_TRUE(sd_match(Rotr, m_Rotr(m_Value(), m_Value())));
266 EXPECT_FALSE(sd_match(Rotl, m_Rotr(m_Value(), m_Value())));
267 EXPECT_FALSE(sd_match(Rotr, m_Rotl(m_Value(), m_Value())));
269 EXPECT_TRUE(sd_match(SMax, m_c_BinOp(ISD::SMAX, m_Value(), m_Value())));
270 EXPECT_TRUE(sd_match(SMax, m_SMax(m_Value(), m_Value())));
271 EXPECT_TRUE(sd_match(SMax, m_SMaxLike(m_Value(), m_Value())));
272 EXPECT_TRUE(sd_match(SMaxLikeGT, m_SMaxLike(m_Value(), m_Value())));
273 EXPECT_TRUE(sd_match(SMaxLikeGE, m_SMaxLike(m_Value(), m_Value())));
274 EXPECT_TRUE(sd_match(SMin, m_c_BinOp(ISD::SMIN, m_Value(), m_Value())));
275 EXPECT_TRUE(sd_match(SMin, m_SMin(m_Value(), m_Value())));
276 EXPECT_TRUE(sd_match(SMin, m_SMinLike(m_Value(), m_Value())));
277 EXPECT_TRUE(sd_match(SMinLikeLT, m_SMinLike(m_Value(), m_Value())));
278 EXPECT_TRUE(sd_match(SMinLikeLE, m_SMinLike(m_Value(), m_Value())));
279 EXPECT_TRUE(sd_match(UMax, m_c_BinOp(ISD::UMAX, m_Value(), m_Value())));
280 EXPECT_TRUE(sd_match(UMax, m_UMax(m_Value(), m_Value())));
281 EXPECT_TRUE(sd_match(UMax, m_UMaxLike(m_Value(), m_Value())));
282 EXPECT_TRUE(sd_match(UMaxLikeUGT, m_UMaxLike(m_Value(), m_Value())));
283 EXPECT_TRUE(sd_match(UMaxLikeUGE, m_UMaxLike(m_Value(), m_Value())));
284 EXPECT_TRUE(sd_match(UMin, m_c_BinOp(ISD::UMIN, m_Value(), m_Value())));
285 EXPECT_TRUE(sd_match(UMin, m_UMin(m_Value(), m_Value())));
286 EXPECT_TRUE(sd_match(UMin, m_UMinLike(m_Value(), m_Value())));
287 EXPECT_TRUE(sd_match(UMinLikeULT, m_UMinLike(m_Value(), m_Value())));
288 EXPECT_TRUE(sd_match(UMinLikeULE, m_UMinLike(m_Value(), m_Value())));
290 SDValue BindVal;
291 EXPECT_TRUE(sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_Value(BindVal),
292 m_Deferred(BindVal))));
293 EXPECT_FALSE(sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_OtherVT(),
294 m_SpecificVT(Float32VT))));
296 EXPECT_TRUE(
297 sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_Value())));
298 EXPECT_TRUE(
299 sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_ConstInt())));
300 EXPECT_TRUE(
301 sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_SpecificInt(1))));
304 TEST_F(SelectionDAGPatternMatchTest, matchUnaryOp) {
305 SDLoc DL;
306 auto Int32VT = EVT::getIntegerVT(Context, 32);
307 auto Int64VT = EVT::getIntegerVT(Context, 64);
308 auto FloatVT = EVT::getFloatingPointVT(32);
310 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
311 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);
312 SDValue Op2 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, FloatVT);
313 SDValue Op3 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int32VT);
315 SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op0);
316 SDValue ZExtNNeg =
317 DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op3, SDNodeFlags::NonNeg);
318 SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op0);
319 SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op1);
321 SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Trunc, Op0);
322 SDValue Neg = DAG->getNegative(Op0, DL, Int32VT);
323 SDValue Not = DAG->getNOT(DL, Op0, Int32VT);
325 SDValue VScale = DAG->getVScale(DL, Int32VT, APInt::getMaxValue(32));
327 SDValue FPToSI = DAG->getNode(ISD::FP_TO_SINT, DL, FloatVT, Op2);
328 SDValue FPToUI = DAG->getNode(ISD::FP_TO_UINT, DL, FloatVT, Op2);
330 SDValue Brev = DAG->getNode(ISD::BITREVERSE, DL, Int32VT, Op0);
331 SDValue Bswap = DAG->getNode(ISD::BSWAP, DL, Int32VT, Op0);
333 SDValue Ctpop = DAG->getNode(ISD::CTPOP, DL, Int32VT, Op0);
334 SDValue Ctlz = DAG->getNode(ISD::CTLZ, DL, Int32VT, Op0);
335 SDValue Cttz = DAG->getNode(ISD::CTTZ, DL, Int32VT, Op0);
337 using namespace SDPatternMatch;
338 EXPECT_TRUE(sd_match(ZExt, m_UnaryOp(ISD::ZERO_EXTEND, m_Value())));
339 EXPECT_TRUE(sd_match(SExt, m_SExt(m_Value())));
340 EXPECT_TRUE(sd_match(SExt, m_SExtLike(m_Value())));
341 ASSERT_TRUE(ZExtNNeg->getFlags().hasNonNeg());
342 EXPECT_FALSE(sd_match(ZExtNNeg, m_SExt(m_Value())));
343 EXPECT_TRUE(sd_match(ZExtNNeg, m_NNegZExt(m_Value())));
344 EXPECT_FALSE(sd_match(ZExt, m_NNegZExt(m_Value())));
345 EXPECT_TRUE(sd_match(ZExtNNeg, m_SExtLike(m_Value())));
346 EXPECT_FALSE(sd_match(ZExt, m_SExtLike(m_Value())));
347 EXPECT_TRUE(sd_match(Trunc, m_Trunc(m_Specific(Op1))));
349 EXPECT_TRUE(sd_match(Neg, m_Neg(m_Value())));
350 EXPECT_TRUE(sd_match(Not, m_Not(m_Value())));
351 EXPECT_FALSE(sd_match(ZExt, m_Neg(m_Value())));
352 EXPECT_FALSE(sd_match(Sub, m_Neg(m_Value())));
353 EXPECT_FALSE(sd_match(Neg, m_Not(m_Value())));
354 EXPECT_TRUE(sd_match(VScale, m_VScale(m_Value())));
356 EXPECT_TRUE(sd_match(FPToUI, m_FPToUI(m_Value())));
357 EXPECT_TRUE(sd_match(FPToSI, m_FPToSI(m_Value())));
358 EXPECT_FALSE(sd_match(FPToUI, m_FPToSI(m_Value())));
359 EXPECT_FALSE(sd_match(FPToSI, m_FPToUI(m_Value())));
361 EXPECT_TRUE(sd_match(Brev, m_BitReverse(m_Value())));
362 EXPECT_TRUE(sd_match(Bswap, m_BSwap(m_Value())));
363 EXPECT_FALSE(sd_match(Brev, m_BSwap(m_Value())));
364 EXPECT_FALSE(sd_match(Bswap, m_BitReverse(m_Value())));
366 EXPECT_TRUE(sd_match(Ctpop, m_Ctpop(m_Value())));
367 EXPECT_TRUE(sd_match(Ctlz, m_Ctlz(m_Value())));
368 EXPECT_TRUE(sd_match(Cttz, m_Cttz(m_Value())));
369 EXPECT_FALSE(sd_match(Ctpop, m_Ctlz(m_Value())));
370 EXPECT_FALSE(sd_match(Ctlz, m_Cttz(m_Value())));
371 EXPECT_FALSE(sd_match(Cttz, m_Ctlz(m_Value())));
374 TEST_F(SelectionDAGPatternMatchTest, matchConstants) {
375 SDLoc DL;
376 auto Int32VT = EVT::getIntegerVT(Context, 32);
377 auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
379 SDValue Arg0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
381 SDValue Const3 = DAG->getConstant(3, DL, Int32VT);
382 SDValue Const87 = DAG->getConstant(87, DL, Int32VT);
383 SDValue Splat = DAG->getSplat(VInt32VT, DL, Arg0);
384 SDValue ConstSplat = DAG->getSplat(VInt32VT, DL, Const3);
385 SDValue Zero = DAG->getConstant(0, DL, Int32VT);
386 SDValue One = DAG->getConstant(1, DL, Int32VT);
387 SDValue AllOnes = DAG->getConstant(APInt::getAllOnes(32), DL, Int32VT);
388 SDValue SetCC = DAG->getSetCC(DL, Int32VT, Arg0, Const3, ISD::SETULT);
390 using namespace SDPatternMatch;
391 EXPECT_TRUE(sd_match(Const87, m_ConstInt()));
392 EXPECT_FALSE(sd_match(Arg0, m_ConstInt()));
393 APInt ConstVal;
394 EXPECT_TRUE(sd_match(ConstSplat, m_ConstInt(ConstVal)));
395 EXPECT_EQ(ConstVal, 3);
396 EXPECT_FALSE(sd_match(Splat, m_ConstInt()));
398 EXPECT_TRUE(sd_match(Const87, m_SpecificInt(87)));
399 EXPECT_TRUE(sd_match(Const3, m_SpecificInt(ConstVal)));
400 EXPECT_TRUE(sd_match(AllOnes, m_AllOnes()));
402 EXPECT_TRUE(sd_match(Zero, DAG.get(), m_False()));
403 EXPECT_TRUE(sd_match(One, DAG.get(), m_True()));
404 EXPECT_FALSE(sd_match(AllOnes, DAG.get(), m_True()));
406 ISD::CondCode CC;
407 EXPECT_TRUE(sd_match(
408 SetCC, m_Node(ISD::SETCC, m_Value(), m_Value(), m_CondCode(CC))));
409 EXPECT_EQ(CC, ISD::SETULT);
410 EXPECT_TRUE(sd_match(SetCC, m_Node(ISD::SETCC, m_Value(), m_Value(),
411 m_SpecificCondCode(ISD::SETULT))));
414 TEST_F(SelectionDAGPatternMatchTest, patternCombinators) {
415 SDLoc DL;
416 auto Int32VT = EVT::getIntegerVT(Context, 32);
418 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
419 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
421 SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);
422 SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Add, Op0);
424 using namespace SDPatternMatch;
425 EXPECT_TRUE(sd_match(
426 Sub, m_AnyOf(m_Opc(ISD::ADD), m_Opc(ISD::SUB), m_Opc(ISD::MUL))));
427 EXPECT_TRUE(sd_match(Add, m_AllOf(m_Opc(ISD::ADD), m_OneUse())));
428 EXPECT_TRUE(sd_match(Add, m_NoneOf(m_Opc(ISD::SUB), m_Opc(ISD::MUL))));
431 TEST_F(SelectionDAGPatternMatchTest, optionalResizing) {
432 SDLoc DL;
433 auto Int32VT = EVT::getIntegerVT(Context, 32);
434 auto Int64VT = EVT::getIntegerVT(Context, 64);
436 SDValue Op32 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
437 SDValue Op64 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);
438 SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op32);
439 SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op32);
440 SDValue AExt = DAG->getNode(ISD::ANY_EXTEND, DL, Int64VT, Op32);
441 SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op64);
443 using namespace SDPatternMatch;
444 SDValue A;
445 EXPECT_TRUE(sd_match(Op32, m_ZExtOrSelf(m_Value(A))));
446 EXPECT_TRUE(A == Op32);
447 EXPECT_TRUE(sd_match(ZExt, m_ZExtOrSelf(m_Value(A))));
448 EXPECT_TRUE(A == Op32);
449 EXPECT_TRUE(sd_match(Op64, m_SExtOrSelf(m_Value(A))));
450 EXPECT_TRUE(A == Op64);
451 EXPECT_TRUE(sd_match(SExt, m_SExtOrSelf(m_Value(A))));
452 EXPECT_TRUE(A == Op32);
453 EXPECT_TRUE(sd_match(Op32, m_AExtOrSelf(m_Value(A))));
454 EXPECT_TRUE(A == Op32);
455 EXPECT_TRUE(sd_match(AExt, m_AExtOrSelf(m_Value(A))));
456 EXPECT_TRUE(A == Op32);
457 EXPECT_TRUE(sd_match(Op64, m_TruncOrSelf(m_Value(A))));
458 EXPECT_TRUE(A == Op64);
459 EXPECT_TRUE(sd_match(Trunc, m_TruncOrSelf(m_Value(A))));
460 EXPECT_TRUE(A == Op64);
463 TEST_F(SelectionDAGPatternMatchTest, matchNode) {
464 SDLoc DL;
465 auto Int32VT = EVT::getIntegerVT(Context, 32);
467 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
468 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
470 SDValue Add = DAG->getNode(ISD::ADD, DL, Int32VT, Op0, Op1);
472 using namespace SDPatternMatch;
473 EXPECT_TRUE(sd_match(Add, m_Node(ISD::ADD, m_Value(), m_Value())));
474 EXPECT_FALSE(sd_match(Add, m_Node(ISD::SUB, m_Value(), m_Value())));
475 EXPECT_FALSE(sd_match(Add, m_Node(ISD::ADD, m_Value())));
476 EXPECT_FALSE(
477 sd_match(Add, m_Node(ISD::ADD, m_Value(), m_Value(), m_Value())));
478 EXPECT_FALSE(sd_match(Add, m_Node(ISD::ADD, m_ConstInt(), m_Value())));
481 namespace {
482 struct VPMatchContext : public SDPatternMatch::BasicMatchContext {
483 using SDPatternMatch::BasicMatchContext::BasicMatchContext;
485 bool match(SDValue OpVal, unsigned Opc) const {
486 if (!OpVal->isVPOpcode())
487 return OpVal->getOpcode() == Opc;
489 auto BaseOpc = ISD::getBaseOpcodeForVP(OpVal->getOpcode(), false);
490 return BaseOpc.has_value() && *BaseOpc == Opc;
493 unsigned getNumOperands(SDValue N) const {
494 return N->isVPOpcode() ? N->getNumOperands() - 2 : N->getNumOperands();
497 } // anonymous namespace
498 TEST_F(SelectionDAGPatternMatchTest, matchContext) {
499 SDLoc DL;
500 auto BoolVT = EVT::getIntegerVT(Context, 1);
501 auto Int32VT = EVT::getIntegerVT(Context, 32);
502 auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
503 auto MaskVT = EVT::getVectorVT(Context, BoolVT, 4);
505 SDValue Scalar0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
506 SDValue Vector0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);
507 SDValue Mask0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, MaskVT);
509 SDValue VPAdd = DAG->getNode(ISD::VP_ADD, DL, VInt32VT,
510 {Vector0, Vector0, Mask0, Scalar0});
511 SDValue VPReduceAdd = DAG->getNode(ISD::VP_REDUCE_ADD, DL, Int32VT,
512 {Scalar0, VPAdd, Mask0, Scalar0});
513 SDValue Add = DAG->getNode(ISD::ADD, DL, VInt32VT, {Vector0, Vector0});
515 using namespace SDPatternMatch;
516 VPMatchContext VPCtx(DAG.get());
517 EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_Opc(ISD::ADD)));
518 EXPECT_TRUE(
519 sd_context_match(VPAdd, VPCtx, m_Node(ISD::ADD, m_Value(), m_Value())));
520 // VPMatchContext can't match pattern using explicit VP Opcode
521 EXPECT_FALSE(sd_context_match(VPAdd, VPCtx,
522 m_Node(ISD::VP_ADD, m_Value(), m_Value())));
523 EXPECT_FALSE(sd_context_match(
524 VPAdd, VPCtx,
525 m_Node(ISD::VP_ADD, m_Value(), m_Value(), m_Value(), m_Value())));
526 // Check Binary Op Pattern
527 EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_Add(m_Value(), m_Value())));
528 // VP_REDUCE_ADD doesn't have a based opcode, so we use a normal
529 // sd_match before switching to VPMatchContext when checking VPAdd.
530 EXPECT_TRUE(sd_match(VPReduceAdd, m_Node(ISD::VP_REDUCE_ADD, m_Value(),
531 m_Context(VPCtx, m_Opc(ISD::ADD)),
532 m_Value(), m_Value())));
533 // non-vector predicated should match too
534 EXPECT_TRUE(sd_context_match(Add, VPCtx, m_Opc(ISD::ADD)));
535 EXPECT_TRUE(
536 sd_context_match(Add, VPCtx, m_Node(ISD::ADD, m_Value(), m_Value())));
537 EXPECT_FALSE(sd_context_match(
538 Add, VPCtx,
539 m_Node(ISD::ADD, m_Value(), m_Value(), m_Value(), m_Value())));
540 EXPECT_TRUE(sd_context_match(Add, VPCtx, m_Add(m_Value(), m_Value())));
543 TEST_F(SelectionDAGPatternMatchTest, matchVPWithBasicContext) {
544 SDLoc DL;
545 auto BoolVT = EVT::getIntegerVT(Context, 1);
546 auto Int32VT = EVT::getIntegerVT(Context, 32);
547 auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
548 auto MaskVT = EVT::getVectorVT(Context, BoolVT, 4);
550 SDValue Vector0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, VInt32VT);
551 SDValue Mask = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, MaskVT);
552 SDValue EL = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 3, Int32VT);
554 SDValue VPAdd =
555 DAG->getNode(ISD::VP_ADD, DL, VInt32VT, Vector0, Vector0, Mask, EL);
557 using namespace SDPatternMatch;
558 EXPECT_FALSE(sd_match(VPAdd, m_Node(ISD::VP_ADD, m_Value(), m_Value())));
559 EXPECT_TRUE(sd_match(
560 VPAdd, m_Node(ISD::VP_ADD, m_Value(), m_Value(), m_Value(), m_Value())));
563 TEST_F(SelectionDAGPatternMatchTest, matchAdvancedProperties) {
564 SDLoc DL;
565 auto Int16VT = EVT::getIntegerVT(Context, 16);
566 auto Int64VT = EVT::getIntegerVT(Context, 64);
568 SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT);
569 SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int16VT);
571 SDValue Add = DAG->getNode(ISD::ADD, DL, Int64VT, Op0, Op0);
573 using namespace SDPatternMatch;
574 EXPECT_TRUE(sd_match(Op0, DAG.get(), m_LegalType(m_Value())));
575 EXPECT_FALSE(sd_match(Op1, DAG.get(), m_LegalType(m_Value())));
576 EXPECT_TRUE(sd_match(Add, DAG.get(),
577 m_LegalOp(m_IntegerVT(m_Add(m_Value(), m_Value())))));