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