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