xref: /llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp (revision 730df5a437914e66b292dd9cb7d5f3f47b73bab0)
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, CodeGenOptLevel::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, CodeGenOptLevel::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_UADDO_CARRY) {
259   SDLoc Loc;
260   auto IntVT = EVT::getIntegerVT(Context, 8);
261   auto UnknownOp = DAG->getRegister(0, IntVT);
262   auto Mask_Zero = DAG->getConstant(0x28, Loc, IntVT);
263   auto Mask_One = DAG->getConstant(0x20, Loc, IntVT);
264   auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask_Zero, UnknownOp);
265   N0 = DAG->getNode(ISD::OR, Loc, IntVT, Mask_One, N0);
266   auto N1 = DAG->getConstant(0x65, Loc, IntVT);
267 
268   KnownBits Known;
269 
270   auto UnknownBorrow = DAG->getRegister(1, IntVT);
271   auto OpUnknownBorrow =
272       DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow);
273   // N0 = 0010?000
274   // N1 = 01100101
275   // B  =        ?
276   //  =>
277   // Known.Zero = 01110000 (0x70)
278   // Known.One  = 10000100 (0x84)
279   Known = DAG->computeKnownBits(OpUnknownBorrow);
280   EXPECT_EQ(Known.Zero, APInt(8, 0x70));
281   EXPECT_EQ(Known.One, APInt(8, 0x84));
282 
283   auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT);
284   auto OpZeroBorrow =
285       DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow);
286   // N0 = 0010?000
287   // N1 = 01100101
288   // B  =        0
289   //  =>
290   // Known.Zero = 01110010 (0x72)
291   // Known.One  = 10000101 (0x85)
292   Known = DAG->computeKnownBits(OpZeroBorrow);
293   EXPECT_EQ(Known.Zero, APInt(8, 0x72));
294   EXPECT_EQ(Known.One, APInt(8, 0x85));
295 
296   auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT);
297   auto OpOneBorrow =
298       DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, OneBorrow);
299   // N0 = 0010?000
300   // N1 = 01100101
301   // B  =        1
302   //  =>
303   // Known.Zero = 01110001 (0x71)
304   // Known.One  = 10000110 (0x86)
305   Known = DAG->computeKnownBits(OpOneBorrow);
306   EXPECT_EQ(Known.Zero, APInt(8, 0x71));
307   EXPECT_EQ(Known.One, APInt(8, 0x86));
308 }
309 
310 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
311 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
312   SDLoc Loc;
313   auto IntVT = EVT::getIntegerVT(Context, 8);
314   auto N0 = DAG->getConstant(0x55, Loc, IntVT);
315   auto UnknownOp = DAG->getRegister(0, IntVT);
316   auto Mask = DAG->getConstant(0x2e, Loc, IntVT);
317   auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
318   auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
319   // N0 = 01010101
320   // N1 = 00?0???0
321   //  =>
322   // Known.One  = 00000001 (0x1)
323   // Known.Zero = 10000000 (0x80)
324   KnownBits Known = DAG->computeKnownBits(Op);
325   EXPECT_EQ(Known.Zero, APInt(8, 0x80));
326   EXPECT_EQ(Known.One, APInt(8, 0x1));
327 }
328 
329 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
330 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_USUBO_CARRY) {
331   SDLoc Loc;
332   auto IntVT = EVT::getIntegerVT(Context, 8);
333   auto N0 = DAG->getConstant(0x5a, Loc, IntVT);
334   auto UnknownOp = DAG->getRegister(0, IntVT);         // ????????
335   auto Mask1_Zero = DAG->getConstant(0x8, Loc, IntVT); // 00001000
336   auto Mask1_One = DAG->getConstant(0x20, Loc, IntVT); // 00100000
337   // N1 = (???????? & 00001000) | 00100000 = 0010?000
338   auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask1_Zero, UnknownOp);
339   N1 = DAG->getNode(ISD::OR, Loc, IntVT, Mask1_One, N1);
340 
341   KnownBits Known;
342 
343   auto UnknownBorrow = DAG->getRegister(1, IntVT);
344   auto OpUnknownBorrow =
345       DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow);
346   // N0 = 01011010
347   // N1 = 0010?000
348   // B  =        ?
349   //  =>
350   // Known.Zero = 11000100 (0xc4)
351   // Known.One  = 00110000 (0x30)
352   Known = DAG->computeKnownBits(OpUnknownBorrow);
353   EXPECT_EQ(Known.Zero, APInt(8, 0xc4));
354   EXPECT_EQ(Known.One, APInt(8, 0x30));
355 
356   auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT);
357   auto OpZeroBorrow =
358       DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow);
359   // N0 = 01011010
360   // N1 = 0010?000
361   // B  =        0
362   //  =>
363   // Known.Zero = 11000101 (0xc5)
364   // Known.One  = 00110010 (0x32)
365   Known = DAG->computeKnownBits(OpZeroBorrow);
366   EXPECT_EQ(Known.Zero, APInt(8, 0xc5));
367   EXPECT_EQ(Known.One, APInt(8, 0x32));
368 
369   auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT);
370   auto OpOneBorrow =
371       DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, OneBorrow);
372   // N0 = 01011010
373   // N1 = 0010?000
374   // B  =        1
375   //  =>
376   // Known.Zero = 11000110 (0xc6)
377   // Known.One  = 00110001 (0x31)
378   Known = DAG->computeKnownBits(OpOneBorrow);
379   EXPECT_EQ(Known.Zero, APInt(8, 0xc6));
380   EXPECT_EQ(Known.One, APInt(8, 0x31));
381 }
382 
383 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) {
384   TargetLowering TL(*TM);
385 
386   SDLoc Loc;
387   auto IntVT = EVT::getIntegerVT(Context, 8);
388   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
389   // Create a BUILD_VECTOR
390   SDValue Op = DAG->getConstant(1, Loc, VecVT);
391   EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
392   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
393 
394   APInt UndefElts;
395   APInt DemandedElts;
396   EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
397 
398   // Width=16, Mask=3
399   DemandedElts = APInt(16, 3);
400   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
401 }
402 
403 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) {
404   TargetLowering TL(*TM);
405 
406   SDLoc Loc;
407   auto IntVT = EVT::getIntegerVT(Context, 8);
408   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
409 
410   // Should create BUILD_VECTORs
411   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
412   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
413   EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
414   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
415 
416   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
417 
418   APInt UndefElts;
419   APInt DemandedElts;
420   EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
421 
422   // Width=16, Mask=3
423   DemandedElts = APInt(16, 3);
424   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
425 }
426 
427 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) {
428   TargetLowering TL(*TM);
429 
430   SDLoc Loc;
431   auto IntVT = EVT::getIntegerVT(Context, 8);
432   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
433   // Create a SPLAT_VECTOR
434   SDValue Op = DAG->getConstant(1, Loc, VecVT);
435   EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
436   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
437 
438   APInt UndefElts;
439   APInt DemandedElts(1,1);
440   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
441 }
442 
443 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) {
444   TargetLowering TL(*TM);
445 
446   SDLoc Loc;
447   auto IntVT = EVT::getIntegerVT(Context, 8);
448   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
449 
450   // Should create SPLAT_VECTORS
451   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
452   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
453   EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
454   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
455 
456   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
457 
458   APInt UndefElts;
459   APInt DemandedElts(1, 1);
460   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
461 }
462 
463 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) {
464   TargetLowering TL(*TM);
465 
466   SDLoc Loc;
467   auto IntVT = EVT::getIntegerVT(Context, 8);
468   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
469   // Create a BUILD_VECTOR
470   SDValue Op = DAG->getConstant(1, Loc, VecVT);
471   EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
472 
473   int SplatIdx = -1;
474   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
475   EXPECT_EQ(SplatIdx, 0);
476 }
477 
478 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) {
479   TargetLowering TL(*TM);
480 
481   SDLoc Loc;
482   auto IntVT = EVT::getIntegerVT(Context, 8);
483   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
484 
485   // Should create BUILD_VECTORs
486   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
487   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
488   EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
489   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
490 
491   int SplatIdx = -1;
492   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
493   EXPECT_EQ(SplatIdx, 0);
494 }
495 
496 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) {
497   TargetLowering TL(*TM);
498 
499   SDLoc Loc;
500   auto IntVT = EVT::getIntegerVT(Context, 8);
501   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
502   // Create a SPLAT_VECTOR
503   SDValue Op = DAG->getConstant(1, Loc, VecVT);
504   EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
505 
506   int SplatIdx = -1;
507   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
508   EXPECT_EQ(SplatIdx, 0);
509 }
510 
511 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) {
512   TargetLowering TL(*TM);
513 
514   SDLoc Loc;
515   auto IntVT = EVT::getIntegerVT(Context, 8);
516   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
517 
518   // Should create SPLAT_VECTORS
519   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
520   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
521   EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
522   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
523 
524   int SplatIdx = -1;
525   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
526   EXPECT_EQ(SplatIdx, 0);
527 }
528 
529 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) {
530   TargetLowering TL(*TM);
531 
532   SDLoc Loc;
533   unsigned NumElts = 16;
534   MVT IntVT = MVT::i8;
535   MVT VecVT = MVT::getVectorVT(IntVT, NumElts);
536 
537   // Base scalar constants.
538   SDValue Val0 = DAG->getConstant(0, Loc, IntVT);
539   SDValue Val1 = DAG->getConstant(1, Loc, IntVT);
540   SDValue Val2 = DAG->getConstant(2, Loc, IntVT);
541   SDValue Val3 = DAG->getConstant(3, Loc, IntVT);
542   SDValue UndefVal = DAG->getUNDEF(IntVT);
543 
544   // Build some repeating sequences.
545   SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123;
546   for(int I = 0; I != 4; ++I) {
547     Pattern1111.append(4, Val1);
548     Pattern1133.append(2, Val1);
549     Pattern1133.append(2, Val3);
550     Pattern0123.push_back(Val0);
551     Pattern0123.push_back(Val1);
552     Pattern0123.push_back(Val2);
553     Pattern0123.push_back(Val3);
554   }
555 
556   // Build a non-pow2 repeating sequence.
557   SmallVector<SDValue, 16> Pattern022;
558   Pattern022.push_back(Val0);
559   Pattern022.append(2, Val2);
560   Pattern022.push_back(Val0);
561   Pattern022.append(2, Val2);
562   Pattern022.push_back(Val0);
563   Pattern022.append(2, Val2);
564   Pattern022.push_back(Val0);
565   Pattern022.append(2, Val2);
566   Pattern022.push_back(Val0);
567   Pattern022.append(2, Val2);
568   Pattern022.push_back(Val0);
569 
570   // Build a non-repeating sequence.
571   SmallVector<SDValue, 16> Pattern1_3;
572   Pattern1_3.append(8, Val1);
573   Pattern1_3.append(8, Val3);
574 
575   // Add some undefs to make it trickier.
576   Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal;
577   Pattern1133[0] = Pattern1133[2] = UndefVal;
578 
579   auto *BV1111 =
580       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111));
581   auto *BV1133 =
582       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133));
583   auto *BV0123=
584       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123));
585   auto *BV022 =
586       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022));
587   auto *BV1_3 =
588       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3));
589 
590   // Check for sequences.
591   SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3;
592   BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3;
593 
594   EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111));
595   EXPECT_EQ(Undefs1111.count(), 3u);
596   EXPECT_EQ(Seq1111.size(), 1u);
597   EXPECT_EQ(Seq1111[0], Val1);
598 
599   EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133));
600   EXPECT_EQ(Undefs1133.count(), 2u);
601   EXPECT_EQ(Seq1133.size(), 4u);
602   EXPECT_EQ(Seq1133[0], Val1);
603   EXPECT_EQ(Seq1133[1], Val1);
604   EXPECT_EQ(Seq1133[2], Val3);
605   EXPECT_EQ(Seq1133[3], Val3);
606 
607   EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123));
608   EXPECT_EQ(Undefs0123.count(), 0u);
609   EXPECT_EQ(Seq0123.size(), 4u);
610   EXPECT_EQ(Seq0123[0], Val0);
611   EXPECT_EQ(Seq0123[1], Val1);
612   EXPECT_EQ(Seq0123[2], Val2);
613   EXPECT_EQ(Seq0123[3], Val3);
614 
615   EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022));
616   EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3));
617 
618   // Try again with DemandedElts masks.
619   APInt Mask1111_0 = APInt::getOneBitSet(NumElts, 0);
620   EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111));
621   EXPECT_EQ(Undefs1111.count(), 0u);
622   EXPECT_EQ(Seq1111.size(), 1u);
623   EXPECT_EQ(Seq1111[0], Val1);
624 
625   APInt Mask1111_1 = APInt::getOneBitSet(NumElts, 2);
626   EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111));
627   EXPECT_EQ(Undefs1111.count(), 1u);
628   EXPECT_EQ(Seq1111.size(), 1u);
629   EXPECT_EQ(Seq1111[0], UndefVal);
630 
631   APInt Mask0123 = APInt(NumElts, 0x7777);
632   EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123));
633   EXPECT_EQ(Undefs0123.count(), 0u);
634   EXPECT_EQ(Seq0123.size(), 4u);
635   EXPECT_EQ(Seq0123[0], Val0);
636   EXPECT_EQ(Seq0123[1], Val1);
637   EXPECT_EQ(Seq0123[2], Val2);
638   EXPECT_EQ(Seq0123[3], SDValue());
639 
640   APInt Mask1_3 = APInt::getHighBitsSet(16, 8);
641   EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3));
642   EXPECT_EQ(Undefs1_3.count(), 0u);
643   EXPECT_EQ(Seq1_3.size(), 1u);
644   EXPECT_EQ(Seq1_3[0], Val3);
645 }
646 
647 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) {
648   MVT VT = MVT::nxv4i64;
649   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
650   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
651 }
652 
653 TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) {
654   MVT VT = MVT::nxv2i32;
655   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger);
656   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
657 }
658 
659 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) {
660   MVT VT = MVT::nxv1f32;
661   EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector);
662   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
663 }
664 
665 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) {
666   EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true);
667   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
668   EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context));
669 }
670 
671 TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) {
672   EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true);
673   EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true);
674 
675   EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector);
676   EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT);
677 }
678 
679 TEST_F(AArch64SelectionDAGTest,
680        getTypeConversion_ScalarizeScalableEVT_nxv1f128) {
681   EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(1));
682   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector);
683   EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128);
684 }
685 
686 TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) {
687   SDLoc Loc;
688   auto IntVT = EVT::getIntegerVT(Context, 8);
689   auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true);
690 
691   // Should create SPLAT_VECTOR
692   SDValue Zero = DAG->getConstant(0, Loc, IntVT);
693   SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero);
694   EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR);
695 }
696 
697 TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) {
698   SDLoc Loc;
699   EVT IntVT = EVT::getIntegerVT(Context, 8);
700 
701   SDValue N0 = DAG->getConstant(0x42, Loc, IntVT);
702   SDValue N1 = DAG->getRegister(0, IntVT);
703   // Construct node to fill arbitrary ExtraInfo.
704   SDValue N2 = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
705   EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode()));
706   EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode()));
707   EXPECT_FALSE(DAG->getPCSections(N2.getNode()));
708   MDNode *MD = MDNode::get(Context, std::nullopt);
709   DAG->addHeapAllocSite(N2.getNode(), MD);
710   DAG->addNoMergeSiteInfo(N2.getNode(), true);
711   DAG->addPCSections(N2.getNode(), MD);
712   EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD);
713   EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode()));
714   EXPECT_EQ(DAG->getPCSections(N2.getNode()), MD);
715 
716   SDValue Root = DAG->getNode(ISD::ADD, Loc, IntVT, N2, N2);
717   EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB);
718   // Create new node and check that ExtraInfo is propagated on RAUW.
719   SDValue New = DAG->getNode(ISD::ADD, Loc, IntVT, N1, N1);
720   EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode()));
721   EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode()));
722   EXPECT_FALSE(DAG->getPCSections(New.getNode()));
723 
724   DAG->ReplaceAllUsesWith(N2, New);
725   EXPECT_EQ(Root->getOperand(0), New);
726   EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD);
727   EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode()));
728   EXPECT_EQ(DAG->getPCSections(New.getNode()), MD);
729 }
730 
731 } // end namespace llvm
732