1 //===- llvm/unittest/CodeGen/AArch64SelectionDAGTest.cpp -------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/CodeGen/MachineModuleInfo.h"
12 #include "llvm/CodeGen/SelectionDAG.h"
13 #include "llvm/CodeGen/TargetLowering.h"
14 #include "llvm/Support/KnownBits.h"
15 #include "llvm/Support/SourceMgr.h"
16 #include "llvm/Support/TargetRegistry.h"
17 #include "llvm/Support/TargetSelect.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "gtest/gtest.h"
23 class AArch64SelectionDAGTest
: public testing::Test
{
25 static void SetUpTestCase() {
26 InitializeAllTargets();
27 InitializeAllTargetMCs();
30 void SetUp() override
{
31 StringRef Assembly
= "define void @f() { ret void }";
33 Triple
TargetTriple("aarch64--");
35 const Target
*T
= TargetRegistry::lookupTarget("", TargetTriple
, Error
);
36 // FIXME: These tests do not depend on AArch64 specifically, but we have to
37 // initialize a target. A skeleton Target for unittests would allow us to
38 // always run these tests.
42 TargetOptions Options
;
43 TM
= std::unique_ptr
<LLVMTargetMachine
>(static_cast<LLVMTargetMachine
*>(
44 T
->createTargetMachine("AArch64", "", "+sve", Options
, None
, None
,
45 CodeGenOpt::Aggressive
)));
50 M
= parseAssemblyString(Assembly
, SMError
, Context
);
52 report_fatal_error(SMError
.getMessage());
53 M
->setDataLayout(TM
->createDataLayout());
55 F
= M
->getFunction("f");
57 report_fatal_error("F?");
59 MachineModuleInfo
MMI(TM
.get());
61 MF
= std::make_unique
<MachineFunction
>(*F
, *TM
, *TM
->getSubtargetImpl(*F
), 0,
64 DAG
= std::make_unique
<SelectionDAG
>(*TM
, CodeGenOpt::None
);
66 report_fatal_error("DAG?");
67 OptimizationRemarkEmitter
ORE(F
);
68 DAG
->init(*MF
, ORE
, nullptr, nullptr, nullptr, nullptr, nullptr);
71 TargetLoweringBase::LegalizeTypeAction
getTypeAction(EVT VT
) {
72 return DAG
->getTargetLoweringInfo().getTypeAction(Context
, VT
);
75 EVT
getTypeToTransformTo(EVT VT
) {
76 return DAG
->getTargetLoweringInfo().getTypeToTransformTo(Context
, VT
);
80 std::unique_ptr
<LLVMTargetMachine
> TM
;
81 std::unique_ptr
<Module
> M
;
83 std::unique_ptr
<MachineFunction
> MF
;
84 std::unique_ptr
<SelectionDAG
> DAG
;
87 TEST_F(AArch64SelectionDAGTest
, computeKnownBits_ZERO_EXTEND_VECTOR_INREG
) {
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());
102 TEST_F(AArch64SelectionDAGTest
, computeKnownBitsSVE_ZERO_EXTEND_VECTOR_INREG
) {
106 auto Int8VT
= EVT::getIntegerVT(Context
, 8);
107 auto Int16VT
= EVT::getIntegerVT(Context
, 16);
108 auto InVecVT
= EVT::getVectorVT(Context
, Int8VT
, 4, true);
109 auto OutVecVT
= EVT::getVectorVT(Context
, Int16VT
, 2, true);
110 auto InVec
= DAG
->getConstant(0, Loc
, InVecVT
);
111 auto Op
= DAG
->getNode(ISD::ZERO_EXTEND_VECTOR_INREG
, Loc
, OutVecVT
, InVec
);
112 auto DemandedElts
= APInt(2, 3);
113 KnownBits Known
= DAG
->computeKnownBits(Op
, DemandedElts
);
115 // We don't know anything for SVE at the moment.
116 EXPECT_EQ(Known
.Zero
, APInt(16, 0u));
117 EXPECT_EQ(Known
.One
, APInt(16, 0u));
118 EXPECT_FALSE(Known
.isZero());
121 TEST_F(AArch64SelectionDAGTest
, computeKnownBits_EXTRACT_SUBVECTOR
) {
125 auto IntVT
= EVT::getIntegerVT(Context
, 8);
126 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 3);
127 auto IdxVT
= EVT::getIntegerVT(Context
, 64);
128 auto Vec
= DAG
->getConstant(0, Loc
, VecVT
);
129 auto ZeroIdx
= DAG
->getConstant(0, Loc
, IdxVT
);
130 auto Op
= DAG
->getNode(ISD::EXTRACT_SUBVECTOR
, Loc
, VecVT
, Vec
, ZeroIdx
);
131 auto DemandedElts
= APInt(3, 7);
132 KnownBits Known
= DAG
->computeKnownBits(Op
, DemandedElts
);
133 EXPECT_TRUE(Known
.isZero());
136 TEST_F(AArch64SelectionDAGTest
, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG
) {
140 auto Int8VT
= EVT::getIntegerVT(Context
, 8);
141 auto Int16VT
= EVT::getIntegerVT(Context
, 16);
142 auto InVecVT
= EVT::getVectorVT(Context
, Int8VT
, 4);
143 auto OutVecVT
= EVT::getVectorVT(Context
, Int16VT
, 2);
144 auto InVec
= DAG
->getConstant(1, Loc
, InVecVT
);
145 auto Op
= DAG
->getNode(ISD::SIGN_EXTEND_VECTOR_INREG
, Loc
, OutVecVT
, InVec
);
146 auto DemandedElts
= APInt(2, 3);
147 EXPECT_EQ(DAG
->ComputeNumSignBits(Op
, DemandedElts
), 15u);
150 TEST_F(AArch64SelectionDAGTest
, ComputeNumSignBitsSVE_SIGN_EXTEND_VECTOR_INREG
) {
154 auto Int8VT
= EVT::getIntegerVT(Context
, 8);
155 auto Int16VT
= EVT::getIntegerVT(Context
, 16);
156 auto InVecVT
= EVT::getVectorVT(Context
, Int8VT
, 4, /*IsScalable=*/true);
157 auto OutVecVT
= EVT::getVectorVT(Context
, Int16VT
, 2, /*IsScalable=*/true);
158 auto InVec
= DAG
->getConstant(1, Loc
, InVecVT
);
159 auto Op
= DAG
->getNode(ISD::SIGN_EXTEND_VECTOR_INREG
, Loc
, OutVecVT
, InVec
);
160 auto DemandedElts
= APInt(2, 3);
161 EXPECT_EQ(DAG
->ComputeNumSignBits(Op
, DemandedElts
), 1u);
164 TEST_F(AArch64SelectionDAGTest
, ComputeNumSignBits_EXTRACT_SUBVECTOR
) {
168 auto IntVT
= EVT::getIntegerVT(Context
, 8);
169 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 3);
170 auto IdxVT
= EVT::getIntegerVT(Context
, 64);
171 auto Vec
= DAG
->getConstant(1, Loc
, VecVT
);
172 auto ZeroIdx
= DAG
->getConstant(0, Loc
, IdxVT
);
173 auto Op
= DAG
->getNode(ISD::EXTRACT_SUBVECTOR
, Loc
, VecVT
, Vec
, ZeroIdx
);
174 auto DemandedElts
= APInt(3, 7);
175 EXPECT_EQ(DAG
->ComputeNumSignBits(Op
, DemandedElts
), 7u);
178 TEST_F(AArch64SelectionDAGTest
, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR
) {
182 TargetLowering
TL(*TM
);
185 auto IntVT
= EVT::getIntegerVT(Context
, 8);
186 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 3);
187 auto IdxVT
= EVT::getIntegerVT(Context
, 64);
188 auto Vec
= DAG
->getConstant(1, Loc
, VecVT
);
189 auto ZeroIdx
= DAG
->getConstant(0, Loc
, IdxVT
);
190 auto Op
= DAG
->getNode(ISD::EXTRACT_SUBVECTOR
, Loc
, VecVT
, Vec
, ZeroIdx
);
191 auto DemandedElts
= APInt(3, 7);
192 auto KnownUndef
= APInt(3, 0);
193 auto KnownZero
= APInt(3, 0);
194 TargetLowering::TargetLoweringOpt
TLO(*DAG
, false, false);
195 EXPECT_EQ(TL
.SimplifyDemandedVectorElts(Op
, DemandedElts
, KnownUndef
,
200 TEST_F(AArch64SelectionDAGTest
, SimplifyDemandedBitsNEON
) {
204 TargetLowering
TL(*TM
);
207 auto Int8VT
= EVT::getIntegerVT(Context
, 8);
208 auto InVecVT
= EVT::getVectorVT(Context
, Int8VT
, 16);
209 SDValue UnknownOp
= DAG
->getRegister(0, InVecVT
);
210 SDValue Mask1S
= DAG
->getConstant(0x8A, Loc
, Int8VT
);
211 SDValue Mask1V
= DAG
->getSplatBuildVector(InVecVT
, Loc
, Mask1S
);
212 SDValue N0
= DAG
->getNode(ISD::AND
, Loc
, InVecVT
, Mask1V
, UnknownOp
);
214 SDValue Mask2S
= DAG
->getConstant(0x55, Loc
, Int8VT
);
215 SDValue Mask2V
= DAG
->getSplatBuildVector(InVecVT
, Loc
, Mask2S
);
217 SDValue Op
= DAG
->getNode(ISD::AND
, Loc
, InVecVT
, N0
, Mask2V
);
221 // Known.Zero = 00100000 (0xAA)
223 APInt DemandedBits
= APInt(8, 0xFF);
224 TargetLowering::TargetLoweringOpt
TLO(*DAG
, false, false);
225 EXPECT_TRUE(TL
.SimplifyDemandedBits(Op
, DemandedBits
, Known
, TLO
));
226 EXPECT_EQ(Known
.Zero
, APInt(8, 0xAA));
229 TEST_F(AArch64SelectionDAGTest
, SimplifyDemandedBitsSVE
) {
233 TargetLowering
TL(*TM
);
236 auto Int8VT
= EVT::getIntegerVT(Context
, 8);
237 auto InVecVT
= EVT::getVectorVT(Context
, Int8VT
, 16, /*IsScalable=*/true);
238 SDValue UnknownOp
= DAG
->getRegister(0, InVecVT
);
239 SDValue Mask1S
= DAG
->getConstant(0x8A, Loc
, Int8VT
);
240 SDValue Mask1V
= DAG
->getSplatVector(InVecVT
, Loc
, Mask1S
);
241 SDValue N0
= DAG
->getNode(ISD::AND
, Loc
, InVecVT
, Mask1V
, UnknownOp
);
243 SDValue Mask2S
= DAG
->getConstant(0x55, Loc
, Int8VT
);
244 SDValue Mask2V
= DAG
->getSplatVector(InVecVT
, Loc
, Mask2S
);
246 SDValue Op
= DAG
->getNode(ISD::AND
, Loc
, InVecVT
, N0
, Mask2V
);
249 APInt DemandedBits
= APInt(8, 0xFF);
250 TargetLowering::TargetLoweringOpt
TLO(*DAG
, false, false);
251 EXPECT_FALSE(TL
.SimplifyDemandedBits(Op
, DemandedBits
, Known
, TLO
));
252 EXPECT_EQ(Known
.Zero
, APInt(8, 0));
255 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
256 TEST_F(AArch64SelectionDAGTest
, ComputeKnownBits_ADD
) {
260 auto IntVT
= EVT::getIntegerVT(Context
, 8);
261 auto UnknownOp
= DAG
->getRegister(0, IntVT
);
262 auto Mask
= DAG
->getConstant(0x8A, Loc
, IntVT
);
263 auto N0
= DAG
->getNode(ISD::AND
, Loc
, IntVT
, Mask
, UnknownOp
);
264 auto N1
= DAG
->getConstant(0x55, Loc
, IntVT
);
265 auto Op
= DAG
->getNode(ISD::ADD
, Loc
, IntVT
, N0
, N1
);
269 // Known.One = 01010101 (0x55)
270 // Known.Zero = 00100000 (0x20)
271 KnownBits Known
= DAG
->computeKnownBits(Op
);
272 EXPECT_EQ(Known
.Zero
, APInt(8, 0x20));
273 EXPECT_EQ(Known
.One
, APInt(8, 0x55));
276 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
277 TEST_F(AArch64SelectionDAGTest
, ComputeKnownBits_SUB
) {
281 auto IntVT
= EVT::getIntegerVT(Context
, 8);
282 auto N0
= DAG
->getConstant(0x55, Loc
, IntVT
);
283 auto UnknownOp
= DAG
->getRegister(0, IntVT
);
284 auto Mask
= DAG
->getConstant(0x2e, Loc
, IntVT
);
285 auto N1
= DAG
->getNode(ISD::AND
, Loc
, IntVT
, Mask
, UnknownOp
);
286 auto Op
= DAG
->getNode(ISD::SUB
, Loc
, IntVT
, N0
, N1
);
290 // Known.One = 00000001 (0x1)
291 // Known.Zero = 10000000 (0x80)
292 KnownBits Known
= DAG
->computeKnownBits(Op
);
293 EXPECT_EQ(Known
.Zero
, APInt(8, 0x80));
294 EXPECT_EQ(Known
.One
, APInt(8, 0x1));
297 TEST_F(AArch64SelectionDAGTest
, isSplatValue_Fixed_BUILD_VECTOR
) {
301 TargetLowering
TL(*TM
);
304 auto IntVT
= EVT::getIntegerVT(Context
, 8);
305 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 16, false);
306 // Create a BUILD_VECTOR
307 SDValue Op
= DAG
->getConstant(1, Loc
, VecVT
);
308 EXPECT_EQ(Op
->getOpcode(), ISD::BUILD_VECTOR
);
309 EXPECT_TRUE(DAG
->isSplatValue(Op
, /*AllowUndefs=*/false));
313 EXPECT_FALSE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
316 DemandedElts
= APInt(16, 3);
317 EXPECT_TRUE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
320 TEST_F(AArch64SelectionDAGTest
, isSplatValue_Fixed_ADD_of_BUILD_VECTOR
) {
324 TargetLowering
TL(*TM
);
327 auto IntVT
= EVT::getIntegerVT(Context
, 8);
328 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 16, false);
330 // Should create BUILD_VECTORs
331 SDValue Val1
= DAG
->getConstant(1, Loc
, VecVT
);
332 SDValue Val2
= DAG
->getConstant(3, Loc
, VecVT
);
333 EXPECT_EQ(Val1
->getOpcode(), ISD::BUILD_VECTOR
);
334 SDValue Op
= DAG
->getNode(ISD::ADD
, Loc
, VecVT
, Val1
, Val2
);
336 EXPECT_TRUE(DAG
->isSplatValue(Op
, /*AllowUndefs=*/false));
340 EXPECT_FALSE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
343 DemandedElts
= APInt(16, 3);
344 EXPECT_TRUE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
347 TEST_F(AArch64SelectionDAGTest
, isSplatValue_Scalable_SPLAT_VECTOR
) {
351 TargetLowering
TL(*TM
);
354 auto IntVT
= EVT::getIntegerVT(Context
, 8);
355 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 16, true);
356 // Create a SPLAT_VECTOR
357 SDValue Op
= DAG
->getConstant(1, Loc
, VecVT
);
358 EXPECT_EQ(Op
->getOpcode(), ISD::SPLAT_VECTOR
);
359 EXPECT_TRUE(DAG
->isSplatValue(Op
, /*AllowUndefs=*/false));
363 EXPECT_TRUE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
365 // Width=16, Mask=3. These bits should be ignored.
366 DemandedElts
= APInt(16, 3);
367 EXPECT_TRUE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
370 TEST_F(AArch64SelectionDAGTest
, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR
) {
374 TargetLowering
TL(*TM
);
377 auto IntVT
= EVT::getIntegerVT(Context
, 8);
378 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 16, true);
380 // Should create SPLAT_VECTORS
381 SDValue Val1
= DAG
->getConstant(1, Loc
, VecVT
);
382 SDValue Val2
= DAG
->getConstant(3, Loc
, VecVT
);
383 EXPECT_EQ(Val1
->getOpcode(), ISD::SPLAT_VECTOR
);
384 SDValue Op
= DAG
->getNode(ISD::ADD
, Loc
, VecVT
, Val1
, Val2
);
386 EXPECT_TRUE(DAG
->isSplatValue(Op
, /*AllowUndefs=*/false));
390 EXPECT_TRUE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
392 // Width=16, Mask=3. These bits should be ignored.
393 DemandedElts
= APInt(16, 3);
394 EXPECT_TRUE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
397 TEST_F(AArch64SelectionDAGTest
, getSplatSourceVector_Fixed_BUILD_VECTOR
) {
401 TargetLowering
TL(*TM
);
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
);
411 EXPECT_EQ(DAG
->getSplatSourceVector(Op
, SplatIdx
), Op
);
412 EXPECT_EQ(SplatIdx
, 0);
415 TEST_F(AArch64SelectionDAGTest
, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR
) {
419 TargetLowering
TL(*TM
);
422 auto IntVT
= EVT::getIntegerVT(Context
, 8);
423 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 16, false);
425 // Should create BUILD_VECTORs
426 SDValue Val1
= DAG
->getConstant(1, Loc
, VecVT
);
427 SDValue Val2
= DAG
->getConstant(3, Loc
, VecVT
);
428 EXPECT_EQ(Val1
->getOpcode(), ISD::BUILD_VECTOR
);
429 SDValue Op
= DAG
->getNode(ISD::ADD
, Loc
, VecVT
, Val1
, Val2
);
432 EXPECT_EQ(DAG
->getSplatSourceVector(Op
, SplatIdx
), Op
);
433 EXPECT_EQ(SplatIdx
, 0);
436 TEST_F(AArch64SelectionDAGTest
, getSplatSourceVector_Scalable_SPLAT_VECTOR
) {
440 TargetLowering
TL(*TM
);
443 auto IntVT
= EVT::getIntegerVT(Context
, 8);
444 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 16, true);
445 // Create a SPLAT_VECTOR
446 SDValue Op
= DAG
->getConstant(1, Loc
, VecVT
);
447 EXPECT_EQ(Op
->getOpcode(), ISD::SPLAT_VECTOR
);
450 EXPECT_EQ(DAG
->getSplatSourceVector(Op
, SplatIdx
), Op
);
451 EXPECT_EQ(SplatIdx
, 0);
454 TEST_F(AArch64SelectionDAGTest
, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR
) {
458 TargetLowering
TL(*TM
);
461 auto IntVT
= EVT::getIntegerVT(Context
, 8);
462 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 16, true);
464 // Should create SPLAT_VECTORS
465 SDValue Val1
= DAG
->getConstant(1, Loc
, VecVT
);
466 SDValue Val2
= DAG
->getConstant(3, Loc
, VecVT
);
467 EXPECT_EQ(Val1
->getOpcode(), ISD::SPLAT_VECTOR
);
468 SDValue Op
= DAG
->getNode(ISD::ADD
, Loc
, VecVT
, Val1
, Val2
);
471 EXPECT_EQ(DAG
->getSplatSourceVector(Op
, SplatIdx
), Op
);
472 EXPECT_EQ(SplatIdx
, 0);
475 TEST_F(AArch64SelectionDAGTest
, getRepeatedSequence_Patterns
) {
479 TargetLowering
TL(*TM
);
482 unsigned NumElts
= 16;
484 MVT VecVT
= MVT::getVectorVT(IntVT
, NumElts
);
486 // Base scalar constants.
487 SDValue Val0
= DAG
->getConstant(0, Loc
, IntVT
);
488 SDValue Val1
= DAG
->getConstant(1, Loc
, IntVT
);
489 SDValue Val2
= DAG
->getConstant(2, Loc
, IntVT
);
490 SDValue Val3
= DAG
->getConstant(3, Loc
, IntVT
);
491 SDValue UndefVal
= DAG
->getUNDEF(IntVT
);
493 // Build some repeating sequences.
494 SmallVector
<SDValue
, 16> Pattern1111
, Pattern1133
, Pattern0123
;
495 for(int I
= 0; I
!= 4; ++I
) {
496 Pattern1111
.append(4, Val1
);
497 Pattern1133
.append(2, Val1
);
498 Pattern1133
.append(2, Val3
);
499 Pattern0123
.push_back(Val0
);
500 Pattern0123
.push_back(Val1
);
501 Pattern0123
.push_back(Val2
);
502 Pattern0123
.push_back(Val3
);
505 // Build a non-pow2 repeating sequence.
506 SmallVector
<SDValue
, 16> Pattern022
;
507 Pattern022
.push_back(Val0
);
508 Pattern022
.append(2, Val2
);
509 Pattern022
.push_back(Val0
);
510 Pattern022
.append(2, Val2
);
511 Pattern022
.push_back(Val0
);
512 Pattern022
.append(2, Val2
);
513 Pattern022
.push_back(Val0
);
514 Pattern022
.append(2, Val2
);
515 Pattern022
.push_back(Val0
);
516 Pattern022
.append(2, Val2
);
517 Pattern022
.push_back(Val0
);
519 // Build a non-repeating sequence.
520 SmallVector
<SDValue
, 16> Pattern1_3
;
521 Pattern1_3
.append(8, Val1
);
522 Pattern1_3
.append(8, Val3
);
524 // Add some undefs to make it trickier.
525 Pattern1111
[1] = Pattern1111
[2] = Pattern1111
[15] = UndefVal
;
526 Pattern1133
[0] = Pattern1133
[2] = UndefVal
;
529 cast
<BuildVectorSDNode
>(DAG
->getBuildVector(VecVT
, Loc
, Pattern1111
));
531 cast
<BuildVectorSDNode
>(DAG
->getBuildVector(VecVT
, Loc
, Pattern1133
));
533 cast
<BuildVectorSDNode
>(DAG
->getBuildVector(VecVT
, Loc
, Pattern0123
));
535 cast
<BuildVectorSDNode
>(DAG
->getBuildVector(VecVT
, Loc
, Pattern022
));
537 cast
<BuildVectorSDNode
>(DAG
->getBuildVector(VecVT
, Loc
, Pattern1_3
));
539 // Check for sequences.
540 SmallVector
<SDValue
, 16> Seq1111
, Seq1133
, Seq0123
, Seq022
, Seq1_3
;
541 BitVector Undefs1111
, Undefs1133
, Undefs0123
, Undefs022
, Undefs1_3
;
543 EXPECT_TRUE(BV1111
->getRepeatedSequence(Seq1111
, &Undefs1111
));
544 EXPECT_EQ(Undefs1111
.count(), 3u);
545 EXPECT_EQ(Seq1111
.size(), 1u);
546 EXPECT_EQ(Seq1111
[0], Val1
);
548 EXPECT_TRUE(BV1133
->getRepeatedSequence(Seq1133
, &Undefs1133
));
549 EXPECT_EQ(Undefs1133
.count(), 2u);
550 EXPECT_EQ(Seq1133
.size(), 4u);
551 EXPECT_EQ(Seq1133
[0], Val1
);
552 EXPECT_EQ(Seq1133
[1], Val1
);
553 EXPECT_EQ(Seq1133
[2], Val3
);
554 EXPECT_EQ(Seq1133
[3], Val3
);
556 EXPECT_TRUE(BV0123
->getRepeatedSequence(Seq0123
, &Undefs0123
));
557 EXPECT_EQ(Undefs0123
.count(), 0u);
558 EXPECT_EQ(Seq0123
.size(), 4u);
559 EXPECT_EQ(Seq0123
[0], Val0
);
560 EXPECT_EQ(Seq0123
[1], Val1
);
561 EXPECT_EQ(Seq0123
[2], Val2
);
562 EXPECT_EQ(Seq0123
[3], Val3
);
564 EXPECT_FALSE(BV022
->getRepeatedSequence(Seq022
, &Undefs022
));
565 EXPECT_FALSE(BV1_3
->getRepeatedSequence(Seq1_3
, &Undefs1_3
));
567 // Try again with DemandedElts masks.
568 APInt Mask1111_0
= APInt::getOneBitSet(NumElts
, 0);
569 EXPECT_TRUE(BV1111
->getRepeatedSequence(Mask1111_0
, Seq1111
, &Undefs1111
));
570 EXPECT_EQ(Undefs1111
.count(), 0u);
571 EXPECT_EQ(Seq1111
.size(), 1u);
572 EXPECT_EQ(Seq1111
[0], Val1
);
574 APInt Mask1111_1
= APInt::getOneBitSet(NumElts
, 2);
575 EXPECT_TRUE(BV1111
->getRepeatedSequence(Mask1111_1
, Seq1111
, &Undefs1111
));
576 EXPECT_EQ(Undefs1111
.count(), 1u);
577 EXPECT_EQ(Seq1111
.size(), 1u);
578 EXPECT_EQ(Seq1111
[0], UndefVal
);
580 APInt Mask0123
= APInt(NumElts
, 0x7777);
581 EXPECT_TRUE(BV0123
->getRepeatedSequence(Mask0123
, Seq0123
, &Undefs0123
));
582 EXPECT_EQ(Undefs0123
.count(), 0u);
583 EXPECT_EQ(Seq0123
.size(), 4u);
584 EXPECT_EQ(Seq0123
[0], Val0
);
585 EXPECT_EQ(Seq0123
[1], Val1
);
586 EXPECT_EQ(Seq0123
[2], Val2
);
587 EXPECT_EQ(Seq0123
[3], SDValue());
589 APInt Mask1_3
= APInt::getHighBitsSet(16, 8);
590 EXPECT_TRUE(BV1_3
->getRepeatedSequence(Mask1_3
, Seq1_3
, &Undefs1_3
));
591 EXPECT_EQ(Undefs1_3
.count(), 0u);
592 EXPECT_EQ(Seq1_3
.size(), 1u);
593 EXPECT_EQ(Seq1_3
[0], Val3
);
596 TEST_F(AArch64SelectionDAGTest
, getTypeConversion_SplitScalableMVT
) {
600 MVT VT
= MVT::nxv4i64
;
601 EXPECT_EQ(getTypeAction(VT
), TargetLoweringBase::TypeSplitVector
);
602 ASSERT_TRUE(getTypeToTransformTo(VT
).isScalableVector());
605 TEST_F(AArch64SelectionDAGTest
, getTypeConversion_PromoteScalableMVT
) {
609 MVT VT
= MVT::nxv2i32
;
610 EXPECT_EQ(getTypeAction(VT
), TargetLoweringBase::TypePromoteInteger
);
611 ASSERT_TRUE(getTypeToTransformTo(VT
).isScalableVector());
614 TEST_F(AArch64SelectionDAGTest
, getTypeConversion_NoScalarizeMVT_nxv1f32
) {
618 MVT VT
= MVT::nxv1f32
;
619 EXPECT_NE(getTypeAction(VT
), TargetLoweringBase::TypeScalarizeVector
);
620 ASSERT_TRUE(getTypeToTransformTo(VT
).isScalableVector());
623 TEST_F(AArch64SelectionDAGTest
, getTypeConversion_SplitScalableEVT
) {
627 EVT VT
= EVT::getVectorVT(Context
, MVT::i64
, 256, true);
628 EXPECT_EQ(getTypeAction(VT
), TargetLoweringBase::TypeSplitVector
);
629 EXPECT_EQ(getTypeToTransformTo(VT
), VT
.getHalfNumVectorElementsVT(Context
));
632 TEST_F(AArch64SelectionDAGTest
, getTypeConversion_WidenScalableEVT
) {
636 EVT FromVT
= EVT::getVectorVT(Context
, MVT::i64
, 6, true);
637 EVT ToVT
= EVT::getVectorVT(Context
, MVT::i64
, 8, true);
639 EXPECT_EQ(getTypeAction(FromVT
), TargetLoweringBase::TypeWidenVector
);
640 EXPECT_EQ(getTypeToTransformTo(FromVT
), ToVT
);
643 TEST_F(AArch64SelectionDAGTest
, getTypeConversion_NoScalarizeEVT_nxv1f128
) {
647 EVT FromVT
= EVT::getVectorVT(Context
, MVT::f128
, 1, true);
648 EXPECT_DEATH(getTypeAction(FromVT
), "Cannot legalize this vector");
651 } // end namespace llvm