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 "../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"
27 class AArch64SelectionDAGTest
: public testing::Test
{
29 static void SetUpTestCase() {
30 InitializeAllTargets();
31 InitializeAllTargetMCs();
34 void SetUp() override
{
35 StringRef Assembly
= "define void @f() { ret void }";
37 Triple
TargetTriple("aarch64--");
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.
46 TargetOptions Options
;
47 TM
= std::unique_ptr
<TargetMachine
>(
48 T
->createTargetMachine("AArch64", "", "+sve", Options
, std::nullopt
,
49 std::nullopt
, CodeGenOptLevel::Aggressive
));
54 M
= parseAssemblyString(Assembly
, SMError
, Context
);
56 report_fatal_error(SMError
.getMessage());
57 M
->setDataLayout(TM
->createDataLayout());
59 F
= M
->getFunction("f");
61 report_fatal_error("F?");
63 MachineModuleInfo
MMI(TM
.get());
65 MF
= std::make_unique
<MachineFunction
>(*F
, *TM
, *TM
->getSubtargetImpl(*F
),
68 DAG
= std::make_unique
<SelectionDAG
>(*TM
, CodeGenOptLevel::None
);
70 report_fatal_error("DAG?");
71 OptimizationRemarkEmitter
ORE(F
);
72 DAG
->init(*MF
, ORE
, nullptr, nullptr, nullptr, nullptr, nullptr, MMI
,
76 TargetLoweringBase::LegalizeTypeAction
getTypeAction(EVT VT
) {
77 return DAG
->getTargetLoweringInfo().getTypeAction(Context
, VT
);
80 EVT
getTypeToTransformTo(EVT VT
) {
81 return DAG
->getTargetLoweringInfo().getTypeToTransformTo(Context
, VT
);
85 std::unique_ptr
<TargetMachine
> TM
;
86 std::unique_ptr
<Module
> M
;
88 std::unique_ptr
<MachineFunction
> MF
;
89 std::unique_ptr
<SelectionDAG
> DAG
;
92 TEST_F(AArch64SelectionDAGTest
, computeKnownBits_ZERO_EXTEND_VECTOR_INREG
) {
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());
105 TEST_F(AArch64SelectionDAGTest
, computeKnownBitsSVE_ZERO_EXTEND_VECTOR_INREG
) {
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
);
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());
122 TEST_F(AArch64SelectionDAGTest
, computeKnownBits_EXTRACT_SUBVECTOR
) {
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());
135 TEST_F(AArch64SelectionDAGTest
, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG
) {
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);
147 TEST_F(AArch64SelectionDAGTest
, ComputeNumSignBitsSVE_SIGN_EXTEND_VECTOR_INREG
) {
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);
159 TEST_F(AArch64SelectionDAGTest
, ComputeNumSignBits_EXTRACT_SUBVECTOR
) {
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);
171 TEST_F(AArch64SelectionDAGTest
, ComputeNumSignBits_VASHR
) {
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);
183 TEST_F(AArch64SelectionDAGTest
, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR
) {
184 TargetLowering
TL(*TM
);
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
,
202 TEST_F(AArch64SelectionDAGTest
, SimplifyDemandedBitsNEON
) {
203 TargetLowering
TL(*TM
);
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
);
213 SDValue Mask2S
= DAG
->getConstant(0x55, Loc
, Int8VT
);
214 SDValue Mask2V
= DAG
->getSplatBuildVector(InVecVT
, Loc
, Mask2S
);
216 SDValue Op
= DAG
->getNode(ISD::AND
, Loc
, InVecVT
, N0
, Mask2V
);
220 // Known.Zero = 00100000 (0xAA)
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));
228 TEST_F(AArch64SelectionDAGTest
, SimplifyDemandedBitsSVE
) {
229 TargetLowering
TL(*TM
);
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
);
239 SDValue Mask2S
= DAG
->getConstant(0x55, Loc
, Int8VT
);
240 SDValue Mask2V
= DAG
->getSplatVector(InVecVT
, Loc
, Mask2S
);
242 SDValue Op
= DAG
->getNode(ISD::AND
, Loc
, InVecVT
, N0
, Mask2V
);
247 // Known.Zero = 00100000 (0xAA)
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));
255 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
256 TEST_F(AArch64SelectionDAGTest
, ComputeKnownBits_ADD
) {
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
);
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));
274 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
275 TEST_F(AArch64SelectionDAGTest
, ComputeKnownBits_UADDO_CARRY
) {
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
);
287 auto UnknownBorrow
= DAG
->getRegister(1, IntVT
);
288 auto OpUnknownBorrow
=
289 DAG
->getNode(ISD::UADDO_CARRY
, Loc
, IntVT
, N0
, N1
, UnknownBorrow
);
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));
300 auto ZeroBorrow
= DAG
->getConstant(0x0, Loc
, IntVT
);
302 DAG
->getNode(ISD::UADDO_CARRY
, Loc
, IntVT
, N0
, N1
, ZeroBorrow
);
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));
313 auto OneBorrow
= DAG
->getConstant(0x1, Loc
, IntVT
);
315 DAG
->getNode(ISD::UADDO_CARRY
, Loc
, IntVT
, N0
, N1
, OneBorrow
);
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));
327 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
328 TEST_F(AArch64SelectionDAGTest
, ComputeKnownBits_SUB
) {
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
);
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));
346 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
347 TEST_F(AArch64SelectionDAGTest
, ComputeKnownBits_USUBO_CARRY
) {
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
);
360 auto UnknownBorrow
= DAG
->getRegister(1, IntVT
);
361 auto OpUnknownBorrow
=
362 DAG
->getNode(ISD::USUBO_CARRY
, Loc
, IntVT
, N0
, N1
, UnknownBorrow
);
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));
373 auto ZeroBorrow
= DAG
->getConstant(0x0, Loc
, IntVT
);
375 DAG
->getNode(ISD::USUBO_CARRY
, Loc
, IntVT
, N0
, N1
, ZeroBorrow
);
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));
386 auto OneBorrow
= DAG
->getConstant(0x1, Loc
, IntVT
);
388 DAG
->getNode(ISD::USUBO_CARRY
, Loc
, IntVT
, N0
, N1
, OneBorrow
);
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));
400 TEST_F(AArch64SelectionDAGTest
, isSplatValue_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
);
409 EXPECT_TRUE(DAG
->isSplatValue(Op
, /*AllowUndefs=*/false));
413 EXPECT_FALSE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
416 DemandedElts
= APInt(16, 3);
417 EXPECT_TRUE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
420 TEST_F(AArch64SelectionDAGTest
, isSplatValue_Fixed_ADD_of_BUILD_VECTOR
) {
421 TargetLowering
TL(*TM
);
424 auto IntVT
= EVT::getIntegerVT(Context
, 8);
425 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 16, false);
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
);
433 EXPECT_TRUE(DAG
->isSplatValue(Op
, /*AllowUndefs=*/false));
437 EXPECT_FALSE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
440 DemandedElts
= APInt(16, 3);
441 EXPECT_TRUE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
444 TEST_F(AArch64SelectionDAGTest
, isSplatValue_Scalable_SPLAT_VECTOR
) {
445 TargetLowering
TL(*TM
);
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));
456 APInt
DemandedElts(1,1);
457 EXPECT_TRUE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
460 TEST_F(AArch64SelectionDAGTest
, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR
) {
461 TargetLowering
TL(*TM
);
464 auto IntVT
= EVT::getIntegerVT(Context
, 8);
465 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 16, true);
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
);
473 EXPECT_TRUE(DAG
->isSplatValue(Op
, /*AllowUndefs=*/false));
476 APInt
DemandedElts(1, 1);
477 EXPECT_TRUE(DAG
->isSplatValue(Op
, DemandedElts
, UndefElts
));
480 TEST_F(AArch64SelectionDAGTest
, getSplatSourceVector_Fixed_BUILD_VECTOR
) {
481 TargetLowering
TL(*TM
);
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
);
491 EXPECT_EQ(DAG
->getSplatSourceVector(Op
, SplatIdx
), Op
);
492 EXPECT_EQ(SplatIdx
, 0);
495 TEST_F(AArch64SelectionDAGTest
, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR
) {
496 TargetLowering
TL(*TM
);
499 auto IntVT
= EVT::getIntegerVT(Context
, 8);
500 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 16, false);
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
);
509 EXPECT_EQ(DAG
->getSplatSourceVector(Op
, SplatIdx
), Op
);
510 EXPECT_EQ(SplatIdx
, 0);
513 TEST_F(AArch64SelectionDAGTest
, getSplatSourceVector_Scalable_SPLAT_VECTOR
) {
514 TargetLowering
TL(*TM
);
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
);
524 EXPECT_EQ(DAG
->getSplatSourceVector(Op
, SplatIdx
), Op
);
525 EXPECT_EQ(SplatIdx
, 0);
528 TEST_F(AArch64SelectionDAGTest
, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR
) {
529 TargetLowering
TL(*TM
);
532 auto IntVT
= EVT::getIntegerVT(Context
, 8);
533 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 16, true);
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
);
542 EXPECT_EQ(DAG
->getSplatSourceVector(Op
, SplatIdx
), Op
);
543 EXPECT_EQ(SplatIdx
, 0);
546 TEST_F(AArch64SelectionDAGTest
, getRepeatedSequence_Patterns
) {
547 TargetLowering
TL(*TM
);
550 unsigned NumElts
= 16;
552 MVT VecVT
= MVT::getVectorVT(IntVT
, NumElts
);
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
);
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
);
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
);
587 // Build a non-repeating sequence.
588 SmallVector
<SDValue
, 16> Pattern1_3
;
589 Pattern1_3
.append(8, Val1
);
590 Pattern1_3
.append(8, Val3
);
592 // Add some undefs to make it trickier.
593 Pattern1111
[1] = Pattern1111
[2] = Pattern1111
[15] = UndefVal
;
594 Pattern1133
[0] = Pattern1133
[2] = UndefVal
;
597 cast
<BuildVectorSDNode
>(DAG
->getBuildVector(VecVT
, Loc
, Pattern1111
));
599 cast
<BuildVectorSDNode
>(DAG
->getBuildVector(VecVT
, Loc
, Pattern1133
));
601 cast
<BuildVectorSDNode
>(DAG
->getBuildVector(VecVT
, Loc
, Pattern0123
));
603 cast
<BuildVectorSDNode
>(DAG
->getBuildVector(VecVT
, Loc
, Pattern022
));
605 cast
<BuildVectorSDNode
>(DAG
->getBuildVector(VecVT
, Loc
, Pattern1_3
));
607 // Check for sequences.
608 SmallVector
<SDValue
, 16> Seq1111
, Seq1133
, Seq0123
, Seq022
, Seq1_3
;
609 BitVector Undefs1111
, Undefs1133
, Undefs0123
, Undefs022
, Undefs1_3
;
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
);
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
);
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
);
632 EXPECT_FALSE(BV022
->getRepeatedSequence(Seq022
, &Undefs022
));
633 EXPECT_FALSE(BV1_3
->getRepeatedSequence(Seq1_3
, &Undefs1_3
));
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
);
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
);
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());
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
);
664 TEST_F(AArch64SelectionDAGTest
, getTypeConversion_SplitScalableMVT
) {
665 MVT VT
= MVT::nxv4i64
;
666 EXPECT_EQ(getTypeAction(VT
), TargetLoweringBase::TypeSplitVector
);
667 ASSERT_TRUE(getTypeToTransformTo(VT
).isScalableVector());
670 TEST_F(AArch64SelectionDAGTest
, getTypeConversion_PromoteScalableMVT
) {
671 MVT VT
= MVT::nxv2i32
;
672 EXPECT_EQ(getTypeAction(VT
), TargetLoweringBase::TypePromoteInteger
);
673 ASSERT_TRUE(getTypeToTransformTo(VT
).isScalableVector());
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());
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
));
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);
692 EXPECT_EQ(getTypeAction(FromVT
), TargetLoweringBase::TypeWidenVector
);
693 EXPECT_EQ(getTypeToTransformTo(FromVT
), ToVT
);
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
);
703 TEST_F(AArch64SelectionDAGTest
, TestFold_STEP_VECTOR
) {
705 auto IntVT
= EVT::getIntegerVT(Context
, 8);
706 auto VecVT
= EVT::getVectorVT(Context
, MVT::i8
, 16, true);
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
);
714 TEST_F(AArch64SelectionDAGTest
, ReplaceAllUsesWith
) {
716 EVT IntVT
= EVT::getIntegerVT(Context
, 8);
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
);
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()));
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
);
748 TEST_F(AArch64SelectionDAGTest
, computeKnownBits_extload_known01
) {
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
);
755 MachinePointerInfo::getFixedStack(DAG
->getMachineFunction(), 0);
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
);
762 auto ALoad
= DAG
->getExtLoad(ISD::EXTLOAD
, Loc
, Int32VT
, DAG
->getEntryNode(),
764 KnownBits Known
= DAG
->computeKnownBits(ALoad
);
765 EXPECT_EQ(Known
.Zero
, APInt(32, 0xfe));
766 EXPECT_EQ(Known
.One
, APInt(32, 0));
768 auto ZLoad
= DAG
->getExtLoad(ISD::ZEXTLOAD
, Loc
, Int32VT
, DAG
->getEntryNode(),
770 Known
= DAG
->computeKnownBits(ZLoad
);
771 EXPECT_EQ(Known
.Zero
, APInt(32, 0xfffffffe));
772 EXPECT_EQ(Known
.One
, APInt(32, 0));
774 auto SLoad
= DAG
->getExtLoad(ISD::SEXTLOAD
, Loc
, Int32VT
, DAG
->getEntryNode(),
776 Known
= DAG
->computeKnownBits(SLoad
);
777 EXPECT_EQ(Known
.Zero
, APInt(32, 0xfffffffe));
778 EXPECT_EQ(Known
.One
, APInt(32, 0));
781 TEST_F(AArch64SelectionDAGTest
, computeKnownBits_extload_knownnegative
) {
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
);
788 MachinePointerInfo::getFixedStack(DAG
->getMachineFunction(), 0);
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
);
795 auto ALoad
= DAG
->getExtLoad(ISD::EXTLOAD
, Loc
, Int32VT
, DAG
->getEntryNode(),
797 KnownBits Known
= DAG
->computeKnownBits(ALoad
);
798 EXPECT_EQ(Known
.Zero
, APInt(32, 0));
799 EXPECT_EQ(Known
.One
, APInt(32, 0xf0));
801 auto ZLoad
= DAG
->getExtLoad(ISD::ZEXTLOAD
, Loc
, Int32VT
, DAG
->getEntryNode(),
803 Known
= DAG
->computeKnownBits(ZLoad
);
804 EXPECT_EQ(Known
.Zero
, APInt(32, 0xffffff00));
805 EXPECT_EQ(Known
.One
, APInt(32, 0x000000f0));
807 auto SLoad
= DAG
->getExtLoad(ISD::SEXTLOAD
, Loc
, Int32VT
, DAG
->getEntryNode(),
809 Known
= DAG
->computeKnownBits(SLoad
);
810 EXPECT_EQ(Known
.Zero
, APInt(32, 0));
811 EXPECT_EQ(Known
.One
, APInt(32, 0xfffffff0));
814 TEST_F(AArch64SelectionDAGTest
,
815 computeKnownBits_AVGFLOORU_AVGFLOORS_AVGCEILU_AVGCEILS
) {
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);
822 SDValue UnknownOp0
= DAG
->getRegister(0, Int8Vec8VT
);
823 SDValue UnknownOp1
= DAG
->getRegister(1, Int8Vec8VT
);
826 DAG
->getNode(ISD::ZERO_EXTEND
, Loc
, Int16Vec8VT
, UnknownOp0
);
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);
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
);
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
);
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
);
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
);
862 } // end namespace llvm