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/MemoryLocation.h" 10 #include "llvm/Analysis/OptimizationRemarkEmitter.h" 11 #include "llvm/AsmParser/Parser.h" 12 #include "llvm/CodeGen/MachineModuleInfo.h" 13 #include "llvm/CodeGen/SelectionDAG.h" 14 #include "llvm/CodeGen/TargetLowering.h" 15 #include "llvm/IR/MDBuilder.h" 16 #include "llvm/MC/TargetRegistry.h" 17 #include "llvm/Support/KnownBits.h" 18 #include "llvm/Support/SourceMgr.h" 19 #include "llvm/Support/TargetSelect.h" 20 #include "llvm/Target/TargetMachine.h" 21 #include "gtest/gtest.h" 22 23 namespace llvm { 24 25 class AArch64SelectionDAGTest : public testing::Test { 26 protected: 27 static void SetUpTestCase() { 28 InitializeAllTargets(); 29 InitializeAllTargetMCs(); 30 } 31 32 void SetUp() override { 33 StringRef Assembly = "define void @f() { ret void }"; 34 35 Triple TargetTriple("aarch64--"); 36 std::string Error; 37 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); 38 // FIXME: These tests do not depend on AArch64 specifically, but we have to 39 // initialize a target. A skeleton Target for unittests would allow us to 40 // always run these tests. 41 if (!T) 42 GTEST_SKIP(); 43 44 TargetOptions Options; 45 TM = std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>( 46 T->createTargetMachine("AArch64", "", "+sve", Options, std::nullopt, 47 std::nullopt, CodeGenOptLevel::Aggressive))); 48 if (!TM) 49 GTEST_SKIP(); 50 51 SMDiagnostic SMError; 52 M = parseAssemblyString(Assembly, SMError, Context); 53 if (!M) 54 report_fatal_error(SMError.getMessage()); 55 M->setDataLayout(TM->createDataLayout()); 56 57 F = M->getFunction("f"); 58 if (!F) 59 report_fatal_error("F?"); 60 61 MachineModuleInfo MMI(TM.get()); 62 63 MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F), 0, 64 MMI); 65 66 DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None); 67 if (!DAG) 68 report_fatal_error("DAG?"); 69 OptimizationRemarkEmitter ORE(F); 70 DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); 71 } 72 73 TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) { 74 return DAG->getTargetLoweringInfo().getTypeAction(Context, VT); 75 } 76 77 EVT getTypeToTransformTo(EVT VT) { 78 return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT); 79 } 80 81 LLVMContext Context; 82 std::unique_ptr<LLVMTargetMachine> TM; 83 std::unique_ptr<Module> M; 84 Function *F; 85 std::unique_ptr<MachineFunction> MF; 86 std::unique_ptr<SelectionDAG> DAG; 87 }; 88 89 TEST_F(AArch64SelectionDAGTest, computeKnownBits_ZERO_EXTEND_VECTOR_INREG) { 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 SDLoc Loc; 104 auto Int8VT = EVT::getIntegerVT(Context, 8); 105 auto Int16VT = EVT::getIntegerVT(Context, 16); 106 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, true); 107 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, true); 108 auto InVec = DAG->getConstant(0, Loc, InVecVT); 109 auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec); 110 auto DemandedElts = APInt(2, 3); 111 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts); 112 113 // We don't know anything for SVE at the moment. 114 EXPECT_EQ(Known.Zero, APInt(16, 0u)); 115 EXPECT_EQ(Known.One, APInt(16, 0u)); 116 EXPECT_FALSE(Known.isZero()); 117 } 118 119 TEST_F(AArch64SelectionDAGTest, computeKnownBits_EXTRACT_SUBVECTOR) { 120 SDLoc Loc; 121 auto IntVT = EVT::getIntegerVT(Context, 8); 122 auto VecVT = EVT::getVectorVT(Context, IntVT, 3); 123 auto IdxVT = EVT::getIntegerVT(Context, 64); 124 auto Vec = DAG->getConstant(0, Loc, VecVT); 125 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT); 126 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx); 127 auto DemandedElts = APInt(3, 7); 128 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts); 129 EXPECT_TRUE(Known.isZero()); 130 } 131 132 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG) { 133 SDLoc Loc; 134 auto Int8VT = EVT::getIntegerVT(Context, 8); 135 auto Int16VT = EVT::getIntegerVT(Context, 16); 136 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4); 137 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2); 138 auto InVec = DAG->getConstant(1, Loc, InVecVT); 139 auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec); 140 auto DemandedElts = APInt(2, 3); 141 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 15u); 142 } 143 144 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBitsSVE_SIGN_EXTEND_VECTOR_INREG) { 145 SDLoc Loc; 146 auto Int8VT = EVT::getIntegerVT(Context, 8); 147 auto Int16VT = EVT::getIntegerVT(Context, 16); 148 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, /*IsScalable=*/true); 149 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, /*IsScalable=*/true); 150 auto InVec = DAG->getConstant(1, Loc, InVecVT); 151 auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec); 152 auto DemandedElts = APInt(2, 3); 153 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 1u); 154 } 155 156 TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_EXTRACT_SUBVECTOR) { 157 SDLoc Loc; 158 auto IntVT = EVT::getIntegerVT(Context, 8); 159 auto VecVT = EVT::getVectorVT(Context, IntVT, 3); 160 auto IdxVT = EVT::getIntegerVT(Context, 64); 161 auto Vec = DAG->getConstant(1, Loc, VecVT); 162 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT); 163 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx); 164 auto DemandedElts = APInt(3, 7); 165 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 7u); 166 } 167 168 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) { 169 TargetLowering TL(*TM); 170 171 SDLoc Loc; 172 auto IntVT = EVT::getIntegerVT(Context, 8); 173 auto VecVT = EVT::getVectorVT(Context, IntVT, 3); 174 auto IdxVT = EVT::getIntegerVT(Context, 64); 175 auto Vec = DAG->getConstant(1, Loc, VecVT); 176 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT); 177 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx); 178 auto DemandedElts = APInt(3, 7); 179 auto KnownUndef = APInt(3, 0); 180 auto KnownZero = APInt(3, 0); 181 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false); 182 EXPECT_EQ(TL.SimplifyDemandedVectorElts(Op, DemandedElts, KnownUndef, 183 KnownZero, TLO), 184 false); 185 } 186 187 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) { 188 TargetLowering TL(*TM); 189 190 SDLoc Loc; 191 auto Int8VT = EVT::getIntegerVT(Context, 8); 192 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16); 193 SDValue UnknownOp = DAG->getRegister(0, InVecVT); 194 SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT); 195 SDValue Mask1V = DAG->getSplatBuildVector(InVecVT, Loc, Mask1S); 196 SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp); 197 198 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT); 199 SDValue Mask2V = DAG->getSplatBuildVector(InVecVT, Loc, Mask2S); 200 201 SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V); 202 // N0 = ?000?0?0 203 // Mask2V = 01010101 204 // => 205 // Known.Zero = 00100000 (0xAA) 206 KnownBits Known; 207 APInt DemandedBits = APInt(8, 0xFF); 208 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false); 209 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO)); 210 EXPECT_EQ(Known.Zero, APInt(8, 0xAA)); 211 } 212 213 TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) { 214 TargetLowering TL(*TM); 215 216 SDLoc Loc; 217 auto Int8VT = EVT::getIntegerVT(Context, 8); 218 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16, /*IsScalable=*/true); 219 SDValue UnknownOp = DAG->getRegister(0, InVecVT); 220 SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT); 221 SDValue Mask1V = DAG->getSplatVector(InVecVT, Loc, Mask1S); 222 SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp); 223 224 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT); 225 SDValue Mask2V = DAG->getSplatVector(InVecVT, Loc, Mask2S); 226 227 SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V); 228 229 // N0 = ?000?0?0 230 // Mask2V = 01010101 231 // => 232 // Known.Zero = 00100000 (0xAA) 233 KnownBits Known; 234 APInt DemandedBits = APInt(8, 0xFF); 235 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false); 236 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO)); 237 EXPECT_EQ(Known.Zero, APInt(8, 0xAA)); 238 } 239 240 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 241 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) { 242 SDLoc Loc; 243 auto IntVT = EVT::getIntegerVT(Context, 8); 244 auto UnknownOp = DAG->getRegister(0, IntVT); 245 auto Mask = DAG->getConstant(0x8A, Loc, IntVT); 246 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp); 247 auto N1 = DAG->getConstant(0x55, Loc, IntVT); 248 auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1); 249 // N0 = ?000?0?0 250 // N1 = 01010101 251 // => 252 // Known.One = 01010101 (0x55) 253 // Known.Zero = 00100000 (0x20) 254 KnownBits Known = DAG->computeKnownBits(Op); 255 EXPECT_EQ(Known.Zero, APInt(8, 0x20)); 256 EXPECT_EQ(Known.One, APInt(8, 0x55)); 257 } 258 259 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 260 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_UADDO_CARRY) { 261 SDLoc Loc; 262 auto IntVT = EVT::getIntegerVT(Context, 8); 263 auto UnknownOp = DAG->getRegister(0, IntVT); 264 auto Mask_Zero = DAG->getConstant(0x28, Loc, IntVT); 265 auto Mask_One = DAG->getConstant(0x20, Loc, IntVT); 266 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask_Zero, UnknownOp); 267 N0 = DAG->getNode(ISD::OR, Loc, IntVT, Mask_One, N0); 268 auto N1 = DAG->getConstant(0x65, Loc, IntVT); 269 270 KnownBits Known; 271 272 auto UnknownBorrow = DAG->getRegister(1, IntVT); 273 auto OpUnknownBorrow = 274 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow); 275 // N0 = 0010?000 276 // N1 = 01100101 277 // B = ? 278 // => 279 // Known.Zero = 01110000 (0x70) 280 // Known.One = 10000100 (0x84) 281 Known = DAG->computeKnownBits(OpUnknownBorrow); 282 EXPECT_EQ(Known.Zero, APInt(8, 0x70)); 283 EXPECT_EQ(Known.One, APInt(8, 0x84)); 284 285 auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT); 286 auto OpZeroBorrow = 287 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow); 288 // N0 = 0010?000 289 // N1 = 01100101 290 // B = 0 291 // => 292 // Known.Zero = 01110010 (0x72) 293 // Known.One = 10000101 (0x85) 294 Known = DAG->computeKnownBits(OpZeroBorrow); 295 EXPECT_EQ(Known.Zero, APInt(8, 0x72)); 296 EXPECT_EQ(Known.One, APInt(8, 0x85)); 297 298 auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT); 299 auto OpOneBorrow = 300 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, OneBorrow); 301 // N0 = 0010?000 302 // N1 = 01100101 303 // B = 1 304 // => 305 // Known.Zero = 01110001 (0x71) 306 // Known.One = 10000110 (0x86) 307 Known = DAG->computeKnownBits(OpOneBorrow); 308 EXPECT_EQ(Known.Zero, APInt(8, 0x71)); 309 EXPECT_EQ(Known.One, APInt(8, 0x86)); 310 } 311 312 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 313 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) { 314 SDLoc Loc; 315 auto IntVT = EVT::getIntegerVT(Context, 8); 316 auto N0 = DAG->getConstant(0x55, Loc, IntVT); 317 auto UnknownOp = DAG->getRegister(0, IntVT); 318 auto Mask = DAG->getConstant(0x2e, Loc, IntVT); 319 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp); 320 auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1); 321 // N0 = 01010101 322 // N1 = 00?0???0 323 // => 324 // Known.One = 00000001 (0x1) 325 // Known.Zero = 10000000 (0x80) 326 KnownBits Known = DAG->computeKnownBits(Op); 327 EXPECT_EQ(Known.Zero, APInt(8, 0x80)); 328 EXPECT_EQ(Known.One, APInt(8, 0x1)); 329 } 330 331 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits. 332 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_USUBO_CARRY) { 333 SDLoc Loc; 334 auto IntVT = EVT::getIntegerVT(Context, 8); 335 auto N0 = DAG->getConstant(0x5a, Loc, IntVT); 336 auto UnknownOp = DAG->getRegister(0, IntVT); // ???????? 337 auto Mask1_Zero = DAG->getConstant(0x8, Loc, IntVT); // 00001000 338 auto Mask1_One = DAG->getConstant(0x20, Loc, IntVT); // 00100000 339 // N1 = (???????? & 00001000) | 00100000 = 0010?000 340 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask1_Zero, UnknownOp); 341 N1 = DAG->getNode(ISD::OR, Loc, IntVT, Mask1_One, N1); 342 343 KnownBits Known; 344 345 auto UnknownBorrow = DAG->getRegister(1, IntVT); 346 auto OpUnknownBorrow = 347 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow); 348 // N0 = 01011010 349 // N1 = 0010?000 350 // B = ? 351 // => 352 // Known.Zero = 11000100 (0xc4) 353 // Known.One = 00110000 (0x30) 354 Known = DAG->computeKnownBits(OpUnknownBorrow); 355 EXPECT_EQ(Known.Zero, APInt(8, 0xc4)); 356 EXPECT_EQ(Known.One, APInt(8, 0x30)); 357 358 auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT); 359 auto OpZeroBorrow = 360 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow); 361 // N0 = 01011010 362 // N1 = 0010?000 363 // B = 0 364 // => 365 // Known.Zero = 11000101 (0xc5) 366 // Known.One = 00110010 (0x32) 367 Known = DAG->computeKnownBits(OpZeroBorrow); 368 EXPECT_EQ(Known.Zero, APInt(8, 0xc5)); 369 EXPECT_EQ(Known.One, APInt(8, 0x32)); 370 371 auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT); 372 auto OpOneBorrow = 373 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, OneBorrow); 374 // N0 = 01011010 375 // N1 = 0010?000 376 // B = 1 377 // => 378 // Known.Zero = 11000110 (0xc6) 379 // Known.One = 00110001 (0x31) 380 Known = DAG->computeKnownBits(OpOneBorrow); 381 EXPECT_EQ(Known.Zero, APInt(8, 0xc6)); 382 EXPECT_EQ(Known.One, APInt(8, 0x31)); 383 } 384 385 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) { 386 TargetLowering TL(*TM); 387 388 SDLoc Loc; 389 auto IntVT = EVT::getIntegerVT(Context, 8); 390 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 391 // Create a BUILD_VECTOR 392 SDValue Op = DAG->getConstant(1, Loc, VecVT); 393 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR); 394 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 395 396 APInt UndefElts; 397 APInt DemandedElts; 398 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 399 400 // Width=16, Mask=3 401 DemandedElts = APInt(16, 3); 402 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 403 } 404 405 TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) { 406 TargetLowering TL(*TM); 407 408 SDLoc Loc; 409 auto IntVT = EVT::getIntegerVT(Context, 8); 410 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 411 412 // Should create BUILD_VECTORs 413 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 414 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 415 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR); 416 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 417 418 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 419 420 APInt UndefElts; 421 APInt DemandedElts; 422 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 423 424 // Width=16, Mask=3 425 DemandedElts = APInt(16, 3); 426 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 427 } 428 429 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) { 430 TargetLowering TL(*TM); 431 432 SDLoc Loc; 433 auto IntVT = EVT::getIntegerVT(Context, 8); 434 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 435 // Create a SPLAT_VECTOR 436 SDValue Op = DAG->getConstant(1, Loc, VecVT); 437 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR); 438 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 439 440 APInt UndefElts; 441 APInt DemandedElts(1,1); 442 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 443 } 444 445 TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) { 446 TargetLowering TL(*TM); 447 448 SDLoc Loc; 449 auto IntVT = EVT::getIntegerVT(Context, 8); 450 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 451 452 // Should create SPLAT_VECTORS 453 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 454 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 455 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR); 456 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 457 458 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false)); 459 460 APInt UndefElts; 461 APInt DemandedElts(1, 1); 462 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts)); 463 } 464 465 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) { 466 TargetLowering TL(*TM); 467 468 SDLoc Loc; 469 auto IntVT = EVT::getIntegerVT(Context, 8); 470 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 471 // Create a BUILD_VECTOR 472 SDValue Op = DAG->getConstant(1, Loc, VecVT); 473 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR); 474 475 int SplatIdx = -1; 476 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 477 EXPECT_EQ(SplatIdx, 0); 478 } 479 480 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) { 481 TargetLowering TL(*TM); 482 483 SDLoc Loc; 484 auto IntVT = EVT::getIntegerVT(Context, 8); 485 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false); 486 487 // Should create BUILD_VECTORs 488 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 489 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 490 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR); 491 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 492 493 int SplatIdx = -1; 494 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 495 EXPECT_EQ(SplatIdx, 0); 496 } 497 498 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) { 499 TargetLowering TL(*TM); 500 501 SDLoc Loc; 502 auto IntVT = EVT::getIntegerVT(Context, 8); 503 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 504 // Create a SPLAT_VECTOR 505 SDValue Op = DAG->getConstant(1, Loc, VecVT); 506 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR); 507 508 int SplatIdx = -1; 509 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 510 EXPECT_EQ(SplatIdx, 0); 511 } 512 513 TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) { 514 TargetLowering TL(*TM); 515 516 SDLoc Loc; 517 auto IntVT = EVT::getIntegerVT(Context, 8); 518 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true); 519 520 // Should create SPLAT_VECTORS 521 SDValue Val1 = DAG->getConstant(1, Loc, VecVT); 522 SDValue Val2 = DAG->getConstant(3, Loc, VecVT); 523 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR); 524 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2); 525 526 int SplatIdx = -1; 527 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op); 528 EXPECT_EQ(SplatIdx, 0); 529 } 530 531 TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) { 532 TargetLowering TL(*TM); 533 534 SDLoc Loc; 535 unsigned NumElts = 16; 536 MVT IntVT = MVT::i8; 537 MVT VecVT = MVT::getVectorVT(IntVT, NumElts); 538 539 // Base scalar constants. 540 SDValue Val0 = DAG->getConstant(0, Loc, IntVT); 541 SDValue Val1 = DAG->getConstant(1, Loc, IntVT); 542 SDValue Val2 = DAG->getConstant(2, Loc, IntVT); 543 SDValue Val3 = DAG->getConstant(3, Loc, IntVT); 544 SDValue UndefVal = DAG->getUNDEF(IntVT); 545 546 // Build some repeating sequences. 547 SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123; 548 for(int I = 0; I != 4; ++I) { 549 Pattern1111.append(4, Val1); 550 Pattern1133.append(2, Val1); 551 Pattern1133.append(2, Val3); 552 Pattern0123.push_back(Val0); 553 Pattern0123.push_back(Val1); 554 Pattern0123.push_back(Val2); 555 Pattern0123.push_back(Val3); 556 } 557 558 // Build a non-pow2 repeating sequence. 559 SmallVector<SDValue, 16> Pattern022; 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 Pattern022.append(2, Val2); 570 Pattern022.push_back(Val0); 571 572 // Build a non-repeating sequence. 573 SmallVector<SDValue, 16> Pattern1_3; 574 Pattern1_3.append(8, Val1); 575 Pattern1_3.append(8, Val3); 576 577 // Add some undefs to make it trickier. 578 Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal; 579 Pattern1133[0] = Pattern1133[2] = UndefVal; 580 581 auto *BV1111 = 582 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111)); 583 auto *BV1133 = 584 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133)); 585 auto *BV0123= 586 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123)); 587 auto *BV022 = 588 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022)); 589 auto *BV1_3 = 590 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3)); 591 592 // Check for sequences. 593 SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3; 594 BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3; 595 596 EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111)); 597 EXPECT_EQ(Undefs1111.count(), 3u); 598 EXPECT_EQ(Seq1111.size(), 1u); 599 EXPECT_EQ(Seq1111[0], Val1); 600 601 EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133)); 602 EXPECT_EQ(Undefs1133.count(), 2u); 603 EXPECT_EQ(Seq1133.size(), 4u); 604 EXPECT_EQ(Seq1133[0], Val1); 605 EXPECT_EQ(Seq1133[1], Val1); 606 EXPECT_EQ(Seq1133[2], Val3); 607 EXPECT_EQ(Seq1133[3], Val3); 608 609 EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123)); 610 EXPECT_EQ(Undefs0123.count(), 0u); 611 EXPECT_EQ(Seq0123.size(), 4u); 612 EXPECT_EQ(Seq0123[0], Val0); 613 EXPECT_EQ(Seq0123[1], Val1); 614 EXPECT_EQ(Seq0123[2], Val2); 615 EXPECT_EQ(Seq0123[3], Val3); 616 617 EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022)); 618 EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3)); 619 620 // Try again with DemandedElts masks. 621 APInt Mask1111_0 = APInt::getOneBitSet(NumElts, 0); 622 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111)); 623 EXPECT_EQ(Undefs1111.count(), 0u); 624 EXPECT_EQ(Seq1111.size(), 1u); 625 EXPECT_EQ(Seq1111[0], Val1); 626 627 APInt Mask1111_1 = APInt::getOneBitSet(NumElts, 2); 628 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111)); 629 EXPECT_EQ(Undefs1111.count(), 1u); 630 EXPECT_EQ(Seq1111.size(), 1u); 631 EXPECT_EQ(Seq1111[0], UndefVal); 632 633 APInt Mask0123 = APInt(NumElts, 0x7777); 634 EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123)); 635 EXPECT_EQ(Undefs0123.count(), 0u); 636 EXPECT_EQ(Seq0123.size(), 4u); 637 EXPECT_EQ(Seq0123[0], Val0); 638 EXPECT_EQ(Seq0123[1], Val1); 639 EXPECT_EQ(Seq0123[2], Val2); 640 EXPECT_EQ(Seq0123[3], SDValue()); 641 642 APInt Mask1_3 = APInt::getHighBitsSet(16, 8); 643 EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3)); 644 EXPECT_EQ(Undefs1_3.count(), 0u); 645 EXPECT_EQ(Seq1_3.size(), 1u); 646 EXPECT_EQ(Seq1_3[0], Val3); 647 } 648 649 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) { 650 MVT VT = MVT::nxv4i64; 651 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector); 652 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 653 } 654 655 TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) { 656 MVT VT = MVT::nxv2i32; 657 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger); 658 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 659 } 660 661 TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) { 662 MVT VT = MVT::nxv1f32; 663 EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector); 664 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector()); 665 } 666 667 TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) { 668 EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true); 669 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector); 670 EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context)); 671 } 672 673 TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) { 674 EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true); 675 EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true); 676 677 EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector); 678 EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT); 679 } 680 681 TEST_F(AArch64SelectionDAGTest, 682 getTypeConversion_ScalarizeScalableEVT_nxv1f128) { 683 EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(1)); 684 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector); 685 EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128); 686 } 687 688 TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) { 689 SDLoc Loc; 690 auto IntVT = EVT::getIntegerVT(Context, 8); 691 auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true); 692 693 // Should create SPLAT_VECTOR 694 SDValue Zero = DAG->getConstant(0, Loc, IntVT); 695 SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero); 696 EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR); 697 } 698 699 TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) { 700 SDLoc Loc; 701 EVT IntVT = EVT::getIntegerVT(Context, 8); 702 703 SDValue N0 = DAG->getConstant(0x42, Loc, IntVT); 704 SDValue N1 = DAG->getRegister(0, IntVT); 705 // Construct node to fill arbitrary ExtraInfo. 706 SDValue N2 = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1); 707 EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode())); 708 EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode())); 709 EXPECT_FALSE(DAG->getPCSections(N2.getNode())); 710 MDNode *MD = MDNode::get(Context, std::nullopt); 711 DAG->addHeapAllocSite(N2.getNode(), MD); 712 DAG->addNoMergeSiteInfo(N2.getNode(), true); 713 DAG->addPCSections(N2.getNode(), MD); 714 EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD); 715 EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode())); 716 EXPECT_EQ(DAG->getPCSections(N2.getNode()), MD); 717 718 SDValue Root = DAG->getNode(ISD::ADD, Loc, IntVT, N2, N2); 719 EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB); 720 // Create new node and check that ExtraInfo is propagated on RAUW. 721 SDValue New = DAG->getNode(ISD::ADD, Loc, IntVT, N1, N1); 722 EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode())); 723 EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode())); 724 EXPECT_FALSE(DAG->getPCSections(New.getNode())); 725 726 DAG->ReplaceAllUsesWith(N2, New); 727 EXPECT_EQ(Root->getOperand(0), New); 728 EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD); 729 EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode())); 730 EXPECT_EQ(DAG->getPCSections(New.getNode()), MD); 731 } 732 733 TEST_F(AArch64SelectionDAGTest, computeKnownBits_extload_known01) { 734 SDLoc Loc; 735 auto Int8VT = EVT::getIntegerVT(Context, 8); 736 auto Int32VT = EVT::getIntegerVT(Context, 32); 737 auto Int64VT = EVT::getIntegerVT(Context, 64); 738 auto Ptr = DAG->getConstant(0, Loc, Int64VT); 739 auto PtrInfo = 740 MachinePointerInfo::getFixedStack(DAG->getMachineFunction(), 0); 741 AAMDNodes AA; 742 MDBuilder MDHelper(*DAG->getContext()); 743 MDNode *Range = MDHelper.createRange(APInt(8, 0), APInt(8, 2)); 744 MachineMemOperand *MMO = DAG->getMachineFunction().getMachineMemOperand( 745 PtrInfo, MachineMemOperand::MOLoad, 8, Align(8), AA, Range); 746 747 auto ALoad = DAG->getExtLoad(ISD::EXTLOAD, Loc, Int32VT, DAG->getEntryNode(), 748 Ptr, Int8VT, MMO); 749 KnownBits Known = DAG->computeKnownBits(ALoad); 750 EXPECT_EQ(Known.Zero, APInt(32, 0xfe)); 751 EXPECT_EQ(Known.One, APInt(32, 0)); 752 753 auto ZLoad = DAG->getExtLoad(ISD::ZEXTLOAD, Loc, Int32VT, DAG->getEntryNode(), 754 Ptr, Int8VT, MMO); 755 Known = DAG->computeKnownBits(ZLoad); 756 EXPECT_EQ(Known.Zero, APInt(32, 0xfffffffe)); 757 EXPECT_EQ(Known.One, APInt(32, 0)); 758 759 auto SLoad = DAG->getExtLoad(ISD::SEXTLOAD, Loc, Int32VT, DAG->getEntryNode(), 760 Ptr, Int8VT, MMO); 761 Known = DAG->computeKnownBits(SLoad); 762 EXPECT_EQ(Known.Zero, APInt(32, 0xfffffffe)); 763 EXPECT_EQ(Known.One, APInt(32, 0)); 764 } 765 766 TEST_F(AArch64SelectionDAGTest, computeKnownBits_extload_knownnegative) { 767 SDLoc Loc; 768 auto Int8VT = EVT::getIntegerVT(Context, 8); 769 auto Int32VT = EVT::getIntegerVT(Context, 32); 770 auto Int64VT = EVT::getIntegerVT(Context, 64); 771 auto Ptr = DAG->getConstant(0, Loc, Int64VT); 772 auto PtrInfo = 773 MachinePointerInfo::getFixedStack(DAG->getMachineFunction(), 0); 774 AAMDNodes AA; 775 MDBuilder MDHelper(*DAG->getContext()); 776 MDNode *Range = MDHelper.createRange(APInt(8, 0xf0), APInt(8, 0xff)); 777 MachineMemOperand *MMO = DAG->getMachineFunction().getMachineMemOperand( 778 PtrInfo, MachineMemOperand::MOLoad, 8, Align(8), AA, Range); 779 780 auto ALoad = DAG->getExtLoad(ISD::EXTLOAD, Loc, Int32VT, DAG->getEntryNode(), 781 Ptr, Int8VT, MMO); 782 KnownBits Known = DAG->computeKnownBits(ALoad); 783 EXPECT_EQ(Known.Zero, APInt(32, 0)); 784 EXPECT_EQ(Known.One, APInt(32, 0xf0)); 785 786 auto ZLoad = DAG->getExtLoad(ISD::ZEXTLOAD, Loc, Int32VT, DAG->getEntryNode(), 787 Ptr, Int8VT, MMO); 788 Known = DAG->computeKnownBits(ZLoad); 789 EXPECT_EQ(Known.Zero, APInt(32, 0xffffff00)); 790 EXPECT_EQ(Known.One, APInt(32, 0x000000f0)); 791 792 auto SLoad = DAG->getExtLoad(ISD::SEXTLOAD, Loc, Int32VT, DAG->getEntryNode(), 793 Ptr, Int8VT, MMO); 794 Known = DAG->computeKnownBits(SLoad); 795 EXPECT_EQ(Known.Zero, APInt(32, 0)); 796 EXPECT_EQ(Known.One, APInt(32, 0xfffffff0)); 797 } 798 799 } // end namespace llvm 800