1 //===- llvm/unittest/CodeGen/AArch64SelectionDAGTest.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/SelectionDAG.h"
13 #include "llvm/CodeGen/TargetLowering.h"
14 #include "llvm/Support/KnownBits.h"
15 #include "llvm/Support/SourceMgr.h"
16 #include "llvm/Support/TargetRegistry.h"
17 #include "llvm/Support/TargetSelect.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "gtest/gtest.h"
20
21 namespace llvm {
22
23 class AArch64SelectionDAGTest : public testing::Test {
24 protected:
SetUpTestCase()25 static void SetUpTestCase() {
26 InitializeAllTargets();
27 InitializeAllTargetMCs();
28 }
29
SetUp()30 void SetUp() override {
31 StringRef Assembly = "define void @f() { ret void }";
32
33 Triple TargetTriple("aarch64--");
34 std::string Error;
35 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
36 // FIXME: These tests do not depend on AArch64 specifically, but we have to
37 // initialize a target. A skeleton Target for unittests would allow us to
38 // always run these tests.
39 if (!T)
40 GTEST_SKIP();
41
42 TargetOptions Options;
43 TM = std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>(
44 T->createTargetMachine("AArch64", "", "+sve", Options, None, None,
45 CodeGenOpt::Aggressive)));
46 if (!TM)
47 GTEST_SKIP();
48
49 SMDiagnostic SMError;
50 M = parseAssemblyString(Assembly, SMError, Context);
51 if (!M)
52 report_fatal_error(SMError.getMessage());
53 M->setDataLayout(TM->createDataLayout());
54
55 F = M->getFunction("f");
56 if (!F)
57 report_fatal_error("F?");
58
59 MachineModuleInfo MMI(TM.get());
60
61 MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F), 0,
62 MMI);
63
64 DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOpt::None);
65 if (!DAG)
66 report_fatal_error("DAG?");
67 OptimizationRemarkEmitter ORE(F);
68 DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr);
69 }
70
getTypeAction(EVT VT)71 TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) {
72 return DAG->getTargetLoweringInfo().getTypeAction(Context, VT);
73 }
74
getTypeToTransformTo(EVT VT)75 EVT getTypeToTransformTo(EVT VT) {
76 return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT);
77 }
78
79 LLVMContext Context;
80 std::unique_ptr<LLVMTargetMachine> TM;
81 std::unique_ptr<Module> M;
82 Function *F;
83 std::unique_ptr<MachineFunction> MF;
84 std::unique_ptr<SelectionDAG> DAG;
85 };
86
TEST_F(AArch64SelectionDAGTest,computeKnownBits_ZERO_EXTEND_VECTOR_INREG)87 TEST_F(AArch64SelectionDAGTest, computeKnownBits_ZERO_EXTEND_VECTOR_INREG) {
88 SDLoc Loc;
89 auto Int8VT = EVT::getIntegerVT(Context, 8);
90 auto Int16VT = EVT::getIntegerVT(Context, 16);
91 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);
92 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);
93 auto InVec = DAG->getConstant(0, Loc, InVecVT);
94 auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
95 auto DemandedElts = APInt(2, 3);
96 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
97 EXPECT_TRUE(Known.isZero());
98 }
99
TEST_F(AArch64SelectionDAGTest,computeKnownBitsSVE_ZERO_EXTEND_VECTOR_INREG)100 TEST_F(AArch64SelectionDAGTest, computeKnownBitsSVE_ZERO_EXTEND_VECTOR_INREG) {
101 SDLoc Loc;
102 auto Int8VT = EVT::getIntegerVT(Context, 8);
103 auto Int16VT = EVT::getIntegerVT(Context, 16);
104 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, true);
105 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, true);
106 auto InVec = DAG->getConstant(0, Loc, InVecVT);
107 auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
108 auto DemandedElts = APInt(2, 3);
109 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
110
111 // We don't know anything for SVE at the moment.
112 EXPECT_EQ(Known.Zero, APInt(16, 0u));
113 EXPECT_EQ(Known.One, APInt(16, 0u));
114 EXPECT_FALSE(Known.isZero());
115 }
116
TEST_F(AArch64SelectionDAGTest,computeKnownBits_EXTRACT_SUBVECTOR)117 TEST_F(AArch64SelectionDAGTest, computeKnownBits_EXTRACT_SUBVECTOR) {
118 SDLoc Loc;
119 auto IntVT = EVT::getIntegerVT(Context, 8);
120 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
121 auto IdxVT = EVT::getIntegerVT(Context, 64);
122 auto Vec = DAG->getConstant(0, Loc, VecVT);
123 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
124 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
125 auto DemandedElts = APInt(3, 7);
126 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
127 EXPECT_TRUE(Known.isZero());
128 }
129
TEST_F(AArch64SelectionDAGTest,ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG)130 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG) {
131 SDLoc Loc;
132 auto Int8VT = EVT::getIntegerVT(Context, 8);
133 auto Int16VT = EVT::getIntegerVT(Context, 16);
134 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);
135 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);
136 auto InVec = DAG->getConstant(1, Loc, InVecVT);
137 auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
138 auto DemandedElts = APInt(2, 3);
139 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 15u);
140 }
141
TEST_F(AArch64SelectionDAGTest,ComputeNumSignBitsSVE_SIGN_EXTEND_VECTOR_INREG)142 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBitsSVE_SIGN_EXTEND_VECTOR_INREG) {
143 SDLoc Loc;
144 auto Int8VT = EVT::getIntegerVT(Context, 8);
145 auto Int16VT = EVT::getIntegerVT(Context, 16);
146 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, /*IsScalable=*/true);
147 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, /*IsScalable=*/true);
148 auto InVec = DAG->getConstant(1, Loc, InVecVT);
149 auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
150 auto DemandedElts = APInt(2, 3);
151 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 1u);
152 }
153
TEST_F(AArch64SelectionDAGTest,ComputeNumSignBits_EXTRACT_SUBVECTOR)154 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_EXTRACT_SUBVECTOR) {
155 SDLoc Loc;
156 auto IntVT = EVT::getIntegerVT(Context, 8);
157 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
158 auto IdxVT = EVT::getIntegerVT(Context, 64);
159 auto Vec = DAG->getConstant(1, Loc, VecVT);
160 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
161 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
162 auto DemandedElts = APInt(3, 7);
163 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 7u);
164 }
165
TEST_F(AArch64SelectionDAGTest,SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR)166 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) {
167 TargetLowering TL(*TM);
168
169 SDLoc Loc;
170 auto IntVT = EVT::getIntegerVT(Context, 8);
171 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
172 auto IdxVT = EVT::getIntegerVT(Context, 64);
173 auto Vec = DAG->getConstant(1, Loc, VecVT);
174 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
175 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
176 auto DemandedElts = APInt(3, 7);
177 auto KnownUndef = APInt(3, 0);
178 auto KnownZero = APInt(3, 0);
179 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
180 EXPECT_EQ(TL.SimplifyDemandedVectorElts(Op, DemandedElts, KnownUndef,
181 KnownZero, TLO),
182 false);
183 }
184
TEST_F(AArch64SelectionDAGTest,SimplifyDemandedBitsNEON)185 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) {
186 TargetLowering TL(*TM);
187
188 SDLoc Loc;
189 auto Int8VT = EVT::getIntegerVT(Context, 8);
190 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16);
191 SDValue UnknownOp = DAG->getRegister(0, InVecVT);
192 SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);
193 SDValue Mask1V = DAG->getSplatBuildVector(InVecVT, Loc, Mask1S);
194 SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);
195
196 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT);
197 SDValue Mask2V = DAG->getSplatBuildVector(InVecVT, Loc, Mask2S);
198
199 SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V);
200 // N0 = ?000?0?0
201 // Mask2V = 01010101
202 // =>
203 // Known.Zero = 00100000 (0xAA)
204 KnownBits Known;
205 APInt DemandedBits = APInt(8, 0xFF);
206 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
207 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
208 EXPECT_EQ(Known.Zero, APInt(8, 0xAA));
209 }
210
TEST_F(AArch64SelectionDAGTest,SimplifyDemandedBitsSVE)211 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) {
212 TargetLowering TL(*TM);
213
214 SDLoc Loc;
215 auto Int8VT = EVT::getIntegerVT(Context, 8);
216 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16, /*IsScalable=*/true);
217 SDValue UnknownOp = DAG->getRegister(0, InVecVT);
218 SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);
219 SDValue Mask1V = DAG->getSplatVector(InVecVT, Loc, Mask1S);
220 SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);
221
222 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT);
223 SDValue Mask2V = DAG->getSplatVector(InVecVT, Loc, Mask2S);
224
225 SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V);
226
227 KnownBits Known;
228 APInt DemandedBits = APInt(8, 0xFF);
229 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
230 EXPECT_FALSE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
231 EXPECT_EQ(Known.Zero, APInt(8, 0));
232 }
233
234 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
TEST_F(AArch64SelectionDAGTest,ComputeKnownBits_ADD)235 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {
236 SDLoc Loc;
237 auto IntVT = EVT::getIntegerVT(Context, 8);
238 auto UnknownOp = DAG->getRegister(0, IntVT);
239 auto Mask = DAG->getConstant(0x8A, Loc, IntVT);
240 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
241 auto N1 = DAG->getConstant(0x55, Loc, IntVT);
242 auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1);
243 // N0 = ?000?0?0
244 // N1 = 01010101
245 // =>
246 // Known.One = 01010101 (0x55)
247 // Known.Zero = 00100000 (0x20)
248 KnownBits Known = DAG->computeKnownBits(Op);
249 EXPECT_EQ(Known.Zero, APInt(8, 0x20));
250 EXPECT_EQ(Known.One, APInt(8, 0x55));
251 }
252
253 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
TEST_F(AArch64SelectionDAGTest,ComputeKnownBits_SUB)254 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
255 SDLoc Loc;
256 auto IntVT = EVT::getIntegerVT(Context, 8);
257 auto N0 = DAG->getConstant(0x55, Loc, IntVT);
258 auto UnknownOp = DAG->getRegister(0, IntVT);
259 auto Mask = DAG->getConstant(0x2e, Loc, IntVT);
260 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
261 auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
262 // N0 = 01010101
263 // N1 = 00?0???0
264 // =>
265 // Known.One = 00000001 (0x1)
266 // Known.Zero = 10000000 (0x80)
267 KnownBits Known = DAG->computeKnownBits(Op);
268 EXPECT_EQ(Known.Zero, APInt(8, 0x80));
269 EXPECT_EQ(Known.One, APInt(8, 0x1));
270 }
271
TEST_F(AArch64SelectionDAGTest,isSplatValue_Fixed_BUILD_VECTOR)272 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) {
273 TargetLowering TL(*TM);
274
275 SDLoc Loc;
276 auto IntVT = EVT::getIntegerVT(Context, 8);
277 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
278 // Create a BUILD_VECTOR
279 SDValue Op = DAG->getConstant(1, Loc, VecVT);
280 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
281 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
282
283 APInt UndefElts;
284 APInt DemandedElts;
285 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
286
287 // Width=16, Mask=3
288 DemandedElts = APInt(16, 3);
289 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
290 }
291
TEST_F(AArch64SelectionDAGTest,isSplatValue_Fixed_ADD_of_BUILD_VECTOR)292 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) {
293 TargetLowering TL(*TM);
294
295 SDLoc Loc;
296 auto IntVT = EVT::getIntegerVT(Context, 8);
297 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
298
299 // Should create BUILD_VECTORs
300 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
301 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
302 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
303 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
304
305 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
306
307 APInt UndefElts;
308 APInt DemandedElts;
309 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
310
311 // Width=16, Mask=3
312 DemandedElts = APInt(16, 3);
313 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
314 }
315
TEST_F(AArch64SelectionDAGTest,isSplatValue_Scalable_SPLAT_VECTOR)316 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) {
317 TargetLowering TL(*TM);
318
319 SDLoc Loc;
320 auto IntVT = EVT::getIntegerVT(Context, 8);
321 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
322 // Create a SPLAT_VECTOR
323 SDValue Op = DAG->getConstant(1, Loc, VecVT);
324 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
325 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
326
327 APInt UndefElts;
328 APInt DemandedElts;
329 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
330
331 // Width=16, Mask=3. These bits should be ignored.
332 DemandedElts = APInt(16, 3);
333 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
334 }
335
TEST_F(AArch64SelectionDAGTest,isSplatValue_Scalable_ADD_of_SPLAT_VECTOR)336 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) {
337 TargetLowering TL(*TM);
338
339 SDLoc Loc;
340 auto IntVT = EVT::getIntegerVT(Context, 8);
341 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
342
343 // Should create SPLAT_VECTORS
344 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
345 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
346 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
347 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
348
349 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
350
351 APInt UndefElts;
352 APInt DemandedElts;
353 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
354
355 // Width=16, Mask=3. These bits should be ignored.
356 DemandedElts = APInt(16, 3);
357 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
358 }
359
TEST_F(AArch64SelectionDAGTest,getSplatSourceVector_Fixed_BUILD_VECTOR)360 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) {
361 TargetLowering TL(*TM);
362
363 SDLoc Loc;
364 auto IntVT = EVT::getIntegerVT(Context, 8);
365 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
366 // Create a BUILD_VECTOR
367 SDValue Op = DAG->getConstant(1, Loc, VecVT);
368 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
369
370 int SplatIdx = -1;
371 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
372 EXPECT_EQ(SplatIdx, 0);
373 }
374
TEST_F(AArch64SelectionDAGTest,getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR)375 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) {
376 TargetLowering TL(*TM);
377
378 SDLoc Loc;
379 auto IntVT = EVT::getIntegerVT(Context, 8);
380 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
381
382 // Should create BUILD_VECTORs
383 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
384 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
385 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
386 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
387
388 int SplatIdx = -1;
389 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
390 EXPECT_EQ(SplatIdx, 0);
391 }
392
TEST_F(AArch64SelectionDAGTest,getSplatSourceVector_Scalable_SPLAT_VECTOR)393 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) {
394 TargetLowering TL(*TM);
395
396 SDLoc Loc;
397 auto IntVT = EVT::getIntegerVT(Context, 8);
398 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
399 // Create a SPLAT_VECTOR
400 SDValue Op = DAG->getConstant(1, Loc, VecVT);
401 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
402
403 int SplatIdx = -1;
404 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
405 EXPECT_EQ(SplatIdx, 0);
406 }
407
TEST_F(AArch64SelectionDAGTest,getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR)408 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) {
409 TargetLowering TL(*TM);
410
411 SDLoc Loc;
412 auto IntVT = EVT::getIntegerVT(Context, 8);
413 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
414
415 // Should create SPLAT_VECTORS
416 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
417 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
418 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
419 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
420
421 int SplatIdx = -1;
422 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
423 EXPECT_EQ(SplatIdx, 0);
424 }
425
TEST_F(AArch64SelectionDAGTest,getRepeatedSequence_Patterns)426 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) {
427 TargetLowering TL(*TM);
428
429 SDLoc Loc;
430 unsigned NumElts = 16;
431 MVT IntVT = MVT::i8;
432 MVT VecVT = MVT::getVectorVT(IntVT, NumElts);
433
434 // Base scalar constants.
435 SDValue Val0 = DAG->getConstant(0, Loc, IntVT);
436 SDValue Val1 = DAG->getConstant(1, Loc, IntVT);
437 SDValue Val2 = DAG->getConstant(2, Loc, IntVT);
438 SDValue Val3 = DAG->getConstant(3, Loc, IntVT);
439 SDValue UndefVal = DAG->getUNDEF(IntVT);
440
441 // Build some repeating sequences.
442 SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123;
443 for(int I = 0; I != 4; ++I) {
444 Pattern1111.append(4, Val1);
445 Pattern1133.append(2, Val1);
446 Pattern1133.append(2, Val3);
447 Pattern0123.push_back(Val0);
448 Pattern0123.push_back(Val1);
449 Pattern0123.push_back(Val2);
450 Pattern0123.push_back(Val3);
451 }
452
453 // Build a non-pow2 repeating sequence.
454 SmallVector<SDValue, 16> Pattern022;
455 Pattern022.push_back(Val0);
456 Pattern022.append(2, Val2);
457 Pattern022.push_back(Val0);
458 Pattern022.append(2, Val2);
459 Pattern022.push_back(Val0);
460 Pattern022.append(2, Val2);
461 Pattern022.push_back(Val0);
462 Pattern022.append(2, Val2);
463 Pattern022.push_back(Val0);
464 Pattern022.append(2, Val2);
465 Pattern022.push_back(Val0);
466
467 // Build a non-repeating sequence.
468 SmallVector<SDValue, 16> Pattern1_3;
469 Pattern1_3.append(8, Val1);
470 Pattern1_3.append(8, Val3);
471
472 // Add some undefs to make it trickier.
473 Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal;
474 Pattern1133[0] = Pattern1133[2] = UndefVal;
475
476 auto *BV1111 =
477 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111));
478 auto *BV1133 =
479 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133));
480 auto *BV0123=
481 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123));
482 auto *BV022 =
483 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022));
484 auto *BV1_3 =
485 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3));
486
487 // Check for sequences.
488 SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3;
489 BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3;
490
491 EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111));
492 EXPECT_EQ(Undefs1111.count(), 3u);
493 EXPECT_EQ(Seq1111.size(), 1u);
494 EXPECT_EQ(Seq1111[0], Val1);
495
496 EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133));
497 EXPECT_EQ(Undefs1133.count(), 2u);
498 EXPECT_EQ(Seq1133.size(), 4u);
499 EXPECT_EQ(Seq1133[0], Val1);
500 EXPECT_EQ(Seq1133[1], Val1);
501 EXPECT_EQ(Seq1133[2], Val3);
502 EXPECT_EQ(Seq1133[3], Val3);
503
504 EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123));
505 EXPECT_EQ(Undefs0123.count(), 0u);
506 EXPECT_EQ(Seq0123.size(), 4u);
507 EXPECT_EQ(Seq0123[0], Val0);
508 EXPECT_EQ(Seq0123[1], Val1);
509 EXPECT_EQ(Seq0123[2], Val2);
510 EXPECT_EQ(Seq0123[3], Val3);
511
512 EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022));
513 EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3));
514
515 // Try again with DemandedElts masks.
516 APInt Mask1111_0 = APInt::getOneBitSet(NumElts, 0);
517 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111));
518 EXPECT_EQ(Undefs1111.count(), 0u);
519 EXPECT_EQ(Seq1111.size(), 1u);
520 EXPECT_EQ(Seq1111[0], Val1);
521
522 APInt Mask1111_1 = APInt::getOneBitSet(NumElts, 2);
523 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111));
524 EXPECT_EQ(Undefs1111.count(), 1u);
525 EXPECT_EQ(Seq1111.size(), 1u);
526 EXPECT_EQ(Seq1111[0], UndefVal);
527
528 APInt Mask0123 = APInt(NumElts, 0x7777);
529 EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123));
530 EXPECT_EQ(Undefs0123.count(), 0u);
531 EXPECT_EQ(Seq0123.size(), 4u);
532 EXPECT_EQ(Seq0123[0], Val0);
533 EXPECT_EQ(Seq0123[1], Val1);
534 EXPECT_EQ(Seq0123[2], Val2);
535 EXPECT_EQ(Seq0123[3], SDValue());
536
537 APInt Mask1_3 = APInt::getHighBitsSet(16, 8);
538 EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3));
539 EXPECT_EQ(Undefs1_3.count(), 0u);
540 EXPECT_EQ(Seq1_3.size(), 1u);
541 EXPECT_EQ(Seq1_3[0], Val3);
542 }
543
TEST_F(AArch64SelectionDAGTest,getTypeConversion_SplitScalableMVT)544 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) {
545 MVT VT = MVT::nxv4i64;
546 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
547 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
548 }
549
TEST_F(AArch64SelectionDAGTest,getTypeConversion_PromoteScalableMVT)550 TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) {
551 MVT VT = MVT::nxv2i32;
552 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger);
553 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
554 }
555
TEST_F(AArch64SelectionDAGTest,getTypeConversion_NoScalarizeMVT_nxv1f32)556 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) {
557 MVT VT = MVT::nxv1f32;
558 EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector);
559 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
560 }
561
TEST_F(AArch64SelectionDAGTest,getTypeConversion_SplitScalableEVT)562 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) {
563 EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true);
564 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
565 EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context));
566 }
567
TEST_F(AArch64SelectionDAGTest,getTypeConversion_WidenScalableEVT)568 TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) {
569 EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true);
570 EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true);
571
572 EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector);
573 EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT);
574 }
575
TEST_F(AArch64SelectionDAGTest,getTypeConversion_ScalarizeScalableEVT_nxv1f128)576 TEST_F(AArch64SelectionDAGTest,
577 getTypeConversion_ScalarizeScalableEVT_nxv1f128) {
578 EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(1));
579 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector);
580 EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128);
581 }
582
TEST_F(AArch64SelectionDAGTest,TestFold_STEP_VECTOR)583 TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) {
584 SDLoc Loc;
585 auto IntVT = EVT::getIntegerVT(Context, 8);
586 auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true);
587
588 // Should create SPLAT_VECTOR
589 SDValue Zero = DAG->getConstant(0, Loc, IntVT);
590 SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero);
591 EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR);
592 }
593
594 } // end namespace llvm
595