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