xref: /llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp (revision fc546f46cd7d09ee8563bdd820f80ed3b022154f)
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, 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   // N0 = ?000?0?0
228   // Mask2V = 01010101
229   //  =>
230   // Known.Zero = 00100000 (0xAA)
231   KnownBits Known;
232   APInt DemandedBits = APInt(8, 0xFF);
233   TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
234   EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
235   EXPECT_EQ(Known.Zero, APInt(8, 0xAA));
236 }
237 
238 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
239 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {
240   SDLoc Loc;
241   auto IntVT = EVT::getIntegerVT(Context, 8);
242   auto UnknownOp = DAG->getRegister(0, IntVT);
243   auto Mask = DAG->getConstant(0x8A, Loc, IntVT);
244   auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
245   auto N1 = DAG->getConstant(0x55, Loc, IntVT);
246   auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1);
247   // N0 = ?000?0?0
248   // N1 = 01010101
249   //  =>
250   // Known.One  = 01010101 (0x55)
251   // Known.Zero = 00100000 (0x20)
252   KnownBits Known = DAG->computeKnownBits(Op);
253   EXPECT_EQ(Known.Zero, APInt(8, 0x20));
254   EXPECT_EQ(Known.One, APInt(8, 0x55));
255 }
256 
257 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
258 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
259   SDLoc Loc;
260   auto IntVT = EVT::getIntegerVT(Context, 8);
261   auto N0 = DAG->getConstant(0x55, Loc, IntVT);
262   auto UnknownOp = DAG->getRegister(0, IntVT);
263   auto Mask = DAG->getConstant(0x2e, Loc, IntVT);
264   auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
265   auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
266   // N0 = 01010101
267   // N1 = 00?0???0
268   //  =>
269   // Known.One  = 00000001 (0x1)
270   // Known.Zero = 10000000 (0x80)
271   KnownBits Known = DAG->computeKnownBits(Op);
272   EXPECT_EQ(Known.Zero, APInt(8, 0x80));
273   EXPECT_EQ(Known.One, APInt(8, 0x1));
274 }
275 
276 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) {
277   TargetLowering TL(*TM);
278 
279   SDLoc Loc;
280   auto IntVT = EVT::getIntegerVT(Context, 8);
281   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
282   // Create a BUILD_VECTOR
283   SDValue Op = DAG->getConstant(1, Loc, VecVT);
284   EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
285   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
286 
287   APInt UndefElts;
288   APInt DemandedElts;
289   EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
290 
291   // Width=16, Mask=3
292   DemandedElts = APInt(16, 3);
293   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
294 }
295 
296 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) {
297   TargetLowering TL(*TM);
298 
299   SDLoc Loc;
300   auto IntVT = EVT::getIntegerVT(Context, 8);
301   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
302 
303   // Should create BUILD_VECTORs
304   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
305   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
306   EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
307   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
308 
309   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
310 
311   APInt UndefElts;
312   APInt DemandedElts;
313   EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
314 
315   // Width=16, Mask=3
316   DemandedElts = APInt(16, 3);
317   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
318 }
319 
320 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) {
321   TargetLowering TL(*TM);
322 
323   SDLoc Loc;
324   auto IntVT = EVT::getIntegerVT(Context, 8);
325   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
326   // Create a SPLAT_VECTOR
327   SDValue Op = DAG->getConstant(1, Loc, VecVT);
328   EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
329   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
330 
331   APInt UndefElts;
332   APInt DemandedElts(1,1);
333   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
334 }
335 
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(1, 1);
353   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
354 }
355 
356 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) {
357   TargetLowering TL(*TM);
358 
359   SDLoc Loc;
360   auto IntVT = EVT::getIntegerVT(Context, 8);
361   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
362   // Create a BUILD_VECTOR
363   SDValue Op = DAG->getConstant(1, Loc, VecVT);
364   EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
365 
366   int SplatIdx = -1;
367   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
368   EXPECT_EQ(SplatIdx, 0);
369 }
370 
371 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) {
372   TargetLowering TL(*TM);
373 
374   SDLoc Loc;
375   auto IntVT = EVT::getIntegerVT(Context, 8);
376   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
377 
378   // Should create BUILD_VECTORs
379   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
380   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
381   EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
382   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
383 
384   int SplatIdx = -1;
385   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
386   EXPECT_EQ(SplatIdx, 0);
387 }
388 
389 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) {
390   TargetLowering TL(*TM);
391 
392   SDLoc Loc;
393   auto IntVT = EVT::getIntegerVT(Context, 8);
394   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
395   // Create a SPLAT_VECTOR
396   SDValue Op = DAG->getConstant(1, Loc, VecVT);
397   EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
398 
399   int SplatIdx = -1;
400   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
401   EXPECT_EQ(SplatIdx, 0);
402 }
403 
404 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) {
405   TargetLowering TL(*TM);
406 
407   SDLoc Loc;
408   auto IntVT = EVT::getIntegerVT(Context, 8);
409   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
410 
411   // Should create SPLAT_VECTORS
412   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
413   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
414   EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
415   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
416 
417   int SplatIdx = -1;
418   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
419   EXPECT_EQ(SplatIdx, 0);
420 }
421 
422 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) {
423   TargetLowering TL(*TM);
424 
425   SDLoc Loc;
426   unsigned NumElts = 16;
427   MVT IntVT = MVT::i8;
428   MVT VecVT = MVT::getVectorVT(IntVT, NumElts);
429 
430   // Base scalar constants.
431   SDValue Val0 = DAG->getConstant(0, Loc, IntVT);
432   SDValue Val1 = DAG->getConstant(1, Loc, IntVT);
433   SDValue Val2 = DAG->getConstant(2, Loc, IntVT);
434   SDValue Val3 = DAG->getConstant(3, Loc, IntVT);
435   SDValue UndefVal = DAG->getUNDEF(IntVT);
436 
437   // Build some repeating sequences.
438   SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123;
439   for(int I = 0; I != 4; ++I) {
440     Pattern1111.append(4, Val1);
441     Pattern1133.append(2, Val1);
442     Pattern1133.append(2, Val3);
443     Pattern0123.push_back(Val0);
444     Pattern0123.push_back(Val1);
445     Pattern0123.push_back(Val2);
446     Pattern0123.push_back(Val3);
447   }
448 
449   // Build a non-pow2 repeating sequence.
450   SmallVector<SDValue, 16> Pattern022;
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   Pattern022.append(2, Val2);
459   Pattern022.push_back(Val0);
460   Pattern022.append(2, Val2);
461   Pattern022.push_back(Val0);
462 
463   // Build a non-repeating sequence.
464   SmallVector<SDValue, 16> Pattern1_3;
465   Pattern1_3.append(8, Val1);
466   Pattern1_3.append(8, Val3);
467 
468   // Add some undefs to make it trickier.
469   Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal;
470   Pattern1133[0] = Pattern1133[2] = UndefVal;
471 
472   auto *BV1111 =
473       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111));
474   auto *BV1133 =
475       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133));
476   auto *BV0123=
477       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123));
478   auto *BV022 =
479       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022));
480   auto *BV1_3 =
481       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3));
482 
483   // Check for sequences.
484   SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3;
485   BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3;
486 
487   EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111));
488   EXPECT_EQ(Undefs1111.count(), 3u);
489   EXPECT_EQ(Seq1111.size(), 1u);
490   EXPECT_EQ(Seq1111[0], Val1);
491 
492   EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133));
493   EXPECT_EQ(Undefs1133.count(), 2u);
494   EXPECT_EQ(Seq1133.size(), 4u);
495   EXPECT_EQ(Seq1133[0], Val1);
496   EXPECT_EQ(Seq1133[1], Val1);
497   EXPECT_EQ(Seq1133[2], Val3);
498   EXPECT_EQ(Seq1133[3], Val3);
499 
500   EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123));
501   EXPECT_EQ(Undefs0123.count(), 0u);
502   EXPECT_EQ(Seq0123.size(), 4u);
503   EXPECT_EQ(Seq0123[0], Val0);
504   EXPECT_EQ(Seq0123[1], Val1);
505   EXPECT_EQ(Seq0123[2], Val2);
506   EXPECT_EQ(Seq0123[3], Val3);
507 
508   EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022));
509   EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3));
510 
511   // Try again with DemandedElts masks.
512   APInt Mask1111_0 = APInt::getOneBitSet(NumElts, 0);
513   EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111));
514   EXPECT_EQ(Undefs1111.count(), 0u);
515   EXPECT_EQ(Seq1111.size(), 1u);
516   EXPECT_EQ(Seq1111[0], Val1);
517 
518   APInt Mask1111_1 = APInt::getOneBitSet(NumElts, 2);
519   EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111));
520   EXPECT_EQ(Undefs1111.count(), 1u);
521   EXPECT_EQ(Seq1111.size(), 1u);
522   EXPECT_EQ(Seq1111[0], UndefVal);
523 
524   APInt Mask0123 = APInt(NumElts, 0x7777);
525   EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123));
526   EXPECT_EQ(Undefs0123.count(), 0u);
527   EXPECT_EQ(Seq0123.size(), 4u);
528   EXPECT_EQ(Seq0123[0], Val0);
529   EXPECT_EQ(Seq0123[1], Val1);
530   EXPECT_EQ(Seq0123[2], Val2);
531   EXPECT_EQ(Seq0123[3], SDValue());
532 
533   APInt Mask1_3 = APInt::getHighBitsSet(16, 8);
534   EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3));
535   EXPECT_EQ(Undefs1_3.count(), 0u);
536   EXPECT_EQ(Seq1_3.size(), 1u);
537   EXPECT_EQ(Seq1_3[0], Val3);
538 }
539 
540 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) {
541   MVT VT = MVT::nxv4i64;
542   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
543   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
544 }
545 
546 TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) {
547   MVT VT = MVT::nxv2i32;
548   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger);
549   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
550 }
551 
552 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) {
553   MVT VT = MVT::nxv1f32;
554   EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector);
555   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
556 }
557 
558 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) {
559   EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true);
560   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
561   EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context));
562 }
563 
564 TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) {
565   EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true);
566   EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true);
567 
568   EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector);
569   EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT);
570 }
571 
572 TEST_F(AArch64SelectionDAGTest,
573        getTypeConversion_ScalarizeScalableEVT_nxv1f128) {
574   EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(1));
575   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector);
576   EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128);
577 }
578 
579 TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) {
580   SDLoc Loc;
581   auto IntVT = EVT::getIntegerVT(Context, 8);
582   auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true);
583 
584   // Should create SPLAT_VECTOR
585   SDValue Zero = DAG->getConstant(0, Loc, IntVT);
586   SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero);
587   EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR);
588 }
589 
590 TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) {
591   SDLoc Loc;
592   EVT IntVT = EVT::getIntegerVT(Context, 8);
593 
594   SDValue N0 = DAG->getConstant(0x42, Loc, IntVT);
595   SDValue N1 = DAG->getRegister(0, IntVT);
596   // Construct node to fill arbitrary ExtraInfo.
597   SDValue N2 = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
598   EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode()));
599   EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode()));
600   EXPECT_FALSE(DAG->getPCSections(N2.getNode()));
601   MDNode *MD = MDNode::get(Context, std::nullopt);
602   DAG->addHeapAllocSite(N2.getNode(), MD);
603   DAG->addNoMergeSiteInfo(N2.getNode(), true);
604   DAG->addPCSections(N2.getNode(), MD);
605   EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD);
606   EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode()));
607   EXPECT_EQ(DAG->getPCSections(N2.getNode()), MD);
608 
609   SDValue Root = DAG->getNode(ISD::ADD, Loc, IntVT, N2, N2);
610   EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB);
611   // Create new node and check that ExtraInfo is propagated on RAUW.
612   SDValue New = DAG->getNode(ISD::ADD, Loc, IntVT, N1, N1);
613   EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode()));
614   EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode()));
615   EXPECT_FALSE(DAG->getPCSections(New.getNode()));
616 
617   DAG->ReplaceAllUsesWith(N2, New);
618   EXPECT_EQ(Root->getOperand(0), New);
619   EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD);
620   EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode()));
621   EXPECT_EQ(DAG->getPCSections(New.getNode()), MD);
622 }
623 
624 } // end namespace llvm
625