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, CodeGenOptLevel::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, CodeGenOptLevel::None); 65 if (!DAG) 66 report_fatal_error("DAG?"); 67 OptimizationRemarkEmitter ORE(F); 68 DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); 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 // N0 = ?000?0?0 228 // Mask2V = 01010101 229 // => 230 // Known.Zero = 00100000 (0xAA) 231 KnownBits Known; 232 APInt DemandedBits = APInt(8, 0xFF); 233 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false); 234 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO)); 235 EXPECT_EQ(Known.Zero, APInt(8, 0xAA)); 236 } 237 238 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 239 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) { 240 SDLoc Loc; 241 auto IntVT = EVT::getIntegerVT(Context, 8); 242 auto UnknownOp = DAG->getRegister(0, IntVT); 243 auto Mask = DAG->getConstant(0x8A, Loc, IntVT); 244 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp); 245 auto N1 = DAG->getConstant(0x55, Loc, IntVT); 246 auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1); 247 // N0 = ?000?0?0 248 // N1 = 01010101 249 // => 250 // Known.One = 01010101 (0x55) 251 // Known.Zero = 00100000 (0x20) 252 KnownBits Known = DAG->computeKnownBits(Op); 253 EXPECT_EQ(Known.Zero, APInt(8, 0x20)); 254 EXPECT_EQ(Known.One, APInt(8, 0x55)); 255 } 256 257 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 258 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_UADDO_CARRY) { 259 SDLoc Loc; 260 auto IntVT = EVT::getIntegerVT(Context, 8); 261 auto UnknownOp = DAG->getRegister(0, IntVT); 262 auto Mask_Zero = DAG->getConstant(0x28, Loc, IntVT); 263 auto Mask_One = DAG->getConstant(0x20, Loc, IntVT); 264 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask_Zero, UnknownOp); 265 N0 = DAG->getNode(ISD::OR, Loc, IntVT, Mask_One, N0); 266 auto N1 = DAG->getConstant(0x65, Loc, IntVT); 267 268 KnownBits Known; 269 270 auto UnknownBorrow = DAG->getRegister(1, IntVT); 271 auto OpUnknownBorrow = 272 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow); 273 // N0 = 0010?000 274 // N1 = 01100101 275 // B = ? 276 // => 277 // Known.Zero = 01110000 (0x70) 278 // Known.One = 10000100 (0x84) 279 Known = DAG->computeKnownBits(OpUnknownBorrow); 280 EXPECT_EQ(Known.Zero, APInt(8, 0x70)); 281 EXPECT_EQ(Known.One, APInt(8, 0x84)); 282 283 auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT); 284 auto OpZeroBorrow = 285 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow); 286 // N0 = 0010?000 287 // N1 = 01100101 288 // B = 0 289 // => 290 // Known.Zero = 01110010 (0x72) 291 // Known.One = 10000101 (0x85) 292 Known = DAG->computeKnownBits(OpZeroBorrow); 293 EXPECT_EQ(Known.Zero, APInt(8, 0x72)); 294 EXPECT_EQ(Known.One, APInt(8, 0x85)); 295 296 auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT); 297 auto OpOneBorrow = 298 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, OneBorrow); 299 // N0 = 0010?000 300 // N1 = 01100101 301 // B = 1 302 // => 303 // Known.Zero = 01110001 (0x71) 304 // Known.One = 10000110 (0x86) 305 Known = DAG->computeKnownBits(OpOneBorrow); 306 EXPECT_EQ(Known.Zero, APInt(8, 0x71)); 307 EXPECT_EQ(Known.One, APInt(8, 0x86)); 308 } 309 310 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 311 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) { 312 SDLoc Loc; 313 auto IntVT = EVT::getIntegerVT(Context, 8); 314 auto N0 = DAG->getConstant(0x55, Loc, IntVT); 315 auto UnknownOp = DAG->getRegister(0, IntVT); 316 auto Mask = DAG->getConstant(0x2e, Loc, IntVT); 317 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp); 318 auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1); 319 // N0 = 01010101 320 // N1 = 00?0???0 321 // => 322 // Known.One = 00000001 (0x1) 323 // Known.Zero = 10000000 (0x80) 324 KnownBits Known = DAG->computeKnownBits(Op); 325 EXPECT_EQ(Known.Zero, APInt(8, 0x80)); 326 EXPECT_EQ(Known.One, APInt(8, 0x1)); 327 } 328 329 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 330 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_USUBO_CARRY) { 331 SDLoc Loc; 332 auto IntVT = EVT::getIntegerVT(Context, 8); 333 auto N0 = DAG->getConstant(0x5a, Loc, IntVT); 334 auto UnknownOp = DAG->getRegister(0, IntVT); // ???????? 335 auto Mask1_Zero = DAG->getConstant(0x8, Loc, IntVT); // 00001000 336 auto Mask1_One = DAG->getConstant(0x20, Loc, IntVT); // 00100000 337 // N1 = (???????? & 00001000) | 00100000 = 0010?000 338 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask1_Zero, UnknownOp); 339 N1 = DAG->getNode(ISD::OR, Loc, IntVT, Mask1_One, N1); 340 341 KnownBits Known; 342 343 auto UnknownBorrow = DAG->getRegister(1, IntVT); 344 auto OpUnknownBorrow = 345 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow); 346 // N0 = 01011010 347 // N1 = 0010?000 348 // B = ? 349 // => 350 // Known.Zero = 11000100 (0xc4) 351 // Known.One = 00110000 (0x30) 352 Known = DAG->computeKnownBits(OpUnknownBorrow); 353 EXPECT_EQ(Known.Zero, APInt(8, 0xc4)); 354 EXPECT_EQ(Known.One, APInt(8, 0x30)); 355 356 auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT); 357 auto OpZeroBorrow = 358 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow); 359 // N0 = 01011010 360 // N1 = 0010?000 361 // B = 0 362 // => 363 // Known.Zero = 11000101 (0xc5) 364 // Known.One = 00110010 (0x32) 365 Known = DAG->computeKnownBits(OpZeroBorrow); 366 EXPECT_EQ(Known.Zero, APInt(8, 0xc5)); 367 EXPECT_EQ(Known.One, APInt(8, 0x32)); 368 369 auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT); 370 auto OpOneBorrow = 371 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, OneBorrow); 372 // N0 = 01011010 373 // N1 = 0010?000 374 // B = 1 375 // => 376 // Known.Zero = 11000110 (0xc6) 377 // Known.One = 00110001 (0x31) 378 Known = DAG->computeKnownBits(OpOneBorrow); 379 EXPECT_EQ(Known.Zero, APInt(8, 0xc6)); 380 EXPECT_EQ(Known.One, APInt(8, 0x31)); 381 } 382 383 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) { 384 TargetLowering TL(*TM); 385 386 SDLoc Loc; 387 auto IntVT = EVT::getIntegerVT(Context, 8); 388 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 389 // Create a BUILD_VECTOR 390 SDValue Op = DAG->getConstant(1, Loc, VecVT); 391 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR); 392 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 393 394 APInt UndefElts; 395 APInt DemandedElts; 396 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 397 398 // Width=16, Mask=3 399 DemandedElts = APInt(16, 3); 400 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 401 } 402 403 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) { 404 TargetLowering TL(*TM); 405 406 SDLoc Loc; 407 auto IntVT = EVT::getIntegerVT(Context, 8); 408 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 409 410 // Should create BUILD_VECTORs 411 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 412 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 413 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR); 414 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 415 416 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 417 418 APInt UndefElts; 419 APInt DemandedElts; 420 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 421 422 // Width=16, Mask=3 423 DemandedElts = APInt(16, 3); 424 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 425 } 426 427 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) { 428 TargetLowering TL(*TM); 429 430 SDLoc Loc; 431 auto IntVT = EVT::getIntegerVT(Context, 8); 432 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 433 // Create a SPLAT_VECTOR 434 SDValue Op = DAG->getConstant(1, Loc, VecVT); 435 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR); 436 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 437 438 APInt UndefElts; 439 APInt DemandedElts(1,1); 440 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 441 } 442 443 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) { 444 TargetLowering TL(*TM); 445 446 SDLoc Loc; 447 auto IntVT = EVT::getIntegerVT(Context, 8); 448 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 449 450 // Should create SPLAT_VECTORS 451 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 452 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 453 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR); 454 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 455 456 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 457 458 APInt UndefElts; 459 APInt DemandedElts(1, 1); 460 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 461 } 462 463 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) { 464 TargetLowering TL(*TM); 465 466 SDLoc Loc; 467 auto IntVT = EVT::getIntegerVT(Context, 8); 468 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 469 // Create a BUILD_VECTOR 470 SDValue Op = DAG->getConstant(1, Loc, VecVT); 471 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR); 472 473 int SplatIdx = -1; 474 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 475 EXPECT_EQ(SplatIdx, 0); 476 } 477 478 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) { 479 TargetLowering TL(*TM); 480 481 SDLoc Loc; 482 auto IntVT = EVT::getIntegerVT(Context, 8); 483 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 484 485 // Should create BUILD_VECTORs 486 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 487 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 488 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR); 489 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 490 491 int SplatIdx = -1; 492 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 493 EXPECT_EQ(SplatIdx, 0); 494 } 495 496 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) { 497 TargetLowering TL(*TM); 498 499 SDLoc Loc; 500 auto IntVT = EVT::getIntegerVT(Context, 8); 501 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 502 // Create a SPLAT_VECTOR 503 SDValue Op = DAG->getConstant(1, Loc, VecVT); 504 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR); 505 506 int SplatIdx = -1; 507 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 508 EXPECT_EQ(SplatIdx, 0); 509 } 510 511 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) { 512 TargetLowering TL(*TM); 513 514 SDLoc Loc; 515 auto IntVT = EVT::getIntegerVT(Context, 8); 516 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 517 518 // Should create SPLAT_VECTORS 519 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 520 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 521 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR); 522 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 523 524 int SplatIdx = -1; 525 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 526 EXPECT_EQ(SplatIdx, 0); 527 } 528 529 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) { 530 TargetLowering TL(*TM); 531 532 SDLoc Loc; 533 unsigned NumElts = 16; 534 MVT IntVT = MVT::i8; 535 MVT VecVT = MVT::getVectorVT(IntVT, NumElts); 536 537 // Base scalar constants. 538 SDValue Val0 = DAG->getConstant(0, Loc, IntVT); 539 SDValue Val1 = DAG->getConstant(1, Loc, IntVT); 540 SDValue Val2 = DAG->getConstant(2, Loc, IntVT); 541 SDValue Val3 = DAG->getConstant(3, Loc, IntVT); 542 SDValue UndefVal = DAG->getUNDEF(IntVT); 543 544 // Build some repeating sequences. 545 SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123; 546 for(int I = 0; I != 4; ++I) { 547 Pattern1111.append(4, Val1); 548 Pattern1133.append(2, Val1); 549 Pattern1133.append(2, Val3); 550 Pattern0123.push_back(Val0); 551 Pattern0123.push_back(Val1); 552 Pattern0123.push_back(Val2); 553 Pattern0123.push_back(Val3); 554 } 555 556 // Build a non-pow2 repeating sequence. 557 SmallVector<SDValue, 16> Pattern022; 558 Pattern022.push_back(Val0); 559 Pattern022.append(2, Val2); 560 Pattern022.push_back(Val0); 561 Pattern022.append(2, Val2); 562 Pattern022.push_back(Val0); 563 Pattern022.append(2, Val2); 564 Pattern022.push_back(Val0); 565 Pattern022.append(2, Val2); 566 Pattern022.push_back(Val0); 567 Pattern022.append(2, Val2); 568 Pattern022.push_back(Val0); 569 570 // Build a non-repeating sequence. 571 SmallVector<SDValue, 16> Pattern1_3; 572 Pattern1_3.append(8, Val1); 573 Pattern1_3.append(8, Val3); 574 575 // Add some undefs to make it trickier. 576 Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal; 577 Pattern1133[0] = Pattern1133[2] = UndefVal; 578 579 auto *BV1111 = 580 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111)); 581 auto *BV1133 = 582 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133)); 583 auto *BV0123= 584 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123)); 585 auto *BV022 = 586 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022)); 587 auto *BV1_3 = 588 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3)); 589 590 // Check for sequences. 591 SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3; 592 BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3; 593 594 EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111)); 595 EXPECT_EQ(Undefs1111.count(), 3u); 596 EXPECT_EQ(Seq1111.size(), 1u); 597 EXPECT_EQ(Seq1111[0], Val1); 598 599 EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133)); 600 EXPECT_EQ(Undefs1133.count(), 2u); 601 EXPECT_EQ(Seq1133.size(), 4u); 602 EXPECT_EQ(Seq1133[0], Val1); 603 EXPECT_EQ(Seq1133[1], Val1); 604 EXPECT_EQ(Seq1133[2], Val3); 605 EXPECT_EQ(Seq1133[3], Val3); 606 607 EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123)); 608 EXPECT_EQ(Undefs0123.count(), 0u); 609 EXPECT_EQ(Seq0123.size(), 4u); 610 EXPECT_EQ(Seq0123[0], Val0); 611 EXPECT_EQ(Seq0123[1], Val1); 612 EXPECT_EQ(Seq0123[2], Val2); 613 EXPECT_EQ(Seq0123[3], Val3); 614 615 EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022)); 616 EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3)); 617 618 // Try again with DemandedElts masks. 619 APInt Mask1111_0 = APInt::getOneBitSet(NumElts, 0); 620 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111)); 621 EXPECT_EQ(Undefs1111.count(), 0u); 622 EXPECT_EQ(Seq1111.size(), 1u); 623 EXPECT_EQ(Seq1111[0], Val1); 624 625 APInt Mask1111_1 = APInt::getOneBitSet(NumElts, 2); 626 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111)); 627 EXPECT_EQ(Undefs1111.count(), 1u); 628 EXPECT_EQ(Seq1111.size(), 1u); 629 EXPECT_EQ(Seq1111[0], UndefVal); 630 631 APInt Mask0123 = APInt(NumElts, 0x7777); 632 EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123)); 633 EXPECT_EQ(Undefs0123.count(), 0u); 634 EXPECT_EQ(Seq0123.size(), 4u); 635 EXPECT_EQ(Seq0123[0], Val0); 636 EXPECT_EQ(Seq0123[1], Val1); 637 EXPECT_EQ(Seq0123[2], Val2); 638 EXPECT_EQ(Seq0123[3], SDValue()); 639 640 APInt Mask1_3 = APInt::getHighBitsSet(16, 8); 641 EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3)); 642 EXPECT_EQ(Undefs1_3.count(), 0u); 643 EXPECT_EQ(Seq1_3.size(), 1u); 644 EXPECT_EQ(Seq1_3[0], Val3); 645 } 646 647 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) { 648 MVT VT = MVT::nxv4i64; 649 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector); 650 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 651 } 652 653 TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) { 654 MVT VT = MVT::nxv2i32; 655 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger); 656 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 657 } 658 659 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) { 660 MVT VT = MVT::nxv1f32; 661 EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector); 662 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 663 } 664 665 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) { 666 EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true); 667 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector); 668 EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context)); 669 } 670 671 TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) { 672 EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true); 673 EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true); 674 675 EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector); 676 EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT); 677 } 678 679 TEST_F(AArch64SelectionDAGTest, 680 getTypeConversion_ScalarizeScalableEVT_nxv1f128) { 681 EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(1)); 682 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector); 683 EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128); 684 } 685 686 TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) { 687 SDLoc Loc; 688 auto IntVT = EVT::getIntegerVT(Context, 8); 689 auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true); 690 691 // Should create SPLAT_VECTOR 692 SDValue Zero = DAG->getConstant(0, Loc, IntVT); 693 SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero); 694 EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR); 695 } 696 697 TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) { 698 SDLoc Loc; 699 EVT IntVT = EVT::getIntegerVT(Context, 8); 700 701 SDValue N0 = DAG->getConstant(0x42, Loc, IntVT); 702 SDValue N1 = DAG->getRegister(0, IntVT); 703 // Construct node to fill arbitrary ExtraInfo. 704 SDValue N2 = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1); 705 EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode())); 706 EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode())); 707 EXPECT_FALSE(DAG->getPCSections(N2.getNode())); 708 MDNode *MD = MDNode::get(Context, std::nullopt); 709 DAG->addHeapAllocSite(N2.getNode(), MD); 710 DAG->addNoMergeSiteInfo(N2.getNode(), true); 711 DAG->addPCSections(N2.getNode(), MD); 712 EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD); 713 EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode())); 714 EXPECT_EQ(DAG->getPCSections(N2.getNode()), MD); 715 716 SDValue Root = DAG->getNode(ISD::ADD, Loc, IntVT, N2, N2); 717 EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB); 718 // Create new node and check that ExtraInfo is propagated on RAUW. 719 SDValue New = DAG->getNode(ISD::ADD, Loc, IntVT, N1, N1); 720 EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode())); 721 EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode())); 722 EXPECT_FALSE(DAG->getPCSections(New.getNode())); 723 724 DAG->ReplaceAllUsesWith(N2, New); 725 EXPECT_EQ(Root->getOperand(0), New); 726 EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD); 727 EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode())); 728 EXPECT_EQ(DAG->getPCSections(New.getNode()), MD); 729 } 730 731 } // end namespace llvm 732