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/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" 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 GTEST_SKIP(); 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 GTEST_SKIP(); 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 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()); 98 } 99 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); 110 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()); 115 } 116 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()); 128 } 129 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); 140 } 141 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); 152 } 153 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); 164 } 165 166 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) { 167 TargetLowering TL(*TM); 168 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); 183 } 184 185 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) { 186 TargetLowering TL(*TM); 187 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); 195 196 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT); 197 SDValue Mask2V = DAG->getSplatBuildVector(InVecVT, Loc, Mask2S); 198 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)); 209 } 210 211 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) { 212 TargetLowering TL(*TM); 213 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); 221 222 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT); 223 SDValue Mask2V = DAG->getSplatVector(InVecVT, Loc, Mask2S); 224 225 SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V); 226 227 KnownBits Known; 228 APInt DemandedBits = APInt(8, 0xFF); 229 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false); 230 EXPECT_FALSE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO)); 231 EXPECT_EQ(Known.Zero, APInt(8, 0)); 232 } 233 234 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 235 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) { 236 SDLoc Loc; 237 auto IntVT = EVT::getIntegerVT(Context, 8); 238 auto UnknownOp = DAG->getRegister(0, IntVT); 239 auto Mask = DAG->getConstant(0x8A, Loc, IntVT); 240 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp); 241 auto N1 = DAG->getConstant(0x55, Loc, IntVT); 242 auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1); 243 // N0 = ?000?0?0 244 // N1 = 01010101 245 // => 246 // Known.One = 01010101 (0x55) 247 // Known.Zero = 00100000 (0x20) 248 KnownBits Known = DAG->computeKnownBits(Op); 249 EXPECT_EQ(Known.Zero, APInt(8, 0x20)); 250 EXPECT_EQ(Known.One, APInt(8, 0x55)); 251 } 252 253 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 254 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) { 255 SDLoc Loc; 256 auto IntVT = EVT::getIntegerVT(Context, 8); 257 auto N0 = DAG->getConstant(0x55, Loc, IntVT); 258 auto UnknownOp = DAG->getRegister(0, IntVT); 259 auto Mask = DAG->getConstant(0x2e, Loc, IntVT); 260 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp); 261 auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1); 262 // N0 = 01010101 263 // N1 = 00?0???0 264 // => 265 // Known.One = 00000001 (0x1) 266 // Known.Zero = 10000000 (0x80) 267 KnownBits Known = DAG->computeKnownBits(Op); 268 EXPECT_EQ(Known.Zero, APInt(8, 0x80)); 269 EXPECT_EQ(Known.One, APInt(8, 0x1)); 270 } 271 272 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) { 273 TargetLowering TL(*TM); 274 275 SDLoc Loc; 276 auto IntVT = EVT::getIntegerVT(Context, 8); 277 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 278 // Create a BUILD_VECTOR 279 SDValue Op = DAG->getConstant(1, Loc, VecVT); 280 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR); 281 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 282 283 APInt UndefElts; 284 APInt DemandedElts; 285 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 286 287 // Width=16, Mask=3 288 DemandedElts = APInt(16, 3); 289 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 290 } 291 292 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) { 293 TargetLowering TL(*TM); 294 295 SDLoc Loc; 296 auto IntVT = EVT::getIntegerVT(Context, 8); 297 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 298 299 // Should create BUILD_VECTORs 300 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 301 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 302 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR); 303 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 304 305 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 306 307 APInt UndefElts; 308 APInt DemandedElts; 309 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 310 311 // Width=16, Mask=3 312 DemandedElts = APInt(16, 3); 313 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 314 } 315 316 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) { 317 TargetLowering TL(*TM); 318 319 SDLoc Loc; 320 auto IntVT = EVT::getIntegerVT(Context, 8); 321 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 322 // Create a SPLAT_VECTOR 323 SDValue Op = DAG->getConstant(1, Loc, VecVT); 324 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR); 325 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 326 327 APInt UndefElts; 328 APInt DemandedElts; 329 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 330 331 // Width=16, Mask=3. These bits should be ignored. 332 DemandedElts = APInt(16, 3); 333 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 334 } 335 336 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) { 337 TargetLowering TL(*TM); 338 339 SDLoc Loc; 340 auto IntVT = EVT::getIntegerVT(Context, 8); 341 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 342 343 // Should create SPLAT_VECTORS 344 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 345 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 346 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR); 347 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 348 349 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 350 351 APInt UndefElts; 352 APInt DemandedElts; 353 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 354 355 // Width=16, Mask=3. These bits should be ignored. 356 DemandedElts = APInt(16, 3); 357 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 358 } 359 360 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) { 361 TargetLowering TL(*TM); 362 363 SDLoc Loc; 364 auto IntVT = EVT::getIntegerVT(Context, 8); 365 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 366 // Create a BUILD_VECTOR 367 SDValue Op = DAG->getConstant(1, Loc, VecVT); 368 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR); 369 370 int SplatIdx = -1; 371 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 372 EXPECT_EQ(SplatIdx, 0); 373 } 374 375 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) { 376 TargetLowering TL(*TM); 377 378 SDLoc Loc; 379 auto IntVT = EVT::getIntegerVT(Context, 8); 380 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 381 382 // Should create BUILD_VECTORs 383 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 384 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 385 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR); 386 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 387 388 int SplatIdx = -1; 389 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 390 EXPECT_EQ(SplatIdx, 0); 391 } 392 393 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) { 394 TargetLowering TL(*TM); 395 396 SDLoc Loc; 397 auto IntVT = EVT::getIntegerVT(Context, 8); 398 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 399 // Create a SPLAT_VECTOR 400 SDValue Op = DAG->getConstant(1, Loc, VecVT); 401 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR); 402 403 int SplatIdx = -1; 404 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 405 EXPECT_EQ(SplatIdx, 0); 406 } 407 408 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) { 409 TargetLowering TL(*TM); 410 411 SDLoc Loc; 412 auto IntVT = EVT::getIntegerVT(Context, 8); 413 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 414 415 // Should create SPLAT_VECTORS 416 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 417 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 418 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR); 419 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 420 421 int SplatIdx = -1; 422 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 423 EXPECT_EQ(SplatIdx, 0); 424 } 425 426 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) { 427 TargetLowering TL(*TM); 428 429 SDLoc Loc; 430 unsigned NumElts = 16; 431 MVT IntVT = MVT::i8; 432 MVT VecVT = MVT::getVectorVT(IntVT, NumElts); 433 434 // Base scalar constants. 435 SDValue Val0 = DAG->getConstant(0, Loc, IntVT); 436 SDValue Val1 = DAG->getConstant(1, Loc, IntVT); 437 SDValue Val2 = DAG->getConstant(2, Loc, IntVT); 438 SDValue Val3 = DAG->getConstant(3, Loc, IntVT); 439 SDValue UndefVal = DAG->getUNDEF(IntVT); 440 441 // Build some repeating sequences. 442 SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123; 443 for(int I = 0; I != 4; ++I) { 444 Pattern1111.append(4, Val1); 445 Pattern1133.append(2, Val1); 446 Pattern1133.append(2, Val3); 447 Pattern0123.push_back(Val0); 448 Pattern0123.push_back(Val1); 449 Pattern0123.push_back(Val2); 450 Pattern0123.push_back(Val3); 451 } 452 453 // Build a non-pow2 repeating sequence. 454 SmallVector<SDValue, 16> Pattern022; 455 Pattern022.push_back(Val0); 456 Pattern022.append(2, Val2); 457 Pattern022.push_back(Val0); 458 Pattern022.append(2, Val2); 459 Pattern022.push_back(Val0); 460 Pattern022.append(2, Val2); 461 Pattern022.push_back(Val0); 462 Pattern022.append(2, Val2); 463 Pattern022.push_back(Val0); 464 Pattern022.append(2, Val2); 465 Pattern022.push_back(Val0); 466 467 // Build a non-repeating sequence. 468 SmallVector<SDValue, 16> Pattern1_3; 469 Pattern1_3.append(8, Val1); 470 Pattern1_3.append(8, Val3); 471 472 // Add some undefs to make it trickier. 473 Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal; 474 Pattern1133[0] = Pattern1133[2] = UndefVal; 475 476 auto *BV1111 = 477 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111)); 478 auto *BV1133 = 479 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133)); 480 auto *BV0123= 481 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123)); 482 auto *BV022 = 483 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022)); 484 auto *BV1_3 = 485 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3)); 486 487 // Check for sequences. 488 SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3; 489 BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3; 490 491 EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111)); 492 EXPECT_EQ(Undefs1111.count(), 3u); 493 EXPECT_EQ(Seq1111.size(), 1u); 494 EXPECT_EQ(Seq1111[0], Val1); 495 496 EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133)); 497 EXPECT_EQ(Undefs1133.count(), 2u); 498 EXPECT_EQ(Seq1133.size(), 4u); 499 EXPECT_EQ(Seq1133[0], Val1); 500 EXPECT_EQ(Seq1133[1], Val1); 501 EXPECT_EQ(Seq1133[2], Val3); 502 EXPECT_EQ(Seq1133[3], Val3); 503 504 EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123)); 505 EXPECT_EQ(Undefs0123.count(), 0u); 506 EXPECT_EQ(Seq0123.size(), 4u); 507 EXPECT_EQ(Seq0123[0], Val0); 508 EXPECT_EQ(Seq0123[1], Val1); 509 EXPECT_EQ(Seq0123[2], Val2); 510 EXPECT_EQ(Seq0123[3], Val3); 511 512 EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022)); 513 EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3)); 514 515 // Try again with DemandedElts masks. 516 APInt Mask1111_0 = APInt::getOneBitSet(NumElts, 0); 517 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111)); 518 EXPECT_EQ(Undefs1111.count(), 0u); 519 EXPECT_EQ(Seq1111.size(), 1u); 520 EXPECT_EQ(Seq1111[0], Val1); 521 522 APInt Mask1111_1 = APInt::getOneBitSet(NumElts, 2); 523 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111)); 524 EXPECT_EQ(Undefs1111.count(), 1u); 525 EXPECT_EQ(Seq1111.size(), 1u); 526 EXPECT_EQ(Seq1111[0], UndefVal); 527 528 APInt Mask0123 = APInt(NumElts, 0x7777); 529 EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123)); 530 EXPECT_EQ(Undefs0123.count(), 0u); 531 EXPECT_EQ(Seq0123.size(), 4u); 532 EXPECT_EQ(Seq0123[0], Val0); 533 EXPECT_EQ(Seq0123[1], Val1); 534 EXPECT_EQ(Seq0123[2], Val2); 535 EXPECT_EQ(Seq0123[3], SDValue()); 536 537 APInt Mask1_3 = APInt::getHighBitsSet(16, 8); 538 EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3)); 539 EXPECT_EQ(Undefs1_3.count(), 0u); 540 EXPECT_EQ(Seq1_3.size(), 1u); 541 EXPECT_EQ(Seq1_3[0], Val3); 542 } 543 544 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) { 545 MVT VT = MVT::nxv4i64; 546 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector); 547 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 548 } 549 550 TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) { 551 MVT VT = MVT::nxv2i32; 552 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger); 553 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 554 } 555 556 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) { 557 MVT VT = MVT::nxv1f32; 558 EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector); 559 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 560 } 561 562 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) { 563 EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true); 564 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector); 565 EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context)); 566 } 567 568 TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) { 569 EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true); 570 EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true); 571 572 EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector); 573 EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT); 574 } 575 576 TEST_F(AArch64SelectionDAGTest, 577 getTypeConversion_ScalarizeScalableEVT_nxv1f128) { 578 EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(1)); 579 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector); 580 EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128); 581 } 582 583 TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) { 584 SDLoc Loc; 585 auto IntVT = EVT::getIntegerVT(Context, 8); 586 auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true); 587 588 // Should create SPLAT_VECTOR 589 SDValue Zero = DAG->getConstant(0, Loc, IntVT); 590 SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero); 591 EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR); 592 } 593 594 TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) { 595 SDLoc Loc; 596 EVT IntVT = EVT::getIntegerVT(Context, 8); 597 598 SDValue N0 = DAG->getConstant(0x42, Loc, IntVT); 599 SDValue N1 = DAG->getRegister(0, IntVT); 600 // Construct node to fill arbitrary ExtraInfo. 601 SDValue N2 = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1); 602 EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode())); 603 EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode())); 604 MDNode *MD = MDNode::get(Context, None); 605 DAG->addHeapAllocSite(N2.getNode(), MD); 606 DAG->addNoMergeSiteInfo(N2.getNode(), true); 607 EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD); 608 EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode())); 609 610 SDValue Root = DAG->getNode(ISD::ADD, Loc, IntVT, N2, N2); 611 EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB); 612 // Create new node and check that ExtraInfo is propagated on RAUW. 613 SDValue New = DAG->getNode(ISD::ADD, Loc, IntVT, N1, N1); 614 EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode())); 615 EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode())); 616 617 DAG->ReplaceAllUsesWith(N2, New); 618 EXPECT_EQ(Root->getOperand(0), New); 619 EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD); 620 EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode())); 621 } 622 623 } // end namespace llvm 624