1 //===- llvm/unittest/CodeGen/AArch64SelectionDAGTest.cpp -------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/Analysis/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" 20 21 namespace llvm { 22 23 class AArch64SelectionDAGTest : public testing::Test { 24 protected: 25 static void SetUpTestCase() { 26 InitializeAllTargets(); 27 InitializeAllTargetMCs(); 28 } 29 30 void SetUp() override { 31 StringRef Assembly = "define void @f() { ret void }"; 32 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 return; 41 42 TargetOptions Options; 43 TM = std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>( 44 T->createTargetMachine("AArch64", "", "+sve", Options, None, None, 45 CodeGenOpt::Aggressive))); 46 if (!TM) 47 return; 48 49 SMDiagnostic SMError; 50 M = parseAssemblyString(Assembly, SMError, Context); 51 if (!M) 52 report_fatal_error(SMError.getMessage()); 53 M->setDataLayout(TM->createDataLayout()); 54 55 F = M->getFunction("f"); 56 if (!F) 57 report_fatal_error("F?"); 58 59 MachineModuleInfo MMI(TM.get()); 60 61 MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F), 0, 62 MMI); 63 64 DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOpt::None); 65 if (!DAG) 66 report_fatal_error("DAG?"); 67 OptimizationRemarkEmitter ORE(F); 68 DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr); 69 } 70 71 TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) { 72 return DAG->getTargetLoweringInfo().getTypeAction(Context, VT); 73 } 74 75 EVT getTypeToTransformTo(EVT VT) { 76 return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT); 77 } 78 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; 85 }; 86 87 TEST_F(AArch64SelectionDAGTest, computeKnownBits_ZERO_EXTEND_VECTOR_INREG) { 88 if (!TM) 89 return; 90 SDLoc Loc; 91 auto Int8VT = EVT::getIntegerVT(Context, 8); 92 auto Int16VT = EVT::getIntegerVT(Context, 16); 93 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4); 94 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2); 95 auto InVec = DAG->getConstant(0, Loc, InVecVT); 96 auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec); 97 auto DemandedElts = APInt(2, 3); 98 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts); 99 EXPECT_TRUE(Known.isZero()); 100 } 101 102 TEST_F(AArch64SelectionDAGTest, computeKnownBitsSVE_ZERO_EXTEND_VECTOR_INREG) { 103 if (!TM) 104 return; 105 SDLoc Loc; 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); 114 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()); 119 } 120 121 TEST_F(AArch64SelectionDAGTest, computeKnownBits_EXTRACT_SUBVECTOR) { 122 if (!TM) 123 return; 124 SDLoc Loc; 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()); 134 } 135 136 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG) { 137 if (!TM) 138 return; 139 SDLoc Loc; 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); 148 } 149 150 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBitsSVE_SIGN_EXTEND_VECTOR_INREG) { 151 if (!TM) 152 return; 153 SDLoc Loc; 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); 162 } 163 164 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_EXTRACT_SUBVECTOR) { 165 if (!TM) 166 return; 167 SDLoc Loc; 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); 176 } 177 178 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) { 179 if (!TM) 180 return; 181 182 TargetLowering TL(*TM); 183 184 SDLoc Loc; 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, 196 KnownZero, TLO), 197 false); 198 } 199 200 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) { 201 if (!TM) 202 return; 203 204 TargetLowering TL(*TM); 205 206 SDLoc Loc; 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); 213 214 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT); 215 SDValue Mask2V = DAG->getSplatBuildVector(InVecVT, Loc, Mask2S); 216 217 SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V); 218 // N0 = ?000?0?0 219 // Mask2V = 01010101 220 // => 221 // Known.Zero = 00100000 (0xAA) 222 KnownBits Known; 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)); 227 } 228 229 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) { 230 if (!TM) 231 return; 232 233 TargetLowering TL(*TM); 234 235 SDLoc Loc; 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); 242 243 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT); 244 SDValue Mask2V = DAG->getSplatVector(InVecVT, Loc, Mask2S); 245 246 SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V); 247 248 KnownBits Known; 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)); 253 } 254 255 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 256 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) { 257 if (!TM) 258 return; 259 SDLoc Loc; 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); 266 // N0 = ?000?0?0 267 // N1 = 01010101 268 // => 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)); 274 } 275 276 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 277 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) { 278 if (!TM) 279 return; 280 SDLoc Loc; 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); 287 // N0 = 01010101 288 // N1 = 00?0???0 289 // => 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)); 295 } 296 297 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) { 298 if (!TM) 299 return; 300 301 TargetLowering TL(*TM); 302 303 SDLoc Loc; 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)); 310 311 APInt UndefElts; 312 APInt DemandedElts; 313 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 314 315 // Width=16, Mask=3 316 DemandedElts = APInt(16, 3); 317 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 318 } 319 320 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) { 321 if (!TM) 322 return; 323 324 TargetLowering TL(*TM); 325 326 SDLoc Loc; 327 auto IntVT = EVT::getIntegerVT(Context, 8); 328 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 329 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); 335 336 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 337 338 APInt UndefElts; 339 APInt DemandedElts; 340 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 341 342 // Width=16, Mask=3 343 DemandedElts = APInt(16, 3); 344 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 345 } 346 347 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) { 348 if (!TM) 349 return; 350 351 TargetLowering TL(*TM); 352 353 SDLoc Loc; 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)); 360 361 APInt UndefElts; 362 APInt DemandedElts; 363 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 364 365 // Width=16, Mask=3. These bits should be ignored. 366 DemandedElts = APInt(16, 3); 367 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 368 } 369 370 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) { 371 if (!TM) 372 return; 373 374 TargetLowering TL(*TM); 375 376 SDLoc Loc; 377 auto IntVT = EVT::getIntegerVT(Context, 8); 378 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 379 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); 385 386 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 387 388 APInt UndefElts; 389 APInt DemandedElts; 390 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 391 392 // Width=16, Mask=3. These bits should be ignored. 393 DemandedElts = APInt(16, 3); 394 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 395 } 396 397 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) { 398 if (!TM) 399 return; 400 401 TargetLowering TL(*TM); 402 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 410 int SplatIdx = -1; 411 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 412 EXPECT_EQ(SplatIdx, 0); 413 } 414 415 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) { 416 if (!TM) 417 return; 418 419 TargetLowering TL(*TM); 420 421 SDLoc Loc; 422 auto IntVT = EVT::getIntegerVT(Context, 8); 423 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 424 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); 430 431 int SplatIdx = -1; 432 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 433 EXPECT_EQ(SplatIdx, 0); 434 } 435 436 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) { 437 if (!TM) 438 return; 439 440 TargetLowering TL(*TM); 441 442 SDLoc Loc; 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); 448 449 int SplatIdx = -1; 450 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 451 EXPECT_EQ(SplatIdx, 0); 452 } 453 454 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) { 455 if (!TM) 456 return; 457 458 TargetLowering TL(*TM); 459 460 SDLoc Loc; 461 auto IntVT = EVT::getIntegerVT(Context, 8); 462 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 463 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); 469 470 int SplatIdx = -1; 471 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 472 EXPECT_EQ(SplatIdx, 0); 473 } 474 475 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) { 476 if (!TM) 477 return; 478 479 TargetLowering TL(*TM); 480 481 SDLoc Loc; 482 unsigned NumElts = 16; 483 MVT IntVT = MVT::i8; 484 MVT VecVT = MVT::getVectorVT(IntVT, NumElts); 485 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); 492 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); 503 } 504 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); 518 519 // Build a non-repeating sequence. 520 SmallVector<SDValue, 16> Pattern1_3; 521 Pattern1_3.append(8, Val1); 522 Pattern1_3.append(8, Val3); 523 524 // Add some undefs to make it trickier. 525 Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal; 526 Pattern1133[0] = Pattern1133[2] = UndefVal; 527 528 auto *BV1111 = 529 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111)); 530 auto *BV1133 = 531 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133)); 532 auto *BV0123= 533 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123)); 534 auto *BV022 = 535 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022)); 536 auto *BV1_3 = 537 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3)); 538 539 // Check for sequences. 540 SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3; 541 BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3; 542 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); 547 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); 555 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); 563 564 EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022)); 565 EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3)); 566 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); 573 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); 579 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()); 588 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); 594 } 595 596 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) { 597 if (!TM) 598 return; 599 600 MVT VT = MVT::nxv4i64; 601 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector); 602 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 603 } 604 605 TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) { 606 if (!TM) 607 return; 608 609 MVT VT = MVT::nxv2i32; 610 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger); 611 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 612 } 613 614 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) { 615 if (!TM) 616 return; 617 618 MVT VT = MVT::nxv1f32; 619 EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector); 620 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 621 } 622 623 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) { 624 if (!TM) 625 return; 626 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)); 630 } 631 632 TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) { 633 if (!TM) 634 return; 635 636 EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true); 637 EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true); 638 639 EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector); 640 EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT); 641 } 642 643 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeEVT_nxv1f128) { 644 if (!TM) 645 return; 646 647 EVT FromVT = EVT::getVectorVT(Context, MVT::f128, 1, true); 648 EXPECT_DEATH(getTypeAction(FromVT), "Cannot legalize this vector"); 649 } 650 651 } // end namespace llvm 652