xref: /llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp (revision 98c0e55d9d31ea0a7b8a1e5395257f10a6a27cc6)
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/MemoryLocation.h"
10 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
11 #include "llvm/AsmParser/Parser.h"
12 #include "llvm/CodeGen/MachineModuleInfo.h"
13 #include "llvm/CodeGen/SelectionDAG.h"
14 #include "llvm/CodeGen/TargetLowering.h"
15 #include "llvm/IR/MDBuilder.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/MC/TargetRegistry.h"
18 #include "llvm/Support/KnownBits.h"
19 #include "llvm/Support/SourceMgr.h"
20 #include "llvm/Support/TargetSelect.h"
21 #include "llvm/Target/TargetMachine.h"
22 #include "gtest/gtest.h"
23 
24 namespace llvm {
25 
26 class AArch64SelectionDAGTest : public testing::Test {
27 protected:
28   static void SetUpTestCase() {
29     InitializeAllTargets();
30     InitializeAllTargetMCs();
31   }
32 
33   void SetUp() override {
34     StringRef Assembly = "define void @f() { ret void }";
35 
36     Triple TargetTriple("aarch64--");
37     std::string Error;
38     const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
39     // FIXME: These tests do not depend on AArch64 specifically, but we have to
40     // initialize a target. A skeleton Target for unittests would allow us to
41     // always run these tests.
42     if (!T)
43       GTEST_SKIP();
44 
45     TargetOptions Options;
46     TM = std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>(
47         T->createTargetMachine("AArch64", "", "+sve", Options, std::nullopt,
48                                std::nullopt, CodeGenOptLevel::Aggressive)));
49     if (!TM)
50       GTEST_SKIP();
51 
52     SMDiagnostic SMError;
53     M = parseAssemblyString(Assembly, SMError, Context);
54     if (!M)
55       report_fatal_error(SMError.getMessage());
56     M->setDataLayout(TM->createDataLayout());
57 
58     F = M->getFunction("f");
59     if (!F)
60       report_fatal_error("F?");
61 
62     MachineModuleInfo MMI(TM.get());
63 
64     MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F), 0,
65                                       MMI);
66 
67     DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None);
68     if (!DAG)
69       report_fatal_error("DAG?");
70     OptimizationRemarkEmitter ORE(F);
71     DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
72   }
73 
74   TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) {
75     return DAG->getTargetLoweringInfo().getTypeAction(Context, VT);
76   }
77 
78   EVT getTypeToTransformTo(EVT VT) {
79     return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT);
80   }
81 
82   LLVMContext Context;
83   std::unique_ptr<LLVMTargetMachine> TM;
84   std::unique_ptr<Module> M;
85   Function *F;
86   std::unique_ptr<MachineFunction> MF;
87   std::unique_ptr<SelectionDAG> DAG;
88 };
89 
90 TEST_F(AArch64SelectionDAGTest, computeKnownBits_ZERO_EXTEND_VECTOR_INREG) {
91   SDLoc Loc;
92   auto Int8VT = EVT::getIntegerVT(Context, 8);
93   auto Int16VT = EVT::getIntegerVT(Context, 16);
94   auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);
95   auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);
96   auto InVec = DAG->getConstant(0, Loc, InVecVT);
97   auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
98   auto DemandedElts = APInt(2, 3);
99   KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
100   EXPECT_TRUE(Known.isZero());
101 }
102 
103 TEST_F(AArch64SelectionDAGTest, computeKnownBitsSVE_ZERO_EXTEND_VECTOR_INREG) {
104   SDLoc Loc;
105   auto Int8VT = EVT::getIntegerVT(Context, 8);
106   auto Int16VT = EVT::getIntegerVT(Context, 16);
107   auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, true);
108   auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, true);
109   auto InVec = DAG->getConstant(0, Loc, InVecVT);
110   auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
111   auto DemandedElts = APInt(2, 3);
112   KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
113 
114   // We don't know anything for SVE at the moment.
115   EXPECT_EQ(Known.Zero, APInt(16, 0u));
116   EXPECT_EQ(Known.One, APInt(16, 0u));
117   EXPECT_FALSE(Known.isZero());
118 }
119 
120 TEST_F(AArch64SelectionDAGTest, computeKnownBits_EXTRACT_SUBVECTOR) {
121   SDLoc Loc;
122   auto IntVT = EVT::getIntegerVT(Context, 8);
123   auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
124   auto IdxVT = EVT::getIntegerVT(Context, 64);
125   auto Vec = DAG->getConstant(0, Loc, VecVT);
126   auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
127   auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
128   auto DemandedElts = APInt(3, 7);
129   KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
130   EXPECT_TRUE(Known.isZero());
131 }
132 
133 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG) {
134   SDLoc Loc;
135   auto Int8VT = EVT::getIntegerVT(Context, 8);
136   auto Int16VT = EVT::getIntegerVT(Context, 16);
137   auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);
138   auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);
139   auto InVec = DAG->getConstant(1, Loc, InVecVT);
140   auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
141   auto DemandedElts = APInt(2, 3);
142   EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 15u);
143 }
144 
145 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBitsSVE_SIGN_EXTEND_VECTOR_INREG) {
146   SDLoc Loc;
147   auto Int8VT = EVT::getIntegerVT(Context, 8);
148   auto Int16VT = EVT::getIntegerVT(Context, 16);
149   auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, /*IsScalable=*/true);
150   auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, /*IsScalable=*/true);
151   auto InVec = DAG->getConstant(1, Loc, InVecVT);
152   auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
153   auto DemandedElts = APInt(2, 3);
154   EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 1u);
155 }
156 
157 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_EXTRACT_SUBVECTOR) {
158   SDLoc Loc;
159   auto IntVT = EVT::getIntegerVT(Context, 8);
160   auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
161   auto IdxVT = EVT::getIntegerVT(Context, 64);
162   auto Vec = DAG->getConstant(1, Loc, VecVT);
163   auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
164   auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
165   auto DemandedElts = APInt(3, 7);
166   EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 7u);
167 }
168 
169 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) {
170   TargetLowering TL(*TM);
171 
172   SDLoc Loc;
173   auto IntVT = EVT::getIntegerVT(Context, 8);
174   auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
175   auto IdxVT = EVT::getIntegerVT(Context, 64);
176   auto Vec = DAG->getConstant(1, Loc, VecVT);
177   auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
178   auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
179   auto DemandedElts = APInt(3, 7);
180   auto KnownUndef = APInt(3, 0);
181   auto KnownZero = APInt(3, 0);
182   TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
183   EXPECT_EQ(TL.SimplifyDemandedVectorElts(Op, DemandedElts, KnownUndef,
184                                           KnownZero, TLO),
185             false);
186 }
187 
188 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) {
189   TargetLowering TL(*TM);
190 
191   SDLoc Loc;
192   auto Int8VT = EVT::getIntegerVT(Context, 8);
193   auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16);
194   SDValue UnknownOp = DAG->getRegister(0, InVecVT);
195   SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);
196   SDValue Mask1V = DAG->getSplatBuildVector(InVecVT, Loc, Mask1S);
197   SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);
198 
199   SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT);
200   SDValue Mask2V = DAG->getSplatBuildVector(InVecVT, Loc, Mask2S);
201 
202   SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V);
203   // N0 = ?000?0?0
204   // Mask2V = 01010101
205   //  =>
206   // Known.Zero = 00100000 (0xAA)
207   KnownBits Known;
208   APInt DemandedBits = APInt(8, 0xFF);
209   TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
210   EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
211   EXPECT_EQ(Known.Zero, APInt(8, 0xAA));
212 }
213 
214 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) {
215   TargetLowering TL(*TM);
216 
217   SDLoc Loc;
218   auto Int8VT = EVT::getIntegerVT(Context, 8);
219   auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16, /*IsScalable=*/true);
220   SDValue UnknownOp = DAG->getRegister(0, InVecVT);
221   SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);
222   SDValue Mask1V = DAG->getSplatVector(InVecVT, Loc, Mask1S);
223   SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);
224 
225   SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT);
226   SDValue Mask2V = DAG->getSplatVector(InVecVT, Loc, Mask2S);
227 
228   SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V);
229 
230   // N0 = ?000?0?0
231   // Mask2V = 01010101
232   //  =>
233   // Known.Zero = 00100000 (0xAA)
234   KnownBits Known;
235   APInt DemandedBits = APInt(8, 0xFF);
236   TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
237   EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
238   EXPECT_EQ(Known.Zero, APInt(8, 0xAA));
239 }
240 
241 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
242 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {
243   SDLoc Loc;
244   auto IntVT = EVT::getIntegerVT(Context, 8);
245   auto UnknownOp = DAG->getRegister(0, IntVT);
246   auto Mask = DAG->getConstant(0x8A, Loc, IntVT);
247   auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
248   auto N1 = DAG->getConstant(0x55, Loc, IntVT);
249   auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1);
250   // N0 = ?000?0?0
251   // N1 = 01010101
252   //  =>
253   // Known.One  = 01010101 (0x55)
254   // Known.Zero = 00100000 (0x20)
255   KnownBits Known = DAG->computeKnownBits(Op);
256   EXPECT_EQ(Known.Zero, APInt(8, 0x20));
257   EXPECT_EQ(Known.One, APInt(8, 0x55));
258 }
259 
260 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
261 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_UADDO_CARRY) {
262   SDLoc Loc;
263   auto IntVT = EVT::getIntegerVT(Context, 8);
264   auto UnknownOp = DAG->getRegister(0, IntVT);
265   auto Mask_Zero = DAG->getConstant(0x28, Loc, IntVT);
266   auto Mask_One = DAG->getConstant(0x20, Loc, IntVT);
267   auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask_Zero, UnknownOp);
268   N0 = DAG->getNode(ISD::OR, Loc, IntVT, Mask_One, N0);
269   auto N1 = DAG->getConstant(0x65, Loc, IntVT);
270 
271   KnownBits Known;
272 
273   auto UnknownBorrow = DAG->getRegister(1, IntVT);
274   auto OpUnknownBorrow =
275       DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow);
276   // N0 = 0010?000
277   // N1 = 01100101
278   // B  =        ?
279   //  =>
280   // Known.Zero = 01110000 (0x70)
281   // Known.One  = 10000100 (0x84)
282   Known = DAG->computeKnownBits(OpUnknownBorrow);
283   EXPECT_EQ(Known.Zero, APInt(8, 0x70));
284   EXPECT_EQ(Known.One, APInt(8, 0x84));
285 
286   auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT);
287   auto OpZeroBorrow =
288       DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow);
289   // N0 = 0010?000
290   // N1 = 01100101
291   // B  =        0
292   //  =>
293   // Known.Zero = 01110010 (0x72)
294   // Known.One  = 10000101 (0x85)
295   Known = DAG->computeKnownBits(OpZeroBorrow);
296   EXPECT_EQ(Known.Zero, APInt(8, 0x72));
297   EXPECT_EQ(Known.One, APInt(8, 0x85));
298 
299   auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT);
300   auto OpOneBorrow =
301       DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, OneBorrow);
302   // N0 = 0010?000
303   // N1 = 01100101
304   // B  =        1
305   //  =>
306   // Known.Zero = 01110001 (0x71)
307   // Known.One  = 10000110 (0x86)
308   Known = DAG->computeKnownBits(OpOneBorrow);
309   EXPECT_EQ(Known.Zero, APInt(8, 0x71));
310   EXPECT_EQ(Known.One, APInt(8, 0x86));
311 }
312 
313 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
314 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
315   SDLoc Loc;
316   auto IntVT = EVT::getIntegerVT(Context, 8);
317   auto N0 = DAG->getConstant(0x55, Loc, IntVT);
318   auto UnknownOp = DAG->getRegister(0, IntVT);
319   auto Mask = DAG->getConstant(0x2e, Loc, IntVT);
320   auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
321   auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
322   // N0 = 01010101
323   // N1 = 00?0???0
324   //  =>
325   // Known.One  = 00000001 (0x1)
326   // Known.Zero = 10000000 (0x80)
327   KnownBits Known = DAG->computeKnownBits(Op);
328   EXPECT_EQ(Known.Zero, APInt(8, 0x80));
329   EXPECT_EQ(Known.One, APInt(8, 0x1));
330 }
331 
332 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
333 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_USUBO_CARRY) {
334   SDLoc Loc;
335   auto IntVT = EVT::getIntegerVT(Context, 8);
336   auto N0 = DAG->getConstant(0x5a, Loc, IntVT);
337   auto UnknownOp = DAG->getRegister(0, IntVT);         // ????????
338   auto Mask1_Zero = DAG->getConstant(0x8, Loc, IntVT); // 00001000
339   auto Mask1_One = DAG->getConstant(0x20, Loc, IntVT); // 00100000
340   // N1 = (???????? & 00001000) | 00100000 = 0010?000
341   auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask1_Zero, UnknownOp);
342   N1 = DAG->getNode(ISD::OR, Loc, IntVT, Mask1_One, N1);
343 
344   KnownBits Known;
345 
346   auto UnknownBorrow = DAG->getRegister(1, IntVT);
347   auto OpUnknownBorrow =
348       DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow);
349   // N0 = 01011010
350   // N1 = 0010?000
351   // B  =        ?
352   //  =>
353   // Known.Zero = 11000100 (0xc4)
354   // Known.One  = 00110000 (0x30)
355   Known = DAG->computeKnownBits(OpUnknownBorrow);
356   EXPECT_EQ(Known.Zero, APInt(8, 0xc4));
357   EXPECT_EQ(Known.One, APInt(8, 0x30));
358 
359   auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT);
360   auto OpZeroBorrow =
361       DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow);
362   // N0 = 01011010
363   // N1 = 0010?000
364   // B  =        0
365   //  =>
366   // Known.Zero = 11000101 (0xc5)
367   // Known.One  = 00110010 (0x32)
368   Known = DAG->computeKnownBits(OpZeroBorrow);
369   EXPECT_EQ(Known.Zero, APInt(8, 0xc5));
370   EXPECT_EQ(Known.One, APInt(8, 0x32));
371 
372   auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT);
373   auto OpOneBorrow =
374       DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, OneBorrow);
375   // N0 = 01011010
376   // N1 = 0010?000
377   // B  =        1
378   //  =>
379   // Known.Zero = 11000110 (0xc6)
380   // Known.One  = 00110001 (0x31)
381   Known = DAG->computeKnownBits(OpOneBorrow);
382   EXPECT_EQ(Known.Zero, APInt(8, 0xc6));
383   EXPECT_EQ(Known.One, APInt(8, 0x31));
384 }
385 
386 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) {
387   TargetLowering TL(*TM);
388 
389   SDLoc Loc;
390   auto IntVT = EVT::getIntegerVT(Context, 8);
391   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
392   // Create a BUILD_VECTOR
393   SDValue Op = DAG->getConstant(1, Loc, VecVT);
394   EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
395   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
396 
397   APInt UndefElts;
398   APInt DemandedElts;
399   EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
400 
401   // Width=16, Mask=3
402   DemandedElts = APInt(16, 3);
403   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
404 }
405 
406 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) {
407   TargetLowering TL(*TM);
408 
409   SDLoc Loc;
410   auto IntVT = EVT::getIntegerVT(Context, 8);
411   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
412 
413   // Should create BUILD_VECTORs
414   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
415   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
416   EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
417   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
418 
419   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
420 
421   APInt UndefElts;
422   APInt DemandedElts;
423   EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
424 
425   // Width=16, Mask=3
426   DemandedElts = APInt(16, 3);
427   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
428 }
429 
430 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) {
431   TargetLowering TL(*TM);
432 
433   SDLoc Loc;
434   auto IntVT = EVT::getIntegerVT(Context, 8);
435   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
436   // Create a SPLAT_VECTOR
437   SDValue Op = DAG->getConstant(1, Loc, VecVT);
438   EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
439   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
440 
441   APInt UndefElts;
442   APInt DemandedElts(1,1);
443   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
444 }
445 
446 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) {
447   TargetLowering TL(*TM);
448 
449   SDLoc Loc;
450   auto IntVT = EVT::getIntegerVT(Context, 8);
451   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
452 
453   // Should create SPLAT_VECTORS
454   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
455   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
456   EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
457   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
458 
459   EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
460 
461   APInt UndefElts;
462   APInt DemandedElts(1, 1);
463   EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
464 }
465 
466 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) {
467   TargetLowering TL(*TM);
468 
469   SDLoc Loc;
470   auto IntVT = EVT::getIntegerVT(Context, 8);
471   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
472   // Create a BUILD_VECTOR
473   SDValue Op = DAG->getConstant(1, Loc, VecVT);
474   EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
475 
476   int SplatIdx = -1;
477   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
478   EXPECT_EQ(SplatIdx, 0);
479 }
480 
481 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) {
482   TargetLowering TL(*TM);
483 
484   SDLoc Loc;
485   auto IntVT = EVT::getIntegerVT(Context, 8);
486   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
487 
488   // Should create BUILD_VECTORs
489   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
490   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
491   EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
492   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
493 
494   int SplatIdx = -1;
495   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
496   EXPECT_EQ(SplatIdx, 0);
497 }
498 
499 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) {
500   TargetLowering TL(*TM);
501 
502   SDLoc Loc;
503   auto IntVT = EVT::getIntegerVT(Context, 8);
504   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
505   // Create a SPLAT_VECTOR
506   SDValue Op = DAG->getConstant(1, Loc, VecVT);
507   EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
508 
509   int SplatIdx = -1;
510   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
511   EXPECT_EQ(SplatIdx, 0);
512 }
513 
514 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) {
515   TargetLowering TL(*TM);
516 
517   SDLoc Loc;
518   auto IntVT = EVT::getIntegerVT(Context, 8);
519   auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
520 
521   // Should create SPLAT_VECTORS
522   SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
523   SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
524   EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
525   SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
526 
527   int SplatIdx = -1;
528   EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
529   EXPECT_EQ(SplatIdx, 0);
530 }
531 
532 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) {
533   TargetLowering TL(*TM);
534 
535   SDLoc Loc;
536   unsigned NumElts = 16;
537   MVT IntVT = MVT::i8;
538   MVT VecVT = MVT::getVectorVT(IntVT, NumElts);
539 
540   // Base scalar constants.
541   SDValue Val0 = DAG->getConstant(0, Loc, IntVT);
542   SDValue Val1 = DAG->getConstant(1, Loc, IntVT);
543   SDValue Val2 = DAG->getConstant(2, Loc, IntVT);
544   SDValue Val3 = DAG->getConstant(3, Loc, IntVT);
545   SDValue UndefVal = DAG->getUNDEF(IntVT);
546 
547   // Build some repeating sequences.
548   SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123;
549   for(int I = 0; I != 4; ++I) {
550     Pattern1111.append(4, Val1);
551     Pattern1133.append(2, Val1);
552     Pattern1133.append(2, Val3);
553     Pattern0123.push_back(Val0);
554     Pattern0123.push_back(Val1);
555     Pattern0123.push_back(Val2);
556     Pattern0123.push_back(Val3);
557   }
558 
559   // Build a non-pow2 repeating sequence.
560   SmallVector<SDValue, 16> Pattern022;
561   Pattern022.push_back(Val0);
562   Pattern022.append(2, Val2);
563   Pattern022.push_back(Val0);
564   Pattern022.append(2, Val2);
565   Pattern022.push_back(Val0);
566   Pattern022.append(2, Val2);
567   Pattern022.push_back(Val0);
568   Pattern022.append(2, Val2);
569   Pattern022.push_back(Val0);
570   Pattern022.append(2, Val2);
571   Pattern022.push_back(Val0);
572 
573   // Build a non-repeating sequence.
574   SmallVector<SDValue, 16> Pattern1_3;
575   Pattern1_3.append(8, Val1);
576   Pattern1_3.append(8, Val3);
577 
578   // Add some undefs to make it trickier.
579   Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal;
580   Pattern1133[0] = Pattern1133[2] = UndefVal;
581 
582   auto *BV1111 =
583       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111));
584   auto *BV1133 =
585       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133));
586   auto *BV0123=
587       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123));
588   auto *BV022 =
589       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022));
590   auto *BV1_3 =
591       cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3));
592 
593   // Check for sequences.
594   SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3;
595   BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3;
596 
597   EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111));
598   EXPECT_EQ(Undefs1111.count(), 3u);
599   EXPECT_EQ(Seq1111.size(), 1u);
600   EXPECT_EQ(Seq1111[0], Val1);
601 
602   EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133));
603   EXPECT_EQ(Undefs1133.count(), 2u);
604   EXPECT_EQ(Seq1133.size(), 4u);
605   EXPECT_EQ(Seq1133[0], Val1);
606   EXPECT_EQ(Seq1133[1], Val1);
607   EXPECT_EQ(Seq1133[2], Val3);
608   EXPECT_EQ(Seq1133[3], Val3);
609 
610   EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123));
611   EXPECT_EQ(Undefs0123.count(), 0u);
612   EXPECT_EQ(Seq0123.size(), 4u);
613   EXPECT_EQ(Seq0123[0], Val0);
614   EXPECT_EQ(Seq0123[1], Val1);
615   EXPECT_EQ(Seq0123[2], Val2);
616   EXPECT_EQ(Seq0123[3], Val3);
617 
618   EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022));
619   EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3));
620 
621   // Try again with DemandedElts masks.
622   APInt Mask1111_0 = APInt::getOneBitSet(NumElts, 0);
623   EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111));
624   EXPECT_EQ(Undefs1111.count(), 0u);
625   EXPECT_EQ(Seq1111.size(), 1u);
626   EXPECT_EQ(Seq1111[0], Val1);
627 
628   APInt Mask1111_1 = APInt::getOneBitSet(NumElts, 2);
629   EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111));
630   EXPECT_EQ(Undefs1111.count(), 1u);
631   EXPECT_EQ(Seq1111.size(), 1u);
632   EXPECT_EQ(Seq1111[0], UndefVal);
633 
634   APInt Mask0123 = APInt(NumElts, 0x7777);
635   EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123));
636   EXPECT_EQ(Undefs0123.count(), 0u);
637   EXPECT_EQ(Seq0123.size(), 4u);
638   EXPECT_EQ(Seq0123[0], Val0);
639   EXPECT_EQ(Seq0123[1], Val1);
640   EXPECT_EQ(Seq0123[2], Val2);
641   EXPECT_EQ(Seq0123[3], SDValue());
642 
643   APInt Mask1_3 = APInt::getHighBitsSet(16, 8);
644   EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3));
645   EXPECT_EQ(Undefs1_3.count(), 0u);
646   EXPECT_EQ(Seq1_3.size(), 1u);
647   EXPECT_EQ(Seq1_3[0], Val3);
648 }
649 
650 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) {
651   MVT VT = MVT::nxv4i64;
652   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
653   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
654 }
655 
656 TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) {
657   MVT VT = MVT::nxv2i32;
658   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger);
659   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
660 }
661 
662 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) {
663   MVT VT = MVT::nxv1f32;
664   EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector);
665   ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
666 }
667 
668 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) {
669   EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true);
670   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
671   EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context));
672 }
673 
674 TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) {
675   EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true);
676   EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true);
677 
678   EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector);
679   EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT);
680 }
681 
682 TEST_F(AArch64SelectionDAGTest,
683        getTypeConversion_ScalarizeScalableEVT_nxv1f128) {
684   EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(1));
685   EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector);
686   EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128);
687 }
688 
689 TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) {
690   SDLoc Loc;
691   auto IntVT = EVT::getIntegerVT(Context, 8);
692   auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true);
693 
694   // Should create SPLAT_VECTOR
695   SDValue Zero = DAG->getConstant(0, Loc, IntVT);
696   SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero);
697   EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR);
698 }
699 
700 TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) {
701   SDLoc Loc;
702   EVT IntVT = EVT::getIntegerVT(Context, 8);
703 
704   SDValue N0 = DAG->getConstant(0x42, Loc, IntVT);
705   SDValue N1 = DAG->getRegister(0, IntVT);
706   // Construct node to fill arbitrary ExtraInfo.
707   SDValue N2 = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
708   EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode()));
709   EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode()));
710   EXPECT_FALSE(DAG->getPCSections(N2.getNode()));
711   MDNode *MD = MDNode::get(Context, std::nullopt);
712   DAG->addHeapAllocSite(N2.getNode(), MD);
713   DAG->addNoMergeSiteInfo(N2.getNode(), true);
714   DAG->addPCSections(N2.getNode(), MD);
715   EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD);
716   EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode()));
717   EXPECT_EQ(DAG->getPCSections(N2.getNode()), MD);
718 
719   SDValue Root = DAG->getNode(ISD::ADD, Loc, IntVT, N2, N2);
720   EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB);
721   // Create new node and check that ExtraInfo is propagated on RAUW.
722   SDValue New = DAG->getNode(ISD::ADD, Loc, IntVT, N1, N1);
723   EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode()));
724   EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode()));
725   EXPECT_FALSE(DAG->getPCSections(New.getNode()));
726 
727   DAG->ReplaceAllUsesWith(N2, New);
728   EXPECT_EQ(Root->getOperand(0), New);
729   EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD);
730   EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode()));
731   EXPECT_EQ(DAG->getPCSections(New.getNode()), MD);
732 }
733 
734 TEST_F(AArch64SelectionDAGTest, computeKnownBits_extload_known01) {
735   SDLoc Loc;
736   auto Int8VT = EVT::getIntegerVT(Context, 8);
737   auto Int32VT = EVT::getIntegerVT(Context, 32);
738   auto Int64VT = EVT::getIntegerVT(Context, 64);
739   auto Ptr = DAG->getConstant(0, Loc, Int64VT);
740   auto PtrInfo =
741       MachinePointerInfo::getFixedStack(DAG->getMachineFunction(), 0);
742   AAMDNodes AA;
743   MDBuilder MDHelper(*DAG->getContext());
744   MDNode *Range = MDHelper.createRange(APInt(8, 0), APInt(8, 2));
745   MachineMemOperand *MMO = DAG->getMachineFunction().getMachineMemOperand(
746       PtrInfo, MachineMemOperand::MOLoad, 8, Align(8), AA, Range);
747 
748   auto ALoad = DAG->getExtLoad(ISD::EXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
749                                Ptr, Int8VT, MMO);
750   KnownBits Known = DAG->computeKnownBits(ALoad);
751   EXPECT_EQ(Known.Zero, APInt(32, 0xfe));
752   EXPECT_EQ(Known.One, APInt(32, 0));
753 
754   auto ZLoad = DAG->getExtLoad(ISD::ZEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
755                                Ptr, Int8VT, MMO);
756   Known = DAG->computeKnownBits(ZLoad);
757   EXPECT_EQ(Known.Zero, APInt(32, 0xfffffffe));
758   EXPECT_EQ(Known.One, APInt(32, 0));
759 
760   auto SLoad = DAG->getExtLoad(ISD::SEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
761                                Ptr, Int8VT, MMO);
762   Known = DAG->computeKnownBits(SLoad);
763   EXPECT_EQ(Known.Zero, APInt(32, 0xfffffffe));
764   EXPECT_EQ(Known.One, APInt(32, 0));
765 }
766 
767 TEST_F(AArch64SelectionDAGTest, computeKnownBits_extload_knownnegative) {
768   SDLoc Loc;
769   auto Int8VT = EVT::getIntegerVT(Context, 8);
770   auto Int32VT = EVT::getIntegerVT(Context, 32);
771   auto Int64VT = EVT::getIntegerVT(Context, 64);
772   auto Ptr = DAG->getConstant(0, Loc, Int64VT);
773   auto PtrInfo =
774       MachinePointerInfo::getFixedStack(DAG->getMachineFunction(), 0);
775   AAMDNodes AA;
776   MDBuilder MDHelper(*DAG->getContext());
777   MDNode *Range = MDHelper.createRange(APInt(8, 0xf0), APInt(8, 0xff));
778   MachineMemOperand *MMO = DAG->getMachineFunction().getMachineMemOperand(
779       PtrInfo, MachineMemOperand::MOLoad, 8, Align(8), AA, Range);
780 
781   auto ALoad = DAG->getExtLoad(ISD::EXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
782                                Ptr, Int8VT, MMO);
783   KnownBits Known = DAG->computeKnownBits(ALoad);
784   EXPECT_EQ(Known.Zero, APInt(32, 0));
785   EXPECT_EQ(Known.One, APInt(32, 0xf0));
786 
787   auto ZLoad = DAG->getExtLoad(ISD::ZEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
788                                Ptr, Int8VT, MMO);
789   Known = DAG->computeKnownBits(ZLoad);
790   EXPECT_EQ(Known.Zero, APInt(32, 0xffffff00));
791   EXPECT_EQ(Known.One, APInt(32, 0x000000f0));
792 
793   auto SLoad = DAG->getExtLoad(ISD::SEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
794                                Ptr, Int8VT, MMO);
795   Known = DAG->computeKnownBits(SLoad);
796   EXPECT_EQ(Known.Zero, APInt(32, 0));
797   EXPECT_EQ(Known.One, APInt(32, 0xfffffff0));
798 }
799 
800 TEST_F(AArch64SelectionDAGTest,
801        computeKnownBits_AVGFLOORU_AVGFLOORS_AVGCEILU_AVGCEILS) {
802   SDLoc Loc;
803   auto Int8VT = EVT::getIntegerVT(Context, 8);
804   auto Int16VT = EVT::getIntegerVT(Context, 16);
805   auto Int8Vec8VT = EVT::getVectorVT(Context, Int8VT, 8);
806   auto Int16Vec8VT = EVT::getVectorVT(Context, Int16VT, 8);
807 
808   SDValue UnknownOp0 = DAG->getRegister(0, Int8Vec8VT);
809   SDValue UnknownOp1 = DAG->getRegister(1, Int8Vec8VT);
810 
811   SDValue ZextOp0 =
812       DAG->getNode(ISD::ZERO_EXTEND, Loc, Int16Vec8VT, UnknownOp0);
813   SDValue ZextOp1 =
814       DAG->getNode(ISD::ZERO_EXTEND, Loc, Int16Vec8VT, UnknownOp1);
815   // ZextOp0 = 00000000????????
816   // ZextOp1 = 00000000????????
817   // => (for all AVG* instructions)
818   // Known.Zero = 1111111100000000 (0xFF00)
819   // Known.One  = 0000000000000000 (0x0000)
820   auto Zeroes = APInt(16, 0xFF00);
821   auto Ones = APInt(16, 0x0000);
822 
823   SDValue AVGFLOORU =
824       DAG->getNode(ISD::AVGFLOORU, Loc, Int16Vec8VT, ZextOp0, ZextOp1);
825   KnownBits KnownAVGFLOORU = DAG->computeKnownBits(AVGFLOORU);
826   EXPECT_EQ(KnownAVGFLOORU.Zero, Zeroes);
827   EXPECT_EQ(KnownAVGFLOORU.One, Ones);
828 
829   SDValue AVGFLOORS =
830       DAG->getNode(ISD::AVGFLOORS, Loc, Int16Vec8VT, ZextOp0, ZextOp1);
831   KnownBits KnownAVGFLOORS = DAG->computeKnownBits(AVGFLOORS);
832   EXPECT_EQ(KnownAVGFLOORS.Zero, Zeroes);
833   EXPECT_EQ(KnownAVGFLOORS.One, Ones);
834 
835   SDValue AVGCEILU =
836       DAG->getNode(ISD::AVGCEILU, Loc, Int16Vec8VT, ZextOp0, ZextOp1);
837   KnownBits KnownAVGCEILU = DAG->computeKnownBits(AVGCEILU);
838   EXPECT_EQ(KnownAVGCEILU.Zero, Zeroes);
839   EXPECT_EQ(KnownAVGCEILU.One, Ones);
840 
841   SDValue AVGCEILS =
842       DAG->getNode(ISD::AVGCEILS, Loc, Int16Vec8VT, ZextOp0, ZextOp1);
843   KnownBits KnownAVGCEILS = DAG->computeKnownBits(AVGCEILS);
844   EXPECT_EQ(KnownAVGCEILS.Zero, Zeroes);
845   EXPECT_EQ(KnownAVGCEILS.One, Ones);
846 }
847 
848 } // end namespace llvm
849