Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / unittests / CodeGen / AArch64SelectionDAGTest.cpp
blobbb8e76a2eeb8beb710d58170fa200888338b9dea
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 //===----------------------------------------------------------------------===//
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/MC/TargetRegistry.h"
15 #include "llvm/Support/KnownBits.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "llvm/Support/TargetSelect.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "gtest/gtest.h"
21 namespace llvm {
23 class AArch64SelectionDAGTest : public testing::Test {
24 protected:
25 static void SetUpTestCase() {
26 InitializeAllTargets();
27 InitializeAllTargetMCs();
30 void SetUp() override {
31 StringRef Assembly = "define void @f() { ret void }";
33 Triple TargetTriple("aarch64--");
34 std::string Error;
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.
39 if (!T)
40 GTEST_SKIP();
42 TargetOptions Options;
43 TM = std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>(
44 T->createTargetMachine("AArch64", "", "+sve", Options, std::nullopt,
45 std::nullopt, CodeGenOptLevel::Aggressive)));
46 if (!TM)
47 GTEST_SKIP();
49 SMDiagnostic SMError;
50 M = parseAssemblyString(Assembly, SMError, Context);
51 if (!M)
52 report_fatal_error(SMError.getMessage());
53 M->setDataLayout(TM->createDataLayout());
55 F = M->getFunction("f");
56 if (!F)
57 report_fatal_error("F?");
59 MachineModuleInfo MMI(TM.get());
61 MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F), 0,
62 MMI);
64 DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None);
65 if (!DAG)
66 report_fatal_error("DAG?");
67 OptimizationRemarkEmitter ORE(F);
68 DAG->init(*MF, ORE, nullptr, 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);
79 LLVMContext Context;
80 std::unique_ptr<LLVMTargetMachine> TM;
81 std::unique_ptr<Module> M;
82 Function *F;
83 std::unique_ptr<MachineFunction> MF;
84 std::unique_ptr<SelectionDAG> DAG;
87 TEST_F(AArch64SelectionDAGTest, computeKnownBits_ZERO_EXTEND_VECTOR_INREG) {
88 SDLoc Loc;
89 auto Int8VT = EVT::getIntegerVT(Context, 8);
90 auto Int16VT = EVT::getIntegerVT(Context, 16);
91 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);
92 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);
93 auto InVec = DAG->getConstant(0, Loc, InVecVT);
94 auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
95 auto DemandedElts = APInt(2, 3);
96 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
97 EXPECT_TRUE(Known.isZero());
100 TEST_F(AArch64SelectionDAGTest, computeKnownBitsSVE_ZERO_EXTEND_VECTOR_INREG) {
101 SDLoc Loc;
102 auto Int8VT = EVT::getIntegerVT(Context, 8);
103 auto Int16VT = EVT::getIntegerVT(Context, 16);
104 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, true);
105 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, true);
106 auto InVec = DAG->getConstant(0, Loc, InVecVT);
107 auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
108 auto DemandedElts = APInt(2, 3);
109 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
111 // We don't know anything for SVE at the moment.
112 EXPECT_EQ(Known.Zero, APInt(16, 0u));
113 EXPECT_EQ(Known.One, APInt(16, 0u));
114 EXPECT_FALSE(Known.isZero());
117 TEST_F(AArch64SelectionDAGTest, computeKnownBits_EXTRACT_SUBVECTOR) {
118 SDLoc Loc;
119 auto IntVT = EVT::getIntegerVT(Context, 8);
120 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
121 auto IdxVT = EVT::getIntegerVT(Context, 64);
122 auto Vec = DAG->getConstant(0, Loc, VecVT);
123 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
124 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
125 auto DemandedElts = APInt(3, 7);
126 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
127 EXPECT_TRUE(Known.isZero());
130 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG) {
131 SDLoc Loc;
132 auto Int8VT = EVT::getIntegerVT(Context, 8);
133 auto Int16VT = EVT::getIntegerVT(Context, 16);
134 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);
135 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);
136 auto InVec = DAG->getConstant(1, Loc, InVecVT);
137 auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
138 auto DemandedElts = APInt(2, 3);
139 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 15u);
142 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBitsSVE_SIGN_EXTEND_VECTOR_INREG) {
143 SDLoc Loc;
144 auto Int8VT = EVT::getIntegerVT(Context, 8);
145 auto Int16VT = EVT::getIntegerVT(Context, 16);
146 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, /*IsScalable=*/true);
147 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, /*IsScalable=*/true);
148 auto InVec = DAG->getConstant(1, Loc, InVecVT);
149 auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
150 auto DemandedElts = APInt(2, 3);
151 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 1u);
154 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_EXTRACT_SUBVECTOR) {
155 SDLoc Loc;
156 auto IntVT = EVT::getIntegerVT(Context, 8);
157 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
158 auto IdxVT = EVT::getIntegerVT(Context, 64);
159 auto Vec = DAG->getConstant(1, Loc, VecVT);
160 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
161 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
162 auto DemandedElts = APInt(3, 7);
163 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 7u);
166 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) {
167 TargetLowering TL(*TM);
169 SDLoc Loc;
170 auto IntVT = EVT::getIntegerVT(Context, 8);
171 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
172 auto IdxVT = EVT::getIntegerVT(Context, 64);
173 auto Vec = DAG->getConstant(1, Loc, VecVT);
174 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
175 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
176 auto DemandedElts = APInt(3, 7);
177 auto KnownUndef = APInt(3, 0);
178 auto KnownZero = APInt(3, 0);
179 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
180 EXPECT_EQ(TL.SimplifyDemandedVectorElts(Op, DemandedElts, KnownUndef,
181 KnownZero, TLO),
182 false);
185 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) {
186 TargetLowering TL(*TM);
188 SDLoc Loc;
189 auto Int8VT = EVT::getIntegerVT(Context, 8);
190 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16);
191 SDValue UnknownOp = DAG->getRegister(0, InVecVT);
192 SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);
193 SDValue Mask1V = DAG->getSplatBuildVector(InVecVT, Loc, Mask1S);
194 SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);
196 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT);
197 SDValue Mask2V = DAG->getSplatBuildVector(InVecVT, Loc, Mask2S);
199 SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V);
200 // N0 = ?000?0?0
201 // Mask2V = 01010101
202 // =>
203 // Known.Zero = 00100000 (0xAA)
204 KnownBits Known;
205 APInt DemandedBits = APInt(8, 0xFF);
206 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
207 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
208 EXPECT_EQ(Known.Zero, APInt(8, 0xAA));
211 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) {
212 TargetLowering TL(*TM);
214 SDLoc Loc;
215 auto Int8VT = EVT::getIntegerVT(Context, 8);
216 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16, /*IsScalable=*/true);
217 SDValue UnknownOp = DAG->getRegister(0, InVecVT);
218 SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);
219 SDValue Mask1V = DAG->getSplatVector(InVecVT, Loc, Mask1S);
220 SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);
222 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT);
223 SDValue Mask2V = DAG->getSplatVector(InVecVT, Loc, Mask2S);
225 SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V);
227 // N0 = ?000?0?0
228 // Mask2V = 01010101
229 // =>
230 // Known.Zero = 00100000 (0xAA)
231 KnownBits Known;
232 APInt DemandedBits = APInt(8, 0xFF);
233 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
234 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
235 EXPECT_EQ(Known.Zero, APInt(8, 0xAA));
238 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
239 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {
240 SDLoc Loc;
241 auto IntVT = EVT::getIntegerVT(Context, 8);
242 auto UnknownOp = DAG->getRegister(0, IntVT);
243 auto Mask = DAG->getConstant(0x8A, Loc, IntVT);
244 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
245 auto N1 = DAG->getConstant(0x55, Loc, IntVT);
246 auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1);
247 // N0 = ?000?0?0
248 // N1 = 01010101
249 // =>
250 // Known.One = 01010101 (0x55)
251 // Known.Zero = 00100000 (0x20)
252 KnownBits Known = DAG->computeKnownBits(Op);
253 EXPECT_EQ(Known.Zero, APInt(8, 0x20));
254 EXPECT_EQ(Known.One, APInt(8, 0x55));
257 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
258 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_UADDO_CARRY) {
259 SDLoc Loc;
260 auto IntVT = EVT::getIntegerVT(Context, 8);
261 auto UnknownOp = DAG->getRegister(0, IntVT);
262 auto Mask_Zero = DAG->getConstant(0x28, Loc, IntVT);
263 auto Mask_One = DAG->getConstant(0x20, Loc, IntVT);
264 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask_Zero, UnknownOp);
265 N0 = DAG->getNode(ISD::OR, Loc, IntVT, Mask_One, N0);
266 auto N1 = DAG->getConstant(0x65, Loc, IntVT);
268 KnownBits Known;
270 auto UnknownBorrow = DAG->getRegister(1, IntVT);
271 auto OpUnknownBorrow =
272 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow);
273 // N0 = 0010?000
274 // N1 = 01100101
275 // B = ?
276 // =>
277 // Known.Zero = 01110000 (0x70)
278 // Known.One = 10000100 (0x84)
279 Known = DAG->computeKnownBits(OpUnknownBorrow);
280 EXPECT_EQ(Known.Zero, APInt(8, 0x70));
281 EXPECT_EQ(Known.One, APInt(8, 0x84));
283 auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT);
284 auto OpZeroBorrow =
285 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow);
286 // N0 = 0010?000
287 // N1 = 01100101
288 // B = 0
289 // =>
290 // Known.Zero = 01110010 (0x72)
291 // Known.One = 10000101 (0x85)
292 Known = DAG->computeKnownBits(OpZeroBorrow);
293 EXPECT_EQ(Known.Zero, APInt(8, 0x72));
294 EXPECT_EQ(Known.One, APInt(8, 0x85));
296 auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT);
297 auto OpOneBorrow =
298 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, OneBorrow);
299 // N0 = 0010?000
300 // N1 = 01100101
301 // B = 1
302 // =>
303 // Known.Zero = 01110001 (0x71)
304 // Known.One = 10000110 (0x86)
305 Known = DAG->computeKnownBits(OpOneBorrow);
306 EXPECT_EQ(Known.Zero, APInt(8, 0x71));
307 EXPECT_EQ(Known.One, APInt(8, 0x86));
310 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
311 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
312 SDLoc Loc;
313 auto IntVT = EVT::getIntegerVT(Context, 8);
314 auto N0 = DAG->getConstant(0x55, Loc, IntVT);
315 auto UnknownOp = DAG->getRegister(0, IntVT);
316 auto Mask = DAG->getConstant(0x2e, Loc, IntVT);
317 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
318 auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
319 // N0 = 01010101
320 // N1 = 00?0???0
321 // =>
322 // Known.One = 00000001 (0x1)
323 // Known.Zero = 10000000 (0x80)
324 KnownBits Known = DAG->computeKnownBits(Op);
325 EXPECT_EQ(Known.Zero, APInt(8, 0x80));
326 EXPECT_EQ(Known.One, APInt(8, 0x1));
329 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
330 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_USUBO_CARRY) {
331 SDLoc Loc;
332 auto IntVT = EVT::getIntegerVT(Context, 8);
333 auto N0 = DAG->getConstant(0x5a, Loc, IntVT);
334 auto UnknownOp = DAG->getRegister(0, IntVT); // ????????
335 auto Mask1_Zero = DAG->getConstant(0x8, Loc, IntVT); // 00001000
336 auto Mask1_One = DAG->getConstant(0x20, Loc, IntVT); // 00100000
337 // N1 = (???????? & 00001000) | 00100000 = 0010?000
338 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask1_Zero, UnknownOp);
339 N1 = DAG->getNode(ISD::OR, Loc, IntVT, Mask1_One, N1);
341 KnownBits Known;
343 auto UnknownBorrow = DAG->getRegister(1, IntVT);
344 auto OpUnknownBorrow =
345 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow);
346 // N0 = 01011010
347 // N1 = 0010?000
348 // B = ?
349 // =>
350 // Known.Zero = 11000100 (0xc4)
351 // Known.One = 00110000 (0x30)
352 Known = DAG->computeKnownBits(OpUnknownBorrow);
353 EXPECT_EQ(Known.Zero, APInt(8, 0xc4));
354 EXPECT_EQ(Known.One, APInt(8, 0x30));
356 auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT);
357 auto OpZeroBorrow =
358 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow);
359 // N0 = 01011010
360 // N1 = 0010?000
361 // B = 0
362 // =>
363 // Known.Zero = 11000101 (0xc5)
364 // Known.One = 00110010 (0x32)
365 Known = DAG->computeKnownBits(OpZeroBorrow);
366 EXPECT_EQ(Known.Zero, APInt(8, 0xc5));
367 EXPECT_EQ(Known.One, APInt(8, 0x32));
369 auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT);
370 auto OpOneBorrow =
371 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, OneBorrow);
372 // N0 = 01011010
373 // N1 = 0010?000
374 // B = 1
375 // =>
376 // Known.Zero = 11000110 (0xc6)
377 // Known.One = 00110001 (0x31)
378 Known = DAG->computeKnownBits(OpOneBorrow);
379 EXPECT_EQ(Known.Zero, APInt(8, 0xc6));
380 EXPECT_EQ(Known.One, APInt(8, 0x31));
383 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) {
384 TargetLowering TL(*TM);
386 SDLoc Loc;
387 auto IntVT = EVT::getIntegerVT(Context, 8);
388 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
389 // Create a BUILD_VECTOR
390 SDValue Op = DAG->getConstant(1, Loc, VecVT);
391 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
392 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
394 APInt UndefElts;
395 APInt DemandedElts;
396 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
398 // Width=16, Mask=3
399 DemandedElts = APInt(16, 3);
400 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
403 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) {
404 TargetLowering TL(*TM);
406 SDLoc Loc;
407 auto IntVT = EVT::getIntegerVT(Context, 8);
408 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
410 // Should create BUILD_VECTORs
411 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
412 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
413 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
414 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
416 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
418 APInt UndefElts;
419 APInt DemandedElts;
420 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
422 // Width=16, Mask=3
423 DemandedElts = APInt(16, 3);
424 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
427 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) {
428 TargetLowering TL(*TM);
430 SDLoc Loc;
431 auto IntVT = EVT::getIntegerVT(Context, 8);
432 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
433 // Create a SPLAT_VECTOR
434 SDValue Op = DAG->getConstant(1, Loc, VecVT);
435 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
436 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
438 APInt UndefElts;
439 APInt DemandedElts(1,1);
440 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
443 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) {
444 TargetLowering TL(*TM);
446 SDLoc Loc;
447 auto IntVT = EVT::getIntegerVT(Context, 8);
448 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
450 // Should create SPLAT_VECTORS
451 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
452 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
453 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
454 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
456 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
458 APInt UndefElts;
459 APInt DemandedElts(1, 1);
460 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
463 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) {
464 TargetLowering TL(*TM);
466 SDLoc Loc;
467 auto IntVT = EVT::getIntegerVT(Context, 8);
468 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
469 // Create a BUILD_VECTOR
470 SDValue Op = DAG->getConstant(1, Loc, VecVT);
471 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
473 int SplatIdx = -1;
474 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
475 EXPECT_EQ(SplatIdx, 0);
478 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) {
479 TargetLowering TL(*TM);
481 SDLoc Loc;
482 auto IntVT = EVT::getIntegerVT(Context, 8);
483 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
485 // Should create BUILD_VECTORs
486 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
487 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
488 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
489 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
491 int SplatIdx = -1;
492 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
493 EXPECT_EQ(SplatIdx, 0);
496 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) {
497 TargetLowering TL(*TM);
499 SDLoc Loc;
500 auto IntVT = EVT::getIntegerVT(Context, 8);
501 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
502 // Create a SPLAT_VECTOR
503 SDValue Op = DAG->getConstant(1, Loc, VecVT);
504 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
506 int SplatIdx = -1;
507 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
508 EXPECT_EQ(SplatIdx, 0);
511 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) {
512 TargetLowering TL(*TM);
514 SDLoc Loc;
515 auto IntVT = EVT::getIntegerVT(Context, 8);
516 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
518 // Should create SPLAT_VECTORS
519 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);
520 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);
521 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
522 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);
524 int SplatIdx = -1;
525 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
526 EXPECT_EQ(SplatIdx, 0);
529 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) {
530 TargetLowering TL(*TM);
532 SDLoc Loc;
533 unsigned NumElts = 16;
534 MVT IntVT = MVT::i8;
535 MVT VecVT = MVT::getVectorVT(IntVT, NumElts);
537 // Base scalar constants.
538 SDValue Val0 = DAG->getConstant(0, Loc, IntVT);
539 SDValue Val1 = DAG->getConstant(1, Loc, IntVT);
540 SDValue Val2 = DAG->getConstant(2, Loc, IntVT);
541 SDValue Val3 = DAG->getConstant(3, Loc, IntVT);
542 SDValue UndefVal = DAG->getUNDEF(IntVT);
544 // Build some repeating sequences.
545 SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123;
546 for(int I = 0; I != 4; ++I) {
547 Pattern1111.append(4, Val1);
548 Pattern1133.append(2, Val1);
549 Pattern1133.append(2, Val3);
550 Pattern0123.push_back(Val0);
551 Pattern0123.push_back(Val1);
552 Pattern0123.push_back(Val2);
553 Pattern0123.push_back(Val3);
556 // Build a non-pow2 repeating sequence.
557 SmallVector<SDValue, 16> Pattern022;
558 Pattern022.push_back(Val0);
559 Pattern022.append(2, Val2);
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);
570 // Build a non-repeating sequence.
571 SmallVector<SDValue, 16> Pattern1_3;
572 Pattern1_3.append(8, Val1);
573 Pattern1_3.append(8, Val3);
575 // Add some undefs to make it trickier.
576 Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal;
577 Pattern1133[0] = Pattern1133[2] = UndefVal;
579 auto *BV1111 =
580 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111));
581 auto *BV1133 =
582 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133));
583 auto *BV0123=
584 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123));
585 auto *BV022 =
586 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022));
587 auto *BV1_3 =
588 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3));
590 // Check for sequences.
591 SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3;
592 BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3;
594 EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111));
595 EXPECT_EQ(Undefs1111.count(), 3u);
596 EXPECT_EQ(Seq1111.size(), 1u);
597 EXPECT_EQ(Seq1111[0], Val1);
599 EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133));
600 EXPECT_EQ(Undefs1133.count(), 2u);
601 EXPECT_EQ(Seq1133.size(), 4u);
602 EXPECT_EQ(Seq1133[0], Val1);
603 EXPECT_EQ(Seq1133[1], Val1);
604 EXPECT_EQ(Seq1133[2], Val3);
605 EXPECT_EQ(Seq1133[3], Val3);
607 EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123));
608 EXPECT_EQ(Undefs0123.count(), 0u);
609 EXPECT_EQ(Seq0123.size(), 4u);
610 EXPECT_EQ(Seq0123[0], Val0);
611 EXPECT_EQ(Seq0123[1], Val1);
612 EXPECT_EQ(Seq0123[2], Val2);
613 EXPECT_EQ(Seq0123[3], Val3);
615 EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022));
616 EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3));
618 // Try again with DemandedElts masks.
619 APInt Mask1111_0 = APInt::getOneBitSet(NumElts, 0);
620 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111));
621 EXPECT_EQ(Undefs1111.count(), 0u);
622 EXPECT_EQ(Seq1111.size(), 1u);
623 EXPECT_EQ(Seq1111[0], Val1);
625 APInt Mask1111_1 = APInt::getOneBitSet(NumElts, 2);
626 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111));
627 EXPECT_EQ(Undefs1111.count(), 1u);
628 EXPECT_EQ(Seq1111.size(), 1u);
629 EXPECT_EQ(Seq1111[0], UndefVal);
631 APInt Mask0123 = APInt(NumElts, 0x7777);
632 EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123));
633 EXPECT_EQ(Undefs0123.count(), 0u);
634 EXPECT_EQ(Seq0123.size(), 4u);
635 EXPECT_EQ(Seq0123[0], Val0);
636 EXPECT_EQ(Seq0123[1], Val1);
637 EXPECT_EQ(Seq0123[2], Val2);
638 EXPECT_EQ(Seq0123[3], SDValue());
640 APInt Mask1_3 = APInt::getHighBitsSet(16, 8);
641 EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3));
642 EXPECT_EQ(Undefs1_3.count(), 0u);
643 EXPECT_EQ(Seq1_3.size(), 1u);
644 EXPECT_EQ(Seq1_3[0], Val3);
647 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) {
648 MVT VT = MVT::nxv4i64;
649 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
650 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
653 TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) {
654 MVT VT = MVT::nxv2i32;
655 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger);
656 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
659 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) {
660 MVT VT = MVT::nxv1f32;
661 EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector);
662 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
665 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) {
666 EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true);
667 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
668 EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context));
671 TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) {
672 EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true);
673 EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true);
675 EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector);
676 EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT);
679 TEST_F(AArch64SelectionDAGTest,
680 getTypeConversion_ScalarizeScalableEVT_nxv1f128) {
681 EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(1));
682 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector);
683 EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128);
686 TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) {
687 SDLoc Loc;
688 auto IntVT = EVT::getIntegerVT(Context, 8);
689 auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true);
691 // Should create SPLAT_VECTOR
692 SDValue Zero = DAG->getConstant(0, Loc, IntVT);
693 SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero);
694 EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR);
697 TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) {
698 SDLoc Loc;
699 EVT IntVT = EVT::getIntegerVT(Context, 8);
701 SDValue N0 = DAG->getConstant(0x42, Loc, IntVT);
702 SDValue N1 = DAG->getRegister(0, IntVT);
703 // Construct node to fill arbitrary ExtraInfo.
704 SDValue N2 = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
705 EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode()));
706 EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode()));
707 EXPECT_FALSE(DAG->getPCSections(N2.getNode()));
708 MDNode *MD = MDNode::get(Context, std::nullopt);
709 DAG->addHeapAllocSite(N2.getNode(), MD);
710 DAG->addNoMergeSiteInfo(N2.getNode(), true);
711 DAG->addPCSections(N2.getNode(), MD);
712 EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD);
713 EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode()));
714 EXPECT_EQ(DAG->getPCSections(N2.getNode()), MD);
716 SDValue Root = DAG->getNode(ISD::ADD, Loc, IntVT, N2, N2);
717 EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB);
718 // Create new node and check that ExtraInfo is propagated on RAUW.
719 SDValue New = DAG->getNode(ISD::ADD, Loc, IntVT, N1, N1);
720 EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode()));
721 EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode()));
722 EXPECT_FALSE(DAG->getPCSections(New.getNode()));
724 DAG->ReplaceAllUsesWith(N2, New);
725 EXPECT_EQ(Root->getOperand(0), New);
726 EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD);
727 EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode()));
728 EXPECT_EQ(DAG->getPCSections(New.getNode()), MD);
731 } // end namespace llvm