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