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