xref: /llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp (revision b6a01caa64aaac2e5db8d7953a81cbe1a139b81f)
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/MC/TargetRegistry.h"
15 #include "llvm/Support/KnownBits.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 namespace llvm {
22 
23 class AArch64SelectionDAGTest : public testing::Test {
24 protected:
25   static void SetUpTestCase() {
26     InitializeAllTargets();
27     InitializeAllTargetMCs();
28   }
29 
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, std::nullopt,
45                                std::nullopt, 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 
71   TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) {
72     return DAG->getTargetLoweringInfo().getTypeAction(Context, VT);
73   }
74 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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.
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.
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 
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 
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 
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(1,1);
329   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
330 }
331 
332 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) {
333   TargetLowering TL(*TM);
334 
335   SDLoc Loc;
336   auto IntVT = EVT::getIntegerVT(Context, 8);
337   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
338 
339   // Should create SPLAT_VECTORS
340   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
341   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
342   EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
343   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
344 
345   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
346 
347   APInt UndefElts;
348   APInt DemandedElts(1, 1);
349   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
350 }
351 
352 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) {
353   TargetLowering TL(*TM);
354 
355   SDLoc Loc;
356   auto IntVT = EVT::getIntegerVT(Context, 8);
357   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
358   // Create a BUILD_VECTOR
359   SDValue Op = DAG->getConstant(1, Loc, VecVT);
360   EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
361 
362   int SplatIdx = -1;
363   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
364   EXPECT_EQ(SplatIdx, 0);
365 }
366 
367 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) {
368   TargetLowering TL(*TM);
369 
370   SDLoc Loc;
371   auto IntVT = EVT::getIntegerVT(Context, 8);
372   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
373 
374   // Should create BUILD_VECTORs
375   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
376   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
377   EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
378   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
379 
380   int SplatIdx = -1;
381   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
382   EXPECT_EQ(SplatIdx, 0);
383 }
384 
385 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) {
386   TargetLowering TL(*TM);
387 
388   SDLoc Loc;
389   auto IntVT = EVT::getIntegerVT(Context, 8);
390   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
391   // Create a SPLAT_VECTOR
392   SDValue Op = DAG->getConstant(1, Loc, VecVT);
393   EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
394 
395   int SplatIdx = -1;
396   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
397   EXPECT_EQ(SplatIdx, 0);
398 }
399 
400 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) {
401   TargetLowering TL(*TM);
402 
403   SDLoc Loc;
404   auto IntVT = EVT::getIntegerVT(Context, 8);
405   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
406 
407   // Should create SPLAT_VECTORS
408   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
409   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
410   EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
411   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
412 
413   int SplatIdx = -1;
414   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
415   EXPECT_EQ(SplatIdx, 0);
416 }
417 
418 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) {
419   TargetLowering TL(*TM);
420 
421   SDLoc Loc;
422   unsigned NumElts = 16;
423   MVT IntVT = MVT::i8;
424   MVT VecVT = MVT::getVectorVT(IntVT, NumElts);
425 
426   // Base scalar constants.
427   SDValue Val0 = DAG->getConstant(0, Loc, IntVT);
428   SDValue Val1 = DAG->getConstant(1, Loc, IntVT);
429   SDValue Val2 = DAG->getConstant(2, Loc, IntVT);
430   SDValue Val3 = DAG->getConstant(3, Loc, IntVT);
431   SDValue UndefVal = DAG->getUNDEF(IntVT);
432 
433   // Build some repeating sequences.
434   SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123;
435   for(int I = 0; I != 4; ++I) {
436     Pattern1111.append(4, Val1);
437     Pattern1133.append(2, Val1);
438     Pattern1133.append(2, Val3);
439     Pattern0123.push_back(Val0);
440     Pattern0123.push_back(Val1);
441     Pattern0123.push_back(Val2);
442     Pattern0123.push_back(Val3);
443   }
444 
445   // Build a non-pow2 repeating sequence.
446   SmallVector<SDValue, 16> Pattern022;
447   Pattern022.push_back(Val0);
448   Pattern022.append(2, Val2);
449   Pattern022.push_back(Val0);
450   Pattern022.append(2, Val2);
451   Pattern022.push_back(Val0);
452   Pattern022.append(2, Val2);
453   Pattern022.push_back(Val0);
454   Pattern022.append(2, Val2);
455   Pattern022.push_back(Val0);
456   Pattern022.append(2, Val2);
457   Pattern022.push_back(Val0);
458 
459   // Build a non-repeating sequence.
460   SmallVector<SDValue, 16> Pattern1_3;
461   Pattern1_3.append(8, Val1);
462   Pattern1_3.append(8, Val3);
463 
464   // Add some undefs to make it trickier.
465   Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal;
466   Pattern1133[0] = Pattern1133[2] = UndefVal;
467 
468   auto *BV1111 =
469       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111));
470   auto *BV1133 =
471       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133));
472   auto *BV0123=
473       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123));
474   auto *BV022 =
475       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022));
476   auto *BV1_3 =
477       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3));
478 
479   // Check for sequences.
480   SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3;
481   BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3;
482 
483   EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111));
484   EXPECT_EQ(Undefs1111.count(), 3u);
485   EXPECT_EQ(Seq1111.size(), 1u);
486   EXPECT_EQ(Seq1111[0], Val1);
487 
488   EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133));
489   EXPECT_EQ(Undefs1133.count(), 2u);
490   EXPECT_EQ(Seq1133.size(), 4u);
491   EXPECT_EQ(Seq1133[0], Val1);
492   EXPECT_EQ(Seq1133[1], Val1);
493   EXPECT_EQ(Seq1133[2], Val3);
494   EXPECT_EQ(Seq1133[3], Val3);
495 
496   EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123));
497   EXPECT_EQ(Undefs0123.count(), 0u);
498   EXPECT_EQ(Seq0123.size(), 4u);
499   EXPECT_EQ(Seq0123[0], Val0);
500   EXPECT_EQ(Seq0123[1], Val1);
501   EXPECT_EQ(Seq0123[2], Val2);
502   EXPECT_EQ(Seq0123[3], Val3);
503 
504   EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022));
505   EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3));
506 
507   // Try again with DemandedElts masks.
508   APInt Mask1111_0 = APInt::getOneBitSet(NumElts, 0);
509   EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111));
510   EXPECT_EQ(Undefs1111.count(), 0u);
511   EXPECT_EQ(Seq1111.size(), 1u);
512   EXPECT_EQ(Seq1111[0], Val1);
513 
514   APInt Mask1111_1 = APInt::getOneBitSet(NumElts, 2);
515   EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111));
516   EXPECT_EQ(Undefs1111.count(), 1u);
517   EXPECT_EQ(Seq1111.size(), 1u);
518   EXPECT_EQ(Seq1111[0], UndefVal);
519 
520   APInt Mask0123 = APInt(NumElts, 0x7777);
521   EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123));
522   EXPECT_EQ(Undefs0123.count(), 0u);
523   EXPECT_EQ(Seq0123.size(), 4u);
524   EXPECT_EQ(Seq0123[0], Val0);
525   EXPECT_EQ(Seq0123[1], Val1);
526   EXPECT_EQ(Seq0123[2], Val2);
527   EXPECT_EQ(Seq0123[3], SDValue());
528 
529   APInt Mask1_3 = APInt::getHighBitsSet(16, 8);
530   EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3));
531   EXPECT_EQ(Undefs1_3.count(), 0u);
532   EXPECT_EQ(Seq1_3.size(), 1u);
533   EXPECT_EQ(Seq1_3[0], Val3);
534 }
535 
536 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) {
537   MVT VT = MVT::nxv4i64;
538   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
539   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
540 }
541 
542 TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) {
543   MVT VT = MVT::nxv2i32;
544   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger);
545   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
546 }
547 
548 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) {
549   MVT VT = MVT::nxv1f32;
550   EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector);
551   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
552 }
553 
554 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) {
555   EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true);
556   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
557   EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context));
558 }
559 
560 TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) {
561   EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true);
562   EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true);
563 
564   EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector);
565   EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT);
566 }
567 
568 TEST_F(AArch64SelectionDAGTest,
569        getTypeConversion_ScalarizeScalableEVT_nxv1f128) {
570   EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(1));
571   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector);
572   EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128);
573 }
574 
575 TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) {
576   SDLoc Loc;
577   auto IntVT = EVT::getIntegerVT(Context, 8);
578   auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true);
579 
580   // Should create SPLAT_VECTOR
581   SDValue Zero = DAG->getConstant(0, Loc, IntVT);
582   SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero);
583   EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR);
584 }
585 
586 TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) {
587   SDLoc Loc;
588   EVT IntVT = EVT::getIntegerVT(Context, 8);
589 
590   SDValue N0 = DAG->getConstant(0x42, Loc, IntVT);
591   SDValue N1 = DAG->getRegister(0, IntVT);
592   // Construct node to fill arbitrary ExtraInfo.
593   SDValue N2 = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
594   EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode()));
595   EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode()));
596   EXPECT_FALSE(DAG->getPCSections(N2.getNode()));
597   MDNode *MD = MDNode::get(Context, std::nullopt);
598   DAG->addHeapAllocSite(N2.getNode(), MD);
599   DAG->addNoMergeSiteInfo(N2.getNode(), true);
600   DAG->addPCSections(N2.getNode(), MD);
601   EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD);
602   EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode()));
603   EXPECT_EQ(DAG->getPCSections(N2.getNode()), MD);
604 
605   SDValue Root = DAG->getNode(ISD::ADD, Loc, IntVT, N2, N2);
606   EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB);
607   // Create new node and check that ExtraInfo is propagated on RAUW.
608   SDValue New = DAG->getNode(ISD::ADD, Loc, IntVT, N1, N1);
609   EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode()));
610   EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode()));
611   EXPECT_FALSE(DAG->getPCSections(New.getNode()));
612 
613   DAG->ReplaceAllUsesWith(N2, New);
614   EXPECT_EQ(Root->getOperand(0), New);
615   EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD);
616   EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode()));
617   EXPECT_EQ(DAG->getPCSections(New.getNode()), MD);
618 }
619 
620 } // end namespace llvm
621