[flang][MLIR] Support delayed privatization for `wsloop` (PFT -> MLIR) (#118271)
[llvm-project.git] / llvm / unittests / CodeGen / AArch64SelectionDAGTest.cpp
blobb00e8dc4424ab5e662e8f5c9e3d9dd72679f9717
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 "../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"
25 namespace llvm {
27 class AArch64SelectionDAGTest : public testing::Test {
28 protected:
29 static void SetUpTestCase() {
30 InitializeAllTargets();
31 InitializeAllTargetMCs();
34 void SetUp() override {
35 StringRef Assembly = "define void @f() { ret void }";
37 Triple TargetTriple("aarch64--");
38 std::string Error;
39 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
40 // FIXME: These tests do not depend on AArch64 specifically, but we have to
41 // initialize a target. A skeleton Target for unittests would allow us to
42 // always run these tests.
43 if (!T)
44 GTEST_SKIP();
46 TargetOptions Options;
47 TM = std::unique_ptr<TargetMachine>(
48 T->createTargetMachine("AArch64", "", "+sve", Options, std::nullopt,
49 std::nullopt, CodeGenOptLevel::Aggressive));
50 if (!TM)
51 GTEST_SKIP();
53 SMDiagnostic SMError;
54 M = parseAssemblyString(Assembly, SMError, Context);
55 if (!M)
56 report_fatal_error(SMError.getMessage());
57 M->setDataLayout(TM->createDataLayout());
59 F = M->getFunction("f");
60 if (!F)
61 report_fatal_error("F?");
63 MachineModuleInfo MMI(TM.get());
65 MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F),
66 MMI.getContext(), 0);
68 DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None);
69 if (!DAG)
70 report_fatal_error("DAG?");
71 OptimizationRemarkEmitter ORE(F);
72 DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, MMI,
73 nullptr);
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);
84 LLVMContext Context;
85 std::unique_ptr<TargetMachine> TM;
86 std::unique_ptr<Module> M;
87 Function *F;
88 std::unique_ptr<MachineFunction> MF;
89 std::unique_ptr<SelectionDAG> DAG;
92 TEST_F(AArch64SelectionDAGTest, computeKnownBits_ZERO_EXTEND_VECTOR_INREG) {
93 SDLoc Loc;
94 auto Int8VT = EVT::getIntegerVT(Context, 8);
95 auto Int16VT = EVT::getIntegerVT(Context, 16);
96 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);
97 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);
98 auto InVec = DAG->getConstant(0, Loc, InVecVT);
99 auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
100 auto DemandedElts = APInt(2, 3);
101 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
102 EXPECT_TRUE(Known.isZero());
105 TEST_F(AArch64SelectionDAGTest, computeKnownBitsSVE_ZERO_EXTEND_VECTOR_INREG) {
106 SDLoc Loc;
107 auto Int8VT = EVT::getIntegerVT(Context, 8);
108 auto Int16VT = EVT::getIntegerVT(Context, 16);
109 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, true);
110 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, true);
111 auto InVec = DAG->getConstant(0, Loc, InVecVT);
112 auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
113 auto DemandedElts = APInt(2, 3);
114 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
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) {
123 SDLoc Loc;
124 auto IntVT = EVT::getIntegerVT(Context, 8);
125 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
126 auto IdxVT = EVT::getIntegerVT(Context, 64);
127 auto Vec = DAG->getConstant(0, Loc, VecVT);
128 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
129 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
130 auto DemandedElts = APInt(3, 7);
131 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
132 EXPECT_TRUE(Known.isZero());
135 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG) {
136 SDLoc Loc;
137 auto Int8VT = EVT::getIntegerVT(Context, 8);
138 auto Int16VT = EVT::getIntegerVT(Context, 16);
139 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);
140 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);
141 auto InVec = DAG->getConstant(1, Loc, InVecVT);
142 auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
143 auto DemandedElts = APInt(2, 3);
144 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 15u);
147 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBitsSVE_SIGN_EXTEND_VECTOR_INREG) {
148 SDLoc Loc;
149 auto Int8VT = EVT::getIntegerVT(Context, 8);
150 auto Int16VT = EVT::getIntegerVT(Context, 16);
151 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, /*IsScalable=*/true);
152 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, /*IsScalable=*/true);
153 auto InVec = DAG->getConstant(1, Loc, InVecVT);
154 auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);
155 auto DemandedElts = APInt(2, 3);
156 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 1u);
159 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_EXTRACT_SUBVECTOR) {
160 SDLoc Loc;
161 auto IntVT = EVT::getIntegerVT(Context, 8);
162 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
163 auto IdxVT = EVT::getIntegerVT(Context, 64);
164 auto Vec = DAG->getConstant(1, Loc, VecVT);
165 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
166 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
167 auto DemandedElts = APInt(3, 7);
168 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 7u);
171 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_VASHR) {
172 SDLoc Loc;
173 auto VecVT = MVT::v8i8;
174 auto Shift = DAG->getConstant(4, Loc, MVT::i32);
175 auto Vec0 = DAG->getConstant(1, Loc, VecVT);
176 auto Op1 = DAG->getNode(AArch64ISD::VASHR, Loc, VecVT, Vec0, Shift);
177 EXPECT_EQ(DAG->ComputeNumSignBits(Op1), 8u);
178 auto VecA = DAG->getConstant(0xaa, Loc, VecVT);
179 auto Op2 = DAG->getNode(AArch64ISD::VASHR, Loc, VecVT, VecA, Shift);
180 EXPECT_EQ(DAG->ComputeNumSignBits(Op2), 5u);
183 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) {
184 TargetLowering TL(*TM);
186 SDLoc Loc;
187 auto IntVT = EVT::getIntegerVT(Context, 8);
188 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);
189 auto IdxVT = EVT::getIntegerVT(Context, 64);
190 auto Vec = DAG->getConstant(1, Loc, VecVT);
191 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);
192 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);
193 auto DemandedElts = APInt(3, 7);
194 auto KnownUndef = APInt(3, 0);
195 auto KnownZero = APInt(3, 0);
196 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
197 EXPECT_EQ(TL.SimplifyDemandedVectorElts(Op, DemandedElts, KnownUndef,
198 KnownZero, TLO),
199 false);
202 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) {
203 TargetLowering TL(*TM);
205 SDLoc Loc;
206 auto Int8VT = EVT::getIntegerVT(Context, 8);
207 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16);
208 SDValue UnknownOp = DAG->getRegister(0, InVecVT);
209 SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);
210 SDValue Mask1V = DAG->getSplatBuildVector(InVecVT, Loc, Mask1S);
211 SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);
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);
217 // N0 = ?000?0?0
218 // Mask2V = 01010101
219 // =>
220 // Known.Zero = 00100000 (0xAA)
221 KnownBits Known;
222 APInt DemandedBits = APInt(8, 0xFF);
223 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
224 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
225 EXPECT_EQ(Known.Zero, APInt(8, 0xAA));
228 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) {
229 TargetLowering TL(*TM);
231 SDLoc Loc;
232 auto Int8VT = EVT::getIntegerVT(Context, 8);
233 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16, /*IsScalable=*/true);
234 SDValue UnknownOp = DAG->getRegister(0, InVecVT);
235 SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);
236 SDValue Mask1V = DAG->getSplatVector(InVecVT, Loc, Mask1S);
237 SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);
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);
244 // N0 = ?000?0?0
245 // Mask2V = 01010101
246 // =>
247 // Known.Zero = 00100000 (0xAA)
248 KnownBits Known;
249 APInt DemandedBits = APInt(8, 0xFF);
250 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
251 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
252 EXPECT_EQ(Known.Zero, APInt(8, 0xAA));
255 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
256 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {
257 SDLoc Loc;
258 auto IntVT = EVT::getIntegerVT(Context, 8);
259 auto UnknownOp = DAG->getRegister(0, IntVT);
260 auto Mask = DAG->getConstant(0x8A, Loc, IntVT);
261 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
262 auto N1 = DAG->getConstant(0x55, Loc, IntVT);
263 auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1);
264 // N0 = ?000?0?0
265 // N1 = 01010101
266 // =>
267 // Known.One = 01010101 (0x55)
268 // Known.Zero = 00100000 (0x20)
269 KnownBits Known = DAG->computeKnownBits(Op);
270 EXPECT_EQ(Known.Zero, APInt(8, 0x20));
271 EXPECT_EQ(Known.One, APInt(8, 0x55));
274 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
275 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_UADDO_CARRY) {
276 SDLoc Loc;
277 auto IntVT = EVT::getIntegerVT(Context, 8);
278 auto UnknownOp = DAG->getRegister(0, IntVT);
279 auto Mask_Zero = DAG->getConstant(0x28, Loc, IntVT);
280 auto Mask_One = DAG->getConstant(0x20, Loc, IntVT);
281 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask_Zero, UnknownOp);
282 N0 = DAG->getNode(ISD::OR, Loc, IntVT, Mask_One, N0);
283 auto N1 = DAG->getConstant(0x65, Loc, IntVT);
285 KnownBits Known;
287 auto UnknownBorrow = DAG->getRegister(1, IntVT);
288 auto OpUnknownBorrow =
289 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow);
290 // N0 = 0010?000
291 // N1 = 01100101
292 // B = ?
293 // =>
294 // Known.Zero = 01110000 (0x70)
295 // Known.One = 10000100 (0x84)
296 Known = DAG->computeKnownBits(OpUnknownBorrow);
297 EXPECT_EQ(Known.Zero, APInt(8, 0x70));
298 EXPECT_EQ(Known.One, APInt(8, 0x84));
300 auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT);
301 auto OpZeroBorrow =
302 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow);
303 // N0 = 0010?000
304 // N1 = 01100101
305 // B = 0
306 // =>
307 // Known.Zero = 01110010 (0x72)
308 // Known.One = 10000101 (0x85)
309 Known = DAG->computeKnownBits(OpZeroBorrow);
310 EXPECT_EQ(Known.Zero, APInt(8, 0x72));
311 EXPECT_EQ(Known.One, APInt(8, 0x85));
313 auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT);
314 auto OpOneBorrow =
315 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, OneBorrow);
316 // N0 = 0010?000
317 // N1 = 01100101
318 // B = 1
319 // =>
320 // Known.Zero = 01110001 (0x71)
321 // Known.One = 10000110 (0x86)
322 Known = DAG->computeKnownBits(OpOneBorrow);
323 EXPECT_EQ(Known.Zero, APInt(8, 0x71));
324 EXPECT_EQ(Known.One, APInt(8, 0x86));
327 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
328 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
329 SDLoc Loc;
330 auto IntVT = EVT::getIntegerVT(Context, 8);
331 auto N0 = DAG->getConstant(0x55, Loc, IntVT);
332 auto UnknownOp = DAG->getRegister(0, IntVT);
333 auto Mask = DAG->getConstant(0x2e, Loc, IntVT);
334 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
335 auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
336 // N0 = 01010101
337 // N1 = 00?0???0
338 // =>
339 // Known.One = 00000001 (0x1)
340 // Known.Zero = 10000000 (0x80)
341 KnownBits Known = DAG->computeKnownBits(Op);
342 EXPECT_EQ(Known.Zero, APInt(8, 0x80));
343 EXPECT_EQ(Known.One, APInt(8, 0x1));
346 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
347 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_USUBO_CARRY) {
348 SDLoc Loc;
349 auto IntVT = EVT::getIntegerVT(Context, 8);
350 auto N0 = DAG->getConstant(0x5a, Loc, IntVT);
351 auto UnknownOp = DAG->getRegister(0, IntVT); // ????????
352 auto Mask1_Zero = DAG->getConstant(0x8, Loc, IntVT); // 00001000
353 auto Mask1_One = DAG->getConstant(0x20, Loc, IntVT); // 00100000
354 // N1 = (???????? & 00001000) | 00100000 = 0010?000
355 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask1_Zero, UnknownOp);
356 N1 = DAG->getNode(ISD::OR, Loc, IntVT, Mask1_One, N1);
358 KnownBits Known;
360 auto UnknownBorrow = DAG->getRegister(1, IntVT);
361 auto OpUnknownBorrow =
362 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow);
363 // N0 = 01011010
364 // N1 = 0010?000
365 // B = ?
366 // =>
367 // Known.Zero = 11000100 (0xc4)
368 // Known.One = 00110000 (0x30)
369 Known = DAG->computeKnownBits(OpUnknownBorrow);
370 EXPECT_EQ(Known.Zero, APInt(8, 0xc4));
371 EXPECT_EQ(Known.One, APInt(8, 0x30));
373 auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT);
374 auto OpZeroBorrow =
375 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow);
376 // N0 = 01011010
377 // N1 = 0010?000
378 // B = 0
379 // =>
380 // Known.Zero = 11000101 (0xc5)
381 // Known.One = 00110010 (0x32)
382 Known = DAG->computeKnownBits(OpZeroBorrow);
383 EXPECT_EQ(Known.Zero, APInt(8, 0xc5));
384 EXPECT_EQ(Known.One, APInt(8, 0x32));
386 auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT);
387 auto OpOneBorrow =
388 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, OneBorrow);
389 // N0 = 01011010
390 // N1 = 0010?000
391 // B = 1
392 // =>
393 // Known.Zero = 11000110 (0xc6)
394 // Known.One = 00110001 (0x31)
395 Known = DAG->computeKnownBits(OpOneBorrow);
396 EXPECT_EQ(Known.Zero, APInt(8, 0xc6));
397 EXPECT_EQ(Known.One, APInt(8, 0x31));
400 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) {
401 TargetLowering TL(*TM);
403 SDLoc Loc;
404 auto IntVT = EVT::getIntegerVT(Context, 8);
405 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
406 // Create a BUILD_VECTOR
407 SDValue Op = DAG->getConstant(1, Loc, VecVT);
408 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
409 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
411 APInt UndefElts;
412 APInt DemandedElts;
413 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
415 // Width=16, Mask=3
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);
423 SDLoc Loc;
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));
435 APInt UndefElts;
436 APInt DemandedElts;
437 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
439 // Width=16, Mask=3
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);
447 SDLoc Loc;
448 auto IntVT = EVT::getIntegerVT(Context, 8);
449 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
450 // Create a SPLAT_VECTOR
451 SDValue Op = DAG->getConstant(1, Loc, VecVT);
452 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
453 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
455 APInt UndefElts;
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);
463 SDLoc Loc;
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));
475 APInt UndefElts;
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);
483 SDLoc Loc;
484 auto IntVT = EVT::getIntegerVT(Context, 8);
485 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);
486 // Create a BUILD_VECTOR
487 SDValue Op = DAG->getConstant(1, Loc, VecVT);
488 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
490 int SplatIdx = -1;
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);
498 SDLoc Loc;
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);
508 int SplatIdx = -1;
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);
516 SDLoc Loc;
517 auto IntVT = EVT::getIntegerVT(Context, 8);
518 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);
519 // Create a SPLAT_VECTOR
520 SDValue Op = DAG->getConstant(1, Loc, VecVT);
521 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
523 int SplatIdx = -1;
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);
531 SDLoc Loc;
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);
541 int SplatIdx = -1;
542 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
543 EXPECT_EQ(SplatIdx, 0);
546 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) {
547 TargetLowering TL(*TM);
549 SDLoc Loc;
550 unsigned NumElts = 16;
551 MVT IntVT = MVT::i8;
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;
596 auto *BV1111 =
597 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111));
598 auto *BV1133 =
599 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133));
600 auto *BV0123=
601 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123));
602 auto *BV022 =
603 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022));
604 auto *BV1_3 =
605 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3));
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) {
704 SDLoc Loc;
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) {
715 SDLoc Loc;
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) {
749 SDLoc Loc;
750 auto Int8VT = EVT::getIntegerVT(Context, 8);
751 auto Int32VT = EVT::getIntegerVT(Context, 32);
752 auto Int64VT = EVT::getIntegerVT(Context, 64);
753 auto Ptr = DAG->getConstant(0, Loc, Int64VT);
754 auto PtrInfo =
755 MachinePointerInfo::getFixedStack(DAG->getMachineFunction(), 0);
756 AAMDNodes AA;
757 MDBuilder MDHelper(*DAG->getContext());
758 MDNode *Range = MDHelper.createRange(APInt(8, 0), APInt(8, 2));
759 MachineMemOperand *MMO = DAG->getMachineFunction().getMachineMemOperand(
760 PtrInfo, MachineMemOperand::MOLoad, 8, Align(8), AA, Range);
762 auto ALoad = DAG->getExtLoad(ISD::EXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
763 Ptr, Int8VT, MMO);
764 KnownBits Known = DAG->computeKnownBits(ALoad);
765 EXPECT_EQ(Known.Zero, APInt(32, 0xfe));
766 EXPECT_EQ(Known.One, APInt(32, 0));
768 auto ZLoad = DAG->getExtLoad(ISD::ZEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
769 Ptr, Int8VT, MMO);
770 Known = DAG->computeKnownBits(ZLoad);
771 EXPECT_EQ(Known.Zero, APInt(32, 0xfffffffe));
772 EXPECT_EQ(Known.One, APInt(32, 0));
774 auto SLoad = DAG->getExtLoad(ISD::SEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
775 Ptr, Int8VT, MMO);
776 Known = DAG->computeKnownBits(SLoad);
777 EXPECT_EQ(Known.Zero, APInt(32, 0xfffffffe));
778 EXPECT_EQ(Known.One, APInt(32, 0));
781 TEST_F(AArch64SelectionDAGTest, computeKnownBits_extload_knownnegative) {
782 SDLoc Loc;
783 auto Int8VT = EVT::getIntegerVT(Context, 8);
784 auto Int32VT = EVT::getIntegerVT(Context, 32);
785 auto Int64VT = EVT::getIntegerVT(Context, 64);
786 auto Ptr = DAG->getConstant(0, Loc, Int64VT);
787 auto PtrInfo =
788 MachinePointerInfo::getFixedStack(DAG->getMachineFunction(), 0);
789 AAMDNodes AA;
790 MDBuilder MDHelper(*DAG->getContext());
791 MDNode *Range = MDHelper.createRange(APInt(8, 0xf0), APInt(8, 0xff));
792 MachineMemOperand *MMO = DAG->getMachineFunction().getMachineMemOperand(
793 PtrInfo, MachineMemOperand::MOLoad, 8, Align(8), AA, Range);
795 auto ALoad = DAG->getExtLoad(ISD::EXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
796 Ptr, Int8VT, MMO);
797 KnownBits Known = DAG->computeKnownBits(ALoad);
798 EXPECT_EQ(Known.Zero, APInt(32, 0));
799 EXPECT_EQ(Known.One, APInt(32, 0xf0));
801 auto ZLoad = DAG->getExtLoad(ISD::ZEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
802 Ptr, Int8VT, MMO);
803 Known = DAG->computeKnownBits(ZLoad);
804 EXPECT_EQ(Known.Zero, APInt(32, 0xffffff00));
805 EXPECT_EQ(Known.One, APInt(32, 0x000000f0));
807 auto SLoad = DAG->getExtLoad(ISD::SEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),
808 Ptr, Int8VT, MMO);
809 Known = DAG->computeKnownBits(SLoad);
810 EXPECT_EQ(Known.Zero, APInt(32, 0));
811 EXPECT_EQ(Known.One, APInt(32, 0xfffffff0));
814 TEST_F(AArch64SelectionDAGTest,
815 computeKnownBits_AVGFLOORU_AVGFLOORS_AVGCEILU_AVGCEILS) {
816 SDLoc Loc;
817 auto Int8VT = EVT::getIntegerVT(Context, 8);
818 auto Int16VT = EVT::getIntegerVT(Context, 16);
819 auto Int8Vec8VT = EVT::getVectorVT(Context, Int8VT, 8);
820 auto Int16Vec8VT = EVT::getVectorVT(Context, Int16VT, 8);
822 SDValue UnknownOp0 = DAG->getRegister(0, Int8Vec8VT);
823 SDValue UnknownOp1 = DAG->getRegister(1, Int8Vec8VT);
825 SDValue ZextOp0 =
826 DAG->getNode(ISD::ZERO_EXTEND, Loc, Int16Vec8VT, UnknownOp0);
827 SDValue ZextOp1 =
828 DAG->getNode(ISD::ZERO_EXTEND, Loc, Int16Vec8VT, UnknownOp1);
829 // ZextOp0 = 00000000????????
830 // ZextOp1 = 00000000????????
831 // => (for all AVG* instructions)
832 // Known.Zero = 1111111100000000 (0xFF00)
833 // Known.One = 0000000000000000 (0x0000)
834 auto Zeroes = APInt(16, 0xFF00);
835 auto Ones = APInt(16, 0x0000);
837 SDValue AVGFLOORU =
838 DAG->getNode(ISD::AVGFLOORU, Loc, Int16Vec8VT, ZextOp0, ZextOp1);
839 KnownBits KnownAVGFLOORU = DAG->computeKnownBits(AVGFLOORU);
840 EXPECT_EQ(KnownAVGFLOORU.Zero, Zeroes);
841 EXPECT_EQ(KnownAVGFLOORU.One, Ones);
843 SDValue AVGFLOORS =
844 DAG->getNode(ISD::AVGFLOORS, Loc, Int16Vec8VT, ZextOp0, ZextOp1);
845 KnownBits KnownAVGFLOORS = DAG->computeKnownBits(AVGFLOORS);
846 EXPECT_EQ(KnownAVGFLOORS.Zero, Zeroes);
847 EXPECT_EQ(KnownAVGFLOORS.One, Ones);
849 SDValue AVGCEILU =
850 DAG->getNode(ISD::AVGCEILU, Loc, Int16Vec8VT, ZextOp0, ZextOp1);
851 KnownBits KnownAVGCEILU = DAG->computeKnownBits(AVGCEILU);
852 EXPECT_EQ(KnownAVGCEILU.Zero, Zeroes);
853 EXPECT_EQ(KnownAVGCEILU.One, Ones);
855 SDValue AVGCEILS =
856 DAG->getNode(ISD::AVGCEILS, Loc, Int16Vec8VT, ZextOp0, ZextOp1);
857 KnownBits KnownAVGCEILS = DAG->computeKnownBits(AVGCEILS);
858 EXPECT_EQ(KnownAVGCEILS.Zero, Zeroes);
859 EXPECT_EQ(KnownAVGCEILS.One, Ones);
862 } // end namespace llvm