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, std::nullopt, 45 std::nullopt, 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(1,1); 329 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 330 } 331 332 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) { 333 TargetLowering TL(*TM); 334 335 SDLoc Loc; 336 auto IntVT = EVT::getIntegerVT(Context, 8); 337 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 338 339 // Should create SPLAT_VECTORS 340 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 341 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 342 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR); 343 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 344 345 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 346 347 APInt UndefElts; 348 APInt DemandedElts(1, 1); 349 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 350 } 351 352 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) { 353 TargetLowering TL(*TM); 354 355 SDLoc Loc; 356 auto IntVT = EVT::getIntegerVT(Context, 8); 357 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 358 // Create a BUILD_VECTOR 359 SDValue Op = DAG->getConstant(1, Loc, VecVT); 360 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR); 361 362 int SplatIdx = -1; 363 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 364 EXPECT_EQ(SplatIdx, 0); 365 } 366 367 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) { 368 TargetLowering TL(*TM); 369 370 SDLoc Loc; 371 auto IntVT = EVT::getIntegerVT(Context, 8); 372 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 373 374 // Should create BUILD_VECTORs 375 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 376 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 377 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR); 378 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 379 380 int SplatIdx = -1; 381 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 382 EXPECT_EQ(SplatIdx, 0); 383 } 384 385 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) { 386 TargetLowering TL(*TM); 387 388 SDLoc Loc; 389 auto IntVT = EVT::getIntegerVT(Context, 8); 390 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 391 // Create a SPLAT_VECTOR 392 SDValue Op = DAG->getConstant(1, Loc, VecVT); 393 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR); 394 395 int SplatIdx = -1; 396 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 397 EXPECT_EQ(SplatIdx, 0); 398 } 399 400 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) { 401 TargetLowering TL(*TM); 402 403 SDLoc Loc; 404 auto IntVT = EVT::getIntegerVT(Context, 8); 405 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 406 407 // Should create SPLAT_VECTORS 408 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 409 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 410 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR); 411 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 412 413 int SplatIdx = -1; 414 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 415 EXPECT_EQ(SplatIdx, 0); 416 } 417 418 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) { 419 TargetLowering TL(*TM); 420 421 SDLoc Loc; 422 unsigned NumElts = 16; 423 MVT IntVT = MVT::i8; 424 MVT VecVT = MVT::getVectorVT(IntVT, NumElts); 425 426 // Base scalar constants. 427 SDValue Val0 = DAG->getConstant(0, Loc, IntVT); 428 SDValue Val1 = DAG->getConstant(1, Loc, IntVT); 429 SDValue Val2 = DAG->getConstant(2, Loc, IntVT); 430 SDValue Val3 = DAG->getConstant(3, Loc, IntVT); 431 SDValue UndefVal = DAG->getUNDEF(IntVT); 432 433 // Build some repeating sequences. 434 SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123; 435 for(int I = 0; I != 4; ++I) { 436 Pattern1111.append(4, Val1); 437 Pattern1133.append(2, Val1); 438 Pattern1133.append(2, Val3); 439 Pattern0123.push_back(Val0); 440 Pattern0123.push_back(Val1); 441 Pattern0123.push_back(Val2); 442 Pattern0123.push_back(Val3); 443 } 444 445 // Build a non-pow2 repeating sequence. 446 SmallVector<SDValue, 16> Pattern022; 447 Pattern022.push_back(Val0); 448 Pattern022.append(2, Val2); 449 Pattern022.push_back(Val0); 450 Pattern022.append(2, Val2); 451 Pattern022.push_back(Val0); 452 Pattern022.append(2, Val2); 453 Pattern022.push_back(Val0); 454 Pattern022.append(2, Val2); 455 Pattern022.push_back(Val0); 456 Pattern022.append(2, Val2); 457 Pattern022.push_back(Val0); 458 459 // Build a non-repeating sequence. 460 SmallVector<SDValue, 16> Pattern1_3; 461 Pattern1_3.append(8, Val1); 462 Pattern1_3.append(8, Val3); 463 464 // Add some undefs to make it trickier. 465 Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal; 466 Pattern1133[0] = Pattern1133[2] = UndefVal; 467 468 auto *BV1111 = 469 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111)); 470 auto *BV1133 = 471 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133)); 472 auto *BV0123= 473 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123)); 474 auto *BV022 = 475 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022)); 476 auto *BV1_3 = 477 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3)); 478 479 // Check for sequences. 480 SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3; 481 BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3; 482 483 EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111)); 484 EXPECT_EQ(Undefs1111.count(), 3u); 485 EXPECT_EQ(Seq1111.size(), 1u); 486 EXPECT_EQ(Seq1111[0], Val1); 487 488 EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133)); 489 EXPECT_EQ(Undefs1133.count(), 2u); 490 EXPECT_EQ(Seq1133.size(), 4u); 491 EXPECT_EQ(Seq1133[0], Val1); 492 EXPECT_EQ(Seq1133[1], Val1); 493 EXPECT_EQ(Seq1133[2], Val3); 494 EXPECT_EQ(Seq1133[3], Val3); 495 496 EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123)); 497 EXPECT_EQ(Undefs0123.count(), 0u); 498 EXPECT_EQ(Seq0123.size(), 4u); 499 EXPECT_EQ(Seq0123[0], Val0); 500 EXPECT_EQ(Seq0123[1], Val1); 501 EXPECT_EQ(Seq0123[2], Val2); 502 EXPECT_EQ(Seq0123[3], Val3); 503 504 EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022)); 505 EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3)); 506 507 // Try again with DemandedElts masks. 508 APInt Mask1111_0 = APInt::getOneBitSet(NumElts, 0); 509 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111)); 510 EXPECT_EQ(Undefs1111.count(), 0u); 511 EXPECT_EQ(Seq1111.size(), 1u); 512 EXPECT_EQ(Seq1111[0], Val1); 513 514 APInt Mask1111_1 = APInt::getOneBitSet(NumElts, 2); 515 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111)); 516 EXPECT_EQ(Undefs1111.count(), 1u); 517 EXPECT_EQ(Seq1111.size(), 1u); 518 EXPECT_EQ(Seq1111[0], UndefVal); 519 520 APInt Mask0123 = APInt(NumElts, 0x7777); 521 EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123)); 522 EXPECT_EQ(Undefs0123.count(), 0u); 523 EXPECT_EQ(Seq0123.size(), 4u); 524 EXPECT_EQ(Seq0123[0], Val0); 525 EXPECT_EQ(Seq0123[1], Val1); 526 EXPECT_EQ(Seq0123[2], Val2); 527 EXPECT_EQ(Seq0123[3], SDValue()); 528 529 APInt Mask1_3 = APInt::getHighBitsSet(16, 8); 530 EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3)); 531 EXPECT_EQ(Undefs1_3.count(), 0u); 532 EXPECT_EQ(Seq1_3.size(), 1u); 533 EXPECT_EQ(Seq1_3[0], Val3); 534 } 535 536 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) { 537 MVT VT = MVT::nxv4i64; 538 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector); 539 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 540 } 541 542 TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) { 543 MVT VT = MVT::nxv2i32; 544 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger); 545 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 546 } 547 548 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) { 549 MVT VT = MVT::nxv1f32; 550 EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector); 551 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 552 } 553 554 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) { 555 EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true); 556 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector); 557 EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context)); 558 } 559 560 TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) { 561 EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true); 562 EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true); 563 564 EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector); 565 EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT); 566 } 567 568 TEST_F(AArch64SelectionDAGTest, 569 getTypeConversion_ScalarizeScalableEVT_nxv1f128) { 570 EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(1)); 571 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector); 572 EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128); 573 } 574 575 TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) { 576 SDLoc Loc; 577 auto IntVT = EVT::getIntegerVT(Context, 8); 578 auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true); 579 580 // Should create SPLAT_VECTOR 581 SDValue Zero = DAG->getConstant(0, Loc, IntVT); 582 SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero); 583 EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR); 584 } 585 586 TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) { 587 SDLoc Loc; 588 EVT IntVT = EVT::getIntegerVT(Context, 8); 589 590 SDValue N0 = DAG->getConstant(0x42, Loc, IntVT); 591 SDValue N1 = DAG->getRegister(0, IntVT); 592 // Construct node to fill arbitrary ExtraInfo. 593 SDValue N2 = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1); 594 EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode())); 595 EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode())); 596 EXPECT_FALSE(DAG->getPCSections(N2.getNode())); 597 MDNode *MD = MDNode::get(Context, std::nullopt); 598 DAG->addHeapAllocSite(N2.getNode(), MD); 599 DAG->addNoMergeSiteInfo(N2.getNode(), true); 600 DAG->addPCSections(N2.getNode(), MD); 601 EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD); 602 EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode())); 603 EXPECT_EQ(DAG->getPCSections(N2.getNode()), MD); 604 605 SDValue Root = DAG->getNode(ISD::ADD, Loc, IntVT, N2, N2); 606 EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB); 607 // Create new node and check that ExtraInfo is propagated on RAUW. 608 SDValue New = DAG->getNode(ISD::ADD, Loc, IntVT, N1, N1); 609 EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode())); 610 EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode())); 611 EXPECT_FALSE(DAG->getPCSections(New.getNode())); 612 613 DAG->ReplaceAllUsesWith(N2, New); 614 EXPECT_EQ(Root->getOperand(0), New); 615 EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD); 616 EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode())); 617 EXPECT_EQ(DAG->getPCSections(New.getNode()), MD); 618 } 619 620 } // end namespace llvm 621