1 //=====-- GCNSubtarget.h - Define GCN Subtarget for AMDGPU ------*- C++ -*-===// 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 /// \file 10 /// AMD GCN specific subclass of TargetSubtarget. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H 15 #define LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H 16 17 #include "AMDGPUCallLowering.h" 18 #include "AMDGPUSubtarget.h" 19 #include "SIFrameLowering.h" 20 #include "SIISelLowering.h" 21 #include "SIInstrInfo.h" 22 #include "llvm/CodeGen/SelectionDAGTargetInfo.h" 23 24 #define GET_SUBTARGETINFO_HEADER 25 #include "AMDGPUGenSubtargetInfo.inc" 26 27 namespace llvm { 28 29 class GCNTargetMachine; 30 31 class GCNSubtarget final : public AMDGPUGenSubtargetInfo, 32 public AMDGPUSubtarget { 33 34 using AMDGPUSubtarget::getMaxWavesPerEU; 35 36 public: 37 // Following 2 enums are documented at: 38 // - https://llvm.org/docs/AMDGPUUsage.html#trap-handler-abi 39 enum class TrapHandlerAbi { 40 NONE = 0x00, 41 AMDHSA = 0x01, 42 }; 43 44 enum class TrapID { 45 LLVMAMDHSATrap = 0x02, 46 LLVMAMDHSADebugTrap = 0x03, 47 }; 48 49 private: 50 /// GlobalISel related APIs. 51 std::unique_ptr<AMDGPUCallLowering> CallLoweringInfo; 52 std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo; 53 std::unique_ptr<InstructionSelector> InstSelector; 54 std::unique_ptr<LegalizerInfo> Legalizer; 55 std::unique_ptr<RegisterBankInfo> RegBankInfo; 56 57 protected: 58 // Basic subtarget description. 59 Triple TargetTriple; 60 AMDGPU::IsaInfo::AMDGPUTargetID TargetID; 61 unsigned Gen = INVALID; 62 InstrItineraryData InstrItins; 63 int LDSBankCount = 0; 64 unsigned MaxPrivateElementSize = 0; 65 66 // Possibly statically set by tablegen, but may want to be overridden. 67 bool FastFMAF32 = false; 68 bool FastDenormalF32 = false; 69 bool HalfRate64Ops = false; 70 bool FullRate64Ops = false; 71 72 // Dynamically set bits that enable features. 73 bool FlatForGlobal = false; 74 bool AutoWaitcntBeforeBarrier = false; 75 bool UnalignedScratchAccess = false; 76 bool UnalignedAccessMode = false; 77 bool HasApertureRegs = false; 78 bool SupportsXNACK = false; 79 80 // This should not be used directly. 'TargetID' tracks the dynamic settings 81 // for XNACK. 82 bool EnableXNACK = false; 83 84 bool EnableTgSplit = false; 85 bool EnableCuMode = false; 86 bool TrapHandler = false; 87 88 // Used as options. 89 bool EnableLoadStoreOpt = false; 90 bool EnableUnsafeDSOffsetFolding = false; 91 bool EnableSIScheduler = false; 92 bool EnableDS128 = false; 93 bool EnablePRTStrictNull = false; 94 bool DumpCode = false; 95 96 // Subtarget statically properties set by tablegen 97 bool FP64 = false; 98 bool FMA = false; 99 bool MIMG_R128 = false; 100 bool CIInsts = false; 101 bool GFX8Insts = false; 102 bool GFX9Insts = false; 103 bool GFX90AInsts = false; 104 bool GFX940Insts = false; 105 bool GFX10Insts = false; 106 bool GFX11Insts = false; 107 bool GFX10_3Insts = false; 108 bool GFX7GFX8GFX9Insts = false; 109 bool SGPRInitBug = false; 110 bool NegativeScratchOffsetBug = false; 111 bool NegativeUnalignedScratchOffsetBug = false; 112 bool HasSMemRealTime = false; 113 bool HasIntClamp = false; 114 bool HasFmaMixInsts = false; 115 bool HasMovrel = false; 116 bool HasVGPRIndexMode = false; 117 bool HasScalarStores = false; 118 bool HasScalarAtomics = false; 119 bool HasSDWAOmod = false; 120 bool HasSDWAScalar = false; 121 bool HasSDWASdst = false; 122 bool HasSDWAMac = false; 123 bool HasSDWAOutModsVOPC = false; 124 bool HasDPP = false; 125 bool HasDPP8 = false; 126 bool Has64BitDPP = false; 127 bool HasPackedFP32Ops = false; 128 bool HasImageInsts = false; 129 bool HasExtendedImageInsts = false; 130 bool HasR128A16 = false; 131 bool HasGFX10A16 = false; 132 bool HasG16 = false; 133 bool HasNSAEncoding = false; 134 unsigned NSAMaxSize = 0; 135 bool GFX10_AEncoding = false; 136 bool GFX10_BEncoding = false; 137 bool HasDLInsts = false; 138 bool HasDot1Insts = false; 139 bool HasDot2Insts = false; 140 bool HasDot3Insts = false; 141 bool HasDot4Insts = false; 142 bool HasDot5Insts = false; 143 bool HasDot6Insts = false; 144 bool HasDot7Insts = false; 145 bool HasDot8Insts = false; 146 bool HasMAIInsts = false; 147 bool HasPkFmacF16Inst = false; 148 bool HasAtomicFaddRtnInsts = false; 149 bool HasAtomicFaddNoRtnInsts = false; 150 bool HasAtomicPkFaddNoRtnInsts = false; 151 bool SupportsSRAMECC = false; 152 153 // This should not be used directly. 'TargetID' tracks the dynamic settings 154 // for SRAMECC. 155 bool EnableSRAMECC = false; 156 157 bool HasNoSdstCMPX = false; 158 bool HasVscnt = false; 159 bool HasGetWaveIdInst = false; 160 bool HasSMemTimeInst = false; 161 bool HasShaderCyclesRegister = false; 162 bool HasVOP3Literal = false; 163 bool HasNoDataDepHazard = false; 164 bool FlatAddressSpace = false; 165 bool FlatInstOffsets = false; 166 bool FlatGlobalInsts = false; 167 bool FlatScratchInsts = false; 168 bool ScalarFlatScratchInsts = false; 169 bool HasArchitectedFlatScratch = false; 170 bool EnableFlatScratch = false; 171 bool AddNoCarryInsts = false; 172 bool HasUnpackedD16VMem = false; 173 bool LDSMisalignedBug = false; 174 bool HasMFMAInlineLiteralBug = false; 175 bool UnalignedBufferAccess = false; 176 bool UnalignedDSAccess = false; 177 bool HasPackedTID = false; 178 bool ScalarizeGlobal = false; 179 180 bool HasVcmpxPermlaneHazard = false; 181 bool HasVMEMtoScalarWriteHazard = false; 182 bool HasSMEMtoVectorWriteHazard = false; 183 bool HasInstFwdPrefetchBug = false; 184 bool HasVcmpxExecWARHazard = false; 185 bool HasLdsBranchVmemWARHazard = false; 186 bool HasNSAtoVMEMBug = false; 187 bool HasNSAClauseBug = false; 188 bool HasOffset3fBug = false; 189 bool HasFlatSegmentOffsetBug = false; 190 bool HasImageStoreD16Bug = false; 191 bool HasImageGather4D16Bug = false; 192 bool HasVOPDInsts = false; 193 194 // Dummy feature to use for assembler in tablegen. 195 bool FeatureDisable = false; 196 197 SelectionDAGTargetInfo TSInfo; 198 private: 199 SIInstrInfo InstrInfo; 200 SITargetLowering TLInfo; 201 SIFrameLowering FrameLowering; 202 203 public: 204 // See COMPUTE_TMPRING_SIZE.WAVESIZE, 13-bit field in units of 256-dword. 205 static const unsigned MaxWaveScratchSize = (256 * 4) * ((1 << 13) - 1); 206 207 GCNSubtarget(const Triple &TT, StringRef GPU, StringRef FS, 208 const GCNTargetMachine &TM); 209 ~GCNSubtarget() override; 210 211 GCNSubtarget &initializeSubtargetDependencies(const Triple &TT, 212 StringRef GPU, StringRef FS); 213 214 const SIInstrInfo *getInstrInfo() const override { 215 return &InstrInfo; 216 } 217 218 const SIFrameLowering *getFrameLowering() const override { 219 return &FrameLowering; 220 } 221 222 const SITargetLowering *getTargetLowering() const override { 223 return &TLInfo; 224 } 225 226 const SIRegisterInfo *getRegisterInfo() const override { 227 return &InstrInfo.getRegisterInfo(); 228 } 229 230 const CallLowering *getCallLowering() const override { 231 return CallLoweringInfo.get(); 232 } 233 234 const InlineAsmLowering *getInlineAsmLowering() const override { 235 return InlineAsmLoweringInfo.get(); 236 } 237 238 InstructionSelector *getInstructionSelector() const override { 239 return InstSelector.get(); 240 } 241 242 const LegalizerInfo *getLegalizerInfo() const override { 243 return Legalizer.get(); 244 } 245 246 const RegisterBankInfo *getRegBankInfo() const override { 247 return RegBankInfo.get(); 248 } 249 250 const AMDGPU::IsaInfo::AMDGPUTargetID &getTargetID() const { 251 return TargetID; 252 } 253 254 // Nothing implemented, just prevent crashes on use. 255 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 256 return &TSInfo; 257 } 258 259 const InstrItineraryData *getInstrItineraryData() const override { 260 return &InstrItins; 261 } 262 263 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 264 265 Generation getGeneration() const { 266 return (Generation)Gen; 267 } 268 269 /// Return the number of high bits known to be zero for a frame index. 270 unsigned getKnownHighZeroBitsForFrameIndex() const { 271 return countLeadingZeros(MaxWaveScratchSize) + getWavefrontSizeLog2(); 272 } 273 274 int getLDSBankCount() const { 275 return LDSBankCount; 276 } 277 278 unsigned getMaxPrivateElementSize(bool ForBufferRSrc = false) const { 279 return (ForBufferRSrc || !enableFlatScratch()) ? MaxPrivateElementSize : 16; 280 } 281 282 unsigned getConstantBusLimit(unsigned Opcode) const; 283 284 /// Returns if the result of this instruction with a 16-bit result returned in 285 /// a 32-bit register implicitly zeroes the high 16-bits, rather than preserve 286 /// the original value. 287 bool zeroesHigh16BitsOfDest(unsigned Opcode) const; 288 289 bool hasIntClamp() const { 290 return HasIntClamp; 291 } 292 293 bool hasFP64() const { 294 return FP64; 295 } 296 297 bool hasMIMG_R128() const { 298 return MIMG_R128; 299 } 300 301 bool hasHWFP64() const { 302 return FP64; 303 } 304 305 bool hasFastFMAF32() const { 306 return FastFMAF32; 307 } 308 309 bool hasHalfRate64Ops() const { 310 return HalfRate64Ops; 311 } 312 313 bool hasFullRate64Ops() const { 314 return FullRate64Ops; 315 } 316 317 bool hasAddr64() const { 318 return (getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS); 319 } 320 321 bool hasFlat() const { 322 return (getGeneration() > AMDGPUSubtarget::SOUTHERN_ISLANDS); 323 } 324 325 // Return true if the target only has the reverse operand versions of VALU 326 // shift instructions (e.g. v_lshrrev_b32, and no v_lshr_b32). 327 bool hasOnlyRevVALUShifts() const { 328 return getGeneration() >= VOLCANIC_ISLANDS; 329 } 330 331 bool hasFractBug() const { 332 return getGeneration() == SOUTHERN_ISLANDS; 333 } 334 335 bool hasBFE() const { 336 return true; 337 } 338 339 bool hasBFI() const { 340 return true; 341 } 342 343 bool hasBFM() const { 344 return hasBFE(); 345 } 346 347 bool hasBCNT(unsigned Size) const { 348 return true; 349 } 350 351 bool hasFFBL() const { 352 return true; 353 } 354 355 bool hasFFBH() const { 356 return true; 357 } 358 359 bool hasMed3_16() const { 360 return getGeneration() >= AMDGPUSubtarget::GFX9; 361 } 362 363 bool hasMin3Max3_16() const { 364 return getGeneration() >= AMDGPUSubtarget::GFX9; 365 } 366 367 bool hasFmaMixInsts() const { 368 return HasFmaMixInsts; 369 } 370 371 bool hasCARRY() const { 372 return true; 373 } 374 375 bool hasFMA() const { 376 return FMA; 377 } 378 379 bool hasSwap() const { 380 return GFX9Insts; 381 } 382 383 bool hasScalarPackInsts() const { 384 return GFX9Insts; 385 } 386 387 bool hasScalarMulHiInsts() const { 388 return GFX9Insts; 389 } 390 391 TrapHandlerAbi getTrapHandlerAbi() const { 392 return isAmdHsaOS() ? TrapHandlerAbi::AMDHSA : TrapHandlerAbi::NONE; 393 } 394 395 bool supportsGetDoorbellID() const { 396 // The S_GETREG DOORBELL_ID is supported by all GFX9 onward targets. 397 return getGeneration() >= GFX9; 398 } 399 400 /// True if the offset field of DS instructions works as expected. On SI, the 401 /// offset uses a 16-bit adder and does not always wrap properly. 402 bool hasUsableDSOffset() const { 403 return getGeneration() >= SEA_ISLANDS; 404 } 405 406 bool unsafeDSOffsetFoldingEnabled() const { 407 return EnableUnsafeDSOffsetFolding; 408 } 409 410 /// Condition output from div_scale is usable. 411 bool hasUsableDivScaleConditionOutput() const { 412 return getGeneration() != SOUTHERN_ISLANDS; 413 } 414 415 /// Extra wait hazard is needed in some cases before 416 /// s_cbranch_vccnz/s_cbranch_vccz. 417 bool hasReadVCCZBug() const { 418 return getGeneration() <= SEA_ISLANDS; 419 } 420 421 /// Writes to VCC_LO/VCC_HI update the VCCZ flag. 422 bool partialVCCWritesUpdateVCCZ() const { 423 return getGeneration() >= GFX10; 424 } 425 426 /// A read of an SGPR by SMRD instruction requires 4 wait states when the SGPR 427 /// was written by a VALU instruction. 428 bool hasSMRDReadVALUDefHazard() const { 429 return getGeneration() == SOUTHERN_ISLANDS; 430 } 431 432 /// A read of an SGPR by a VMEM instruction requires 5 wait states when the 433 /// SGPR was written by a VALU Instruction. 434 bool hasVMEMReadSGPRVALUDefHazard() const { 435 return getGeneration() >= VOLCANIC_ISLANDS; 436 } 437 438 bool hasRFEHazards() const { 439 return getGeneration() >= VOLCANIC_ISLANDS; 440 } 441 442 /// Number of hazard wait states for s_setreg_b32/s_setreg_imm32_b32. 443 unsigned getSetRegWaitStates() const { 444 return getGeneration() <= SEA_ISLANDS ? 1 : 2; 445 } 446 447 bool dumpCode() const { 448 return DumpCode; 449 } 450 451 /// Return the amount of LDS that can be used that will not restrict the 452 /// occupancy lower than WaveCount. 453 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount, 454 const Function &) const; 455 456 bool supportsMinMaxDenormModes() const { 457 return getGeneration() >= AMDGPUSubtarget::GFX9; 458 } 459 460 /// \returns If target supports S_DENORM_MODE. 461 bool hasDenormModeInst() const { 462 return getGeneration() >= AMDGPUSubtarget::GFX10; 463 } 464 465 bool useFlatForGlobal() const { 466 return FlatForGlobal; 467 } 468 469 /// \returns If target supports ds_read/write_b128 and user enables generation 470 /// of ds_read/write_b128. 471 bool useDS128() const { 472 return CIInsts && EnableDS128; 473 } 474 475 /// \return If target supports ds_read/write_b96/128. 476 bool hasDS96AndDS128() const { 477 return CIInsts; 478 } 479 480 /// Have v_trunc_f64, v_ceil_f64, v_rndne_f64 481 bool haveRoundOpsF64() const { 482 return CIInsts; 483 } 484 485 /// \returns If MUBUF instructions always perform range checking, even for 486 /// buffer resources used for private memory access. 487 bool privateMemoryResourceIsRangeChecked() const { 488 return getGeneration() < AMDGPUSubtarget::GFX9; 489 } 490 491 /// \returns If target requires PRT Struct NULL support (zero result registers 492 /// for sparse texture support). 493 bool usePRTStrictNull() const { 494 return EnablePRTStrictNull; 495 } 496 497 bool hasAutoWaitcntBeforeBarrier() const { 498 return AutoWaitcntBeforeBarrier; 499 } 500 501 bool hasUnalignedBufferAccess() const { 502 return UnalignedBufferAccess; 503 } 504 505 bool hasUnalignedBufferAccessEnabled() const { 506 return UnalignedBufferAccess && UnalignedAccessMode; 507 } 508 509 bool hasUnalignedDSAccess() const { 510 return UnalignedDSAccess; 511 } 512 513 bool hasUnalignedDSAccessEnabled() const { 514 return UnalignedDSAccess && UnalignedAccessMode; 515 } 516 517 bool hasUnalignedScratchAccess() const { 518 return UnalignedScratchAccess; 519 } 520 521 bool hasUnalignedAccessMode() const { 522 return UnalignedAccessMode; 523 } 524 525 bool hasApertureRegs() const { 526 return HasApertureRegs; 527 } 528 529 bool isTrapHandlerEnabled() const { 530 return TrapHandler; 531 } 532 533 bool isXNACKEnabled() const { 534 return TargetID.isXnackOnOrAny(); 535 } 536 537 bool isTgSplitEnabled() const { 538 return EnableTgSplit; 539 } 540 541 bool isCuModeEnabled() const { 542 return EnableCuMode; 543 } 544 545 bool hasFlatAddressSpace() const { 546 return FlatAddressSpace; 547 } 548 549 bool hasFlatScrRegister() const { 550 return hasFlatAddressSpace(); 551 } 552 553 bool hasFlatInstOffsets() const { 554 return FlatInstOffsets; 555 } 556 557 bool hasFlatGlobalInsts() const { 558 return FlatGlobalInsts; 559 } 560 561 bool hasFlatScratchInsts() const { 562 return FlatScratchInsts; 563 } 564 565 // Check if target supports ST addressing mode with FLAT scratch instructions. 566 // The ST addressing mode means no registers are used, either VGPR or SGPR, 567 // but only immediate offset is swizzled and added to the FLAT scratch base. 568 bool hasFlatScratchSTMode() const { 569 return hasFlatScratchInsts() && (hasGFX10_3Insts() || hasGFX940Insts()); 570 } 571 572 bool hasFlatScratchSVSMode() const { return GFX940Insts || GFX11Insts; } 573 574 bool hasScalarFlatScratchInsts() const { 575 return ScalarFlatScratchInsts; 576 } 577 578 bool enableFlatScratch() const { 579 return flatScratchIsArchitected() || 580 (EnableFlatScratch && hasFlatScratchInsts()); 581 } 582 583 bool hasGlobalAddTidInsts() const { 584 return GFX10_BEncoding; 585 } 586 587 bool hasAtomicCSub() const { 588 return GFX10_BEncoding; 589 } 590 591 bool hasMultiDwordFlatScratchAddressing() const { 592 return getGeneration() >= GFX9; 593 } 594 595 bool hasFlatSegmentOffsetBug() const { 596 return HasFlatSegmentOffsetBug; 597 } 598 599 bool hasFlatLgkmVMemCountInOrder() const { 600 return getGeneration() > GFX9; 601 } 602 603 bool hasD16LoadStore() const { 604 return getGeneration() >= GFX9; 605 } 606 607 bool d16PreservesUnusedBits() const { 608 return hasD16LoadStore() && !TargetID.isSramEccOnOrAny(); 609 } 610 611 bool hasD16Images() const { 612 return getGeneration() >= VOLCANIC_ISLANDS; 613 } 614 615 /// Return if most LDS instructions have an m0 use that require m0 to be 616 /// initialized. 617 bool ldsRequiresM0Init() const { 618 return getGeneration() < GFX9; 619 } 620 621 // True if the hardware rewinds and replays GWS operations if a wave is 622 // preempted. 623 // 624 // If this is false, a GWS operation requires testing if a nack set the 625 // MEM_VIOL bit, and repeating if so. 626 bool hasGWSAutoReplay() const { 627 return getGeneration() >= GFX9; 628 } 629 630 /// \returns if target has ds_gws_sema_release_all instruction. 631 bool hasGWSSemaReleaseAll() const { 632 return CIInsts; 633 } 634 635 /// \returns true if the target has integer add/sub instructions that do not 636 /// produce a carry-out. This includes v_add_[iu]32, v_sub_[iu]32, 637 /// v_add_[iu]16, and v_sub_[iu]16, all of which support the clamp modifier 638 /// for saturation. 639 bool hasAddNoCarry() const { 640 return AddNoCarryInsts; 641 } 642 643 bool hasUnpackedD16VMem() const { 644 return HasUnpackedD16VMem; 645 } 646 647 // Covers VS/PS/CS graphics shaders 648 bool isMesaGfxShader(const Function &F) const { 649 return isMesa3DOS() && AMDGPU::isShader(F.getCallingConv()); 650 } 651 652 bool hasMad64_32() const { 653 return getGeneration() >= SEA_ISLANDS; 654 } 655 656 bool hasSDWAOmod() const { 657 return HasSDWAOmod; 658 } 659 660 bool hasSDWAScalar() const { 661 return HasSDWAScalar; 662 } 663 664 bool hasSDWASdst() const { 665 return HasSDWASdst; 666 } 667 668 bool hasSDWAMac() const { 669 return HasSDWAMac; 670 } 671 672 bool hasSDWAOutModsVOPC() const { 673 return HasSDWAOutModsVOPC; 674 } 675 676 bool hasDLInsts() const { 677 return HasDLInsts; 678 } 679 680 bool hasDot1Insts() const { 681 return HasDot1Insts; 682 } 683 684 bool hasDot2Insts() const { 685 return HasDot2Insts; 686 } 687 688 bool hasDot3Insts() const { 689 return HasDot3Insts; 690 } 691 692 bool hasDot4Insts() const { 693 return HasDot4Insts; 694 } 695 696 bool hasDot5Insts() const { 697 return HasDot5Insts; 698 } 699 700 bool hasDot6Insts() const { 701 return HasDot6Insts; 702 } 703 704 bool hasDot7Insts() const { 705 return HasDot7Insts; 706 } 707 708 bool hasDot8Insts() const { 709 return HasDot8Insts; 710 } 711 712 bool hasMAIInsts() const { 713 return HasMAIInsts; 714 } 715 716 bool hasPkFmacF16Inst() const { 717 return HasPkFmacF16Inst; 718 } 719 720 bool hasAtomicFaddInsts() const { 721 return HasAtomicFaddRtnInsts || HasAtomicFaddNoRtnInsts; 722 } 723 724 bool hasAtomicFaddRtnInsts() const { return HasAtomicFaddRtnInsts; } 725 726 bool hasAtomicFaddNoRtnInsts() const { return HasAtomicFaddNoRtnInsts; } 727 728 bool hasAtomicPkFaddNoRtnInsts() const { return HasAtomicPkFaddNoRtnInsts; } 729 730 bool hasNoSdstCMPX() const { 731 return HasNoSdstCMPX; 732 } 733 734 bool hasVscnt() const { 735 return HasVscnt; 736 } 737 738 bool hasGetWaveIdInst() const { 739 return HasGetWaveIdInst; 740 } 741 742 bool hasSMemTimeInst() const { 743 return HasSMemTimeInst; 744 } 745 746 bool hasShaderCyclesRegister() const { 747 return HasShaderCyclesRegister; 748 } 749 750 bool hasVOP3Literal() const { 751 return HasVOP3Literal; 752 } 753 754 bool hasNoDataDepHazard() const { 755 return HasNoDataDepHazard; 756 } 757 758 bool vmemWriteNeedsExpWaitcnt() const { 759 return getGeneration() < SEA_ISLANDS; 760 } 761 762 // Scratch is allocated in 256 dword per wave blocks for the entire 763 // wavefront. When viewed from the perspective of an arbitrary workitem, this 764 // is 4-byte aligned. 765 // 766 // Only 4-byte alignment is really needed to access anything. Transformations 767 // on the pointer value itself may rely on the alignment / known low bits of 768 // the pointer. Set this to something above the minimum to avoid needing 769 // dynamic realignment in common cases. 770 Align getStackAlignment() const { return Align(16); } 771 772 bool enableMachineScheduler() const override { 773 return true; 774 } 775 776 bool useAA() const override; 777 778 bool enableSubRegLiveness() const override { 779 return true; 780 } 781 782 void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b; } 783 bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal; } 784 785 // static wrappers 786 static bool hasHalfRate64Ops(const TargetSubtargetInfo &STI); 787 788 // XXX - Why is this here if it isn't in the default pass set? 789 bool enableEarlyIfConversion() const override { 790 return true; 791 } 792 793 void overrideSchedPolicy(MachineSchedPolicy &Policy, 794 unsigned NumRegionInstrs) const override; 795 796 unsigned getMaxNumUserSGPRs() const { 797 return 16; 798 } 799 800 bool hasSMemRealTime() const { 801 return HasSMemRealTime; 802 } 803 804 bool hasMovrel() const { 805 return HasMovrel; 806 } 807 808 bool hasVGPRIndexMode() const { 809 return HasVGPRIndexMode; 810 } 811 812 bool useVGPRIndexMode() const; 813 814 bool hasScalarCompareEq64() const { 815 return getGeneration() >= VOLCANIC_ISLANDS; 816 } 817 818 bool hasScalarStores() const { 819 return HasScalarStores; 820 } 821 822 bool hasScalarAtomics() const { 823 return HasScalarAtomics; 824 } 825 826 bool hasLDSFPAtomicAdd() const { return GFX8Insts; } 827 828 /// \returns true if the subtarget has the v_permlanex16_b32 instruction. 829 bool hasPermLaneX16() const { return getGeneration() >= GFX10; } 830 831 /// \returns true if the subtarget has the v_permlane64_b32 instruction. 832 bool hasPermLane64() const { return getGeneration() >= GFX11; } 833 834 bool hasDPP() const { 835 return HasDPP; 836 } 837 838 bool hasDPPBroadcasts() const { 839 return HasDPP && getGeneration() < GFX10; 840 } 841 842 bool hasDPPWavefrontShifts() const { 843 return HasDPP && getGeneration() < GFX10; 844 } 845 846 bool hasDPP8() const { 847 return HasDPP8; 848 } 849 850 bool has64BitDPP() const { 851 return Has64BitDPP; 852 } 853 854 bool hasPackedFP32Ops() const { 855 return HasPackedFP32Ops; 856 } 857 858 bool hasFmaakFmamkF32Insts() const { 859 return getGeneration() >= GFX10 || hasGFX940Insts(); 860 } 861 862 bool hasImageInsts() const { 863 return HasImageInsts; 864 } 865 866 bool hasExtendedImageInsts() const { 867 return HasExtendedImageInsts; 868 } 869 870 bool hasR128A16() const { 871 return HasR128A16; 872 } 873 874 bool hasGFX10A16() const { 875 return HasGFX10A16; 876 } 877 878 bool hasA16() const { return hasR128A16() || hasGFX10A16(); } 879 880 bool hasG16() const { return HasG16; } 881 882 bool hasOffset3fBug() const { 883 return HasOffset3fBug; 884 } 885 886 bool hasImageStoreD16Bug() const { return HasImageStoreD16Bug; } 887 888 bool hasImageGather4D16Bug() const { return HasImageGather4D16Bug; } 889 890 bool hasNSAEncoding() const { return HasNSAEncoding; } 891 892 unsigned getNSAMaxSize() const { return NSAMaxSize; } 893 894 bool hasGFX10_AEncoding() const { 895 return GFX10_AEncoding; 896 } 897 898 bool hasGFX10_BEncoding() const { 899 return GFX10_BEncoding; 900 } 901 902 bool hasGFX10_3Insts() const { 903 return GFX10_3Insts; 904 } 905 906 bool hasMadF16() const; 907 908 bool hasMovB64() const { return GFX940Insts; } 909 910 bool hasLshlAddB64() const { return GFX940Insts; } 911 912 bool enableSIScheduler() const { 913 return EnableSIScheduler; 914 } 915 916 bool loadStoreOptEnabled() const { 917 return EnableLoadStoreOpt; 918 } 919 920 bool hasSGPRInitBug() const { 921 return SGPRInitBug; 922 } 923 924 bool hasNegativeScratchOffsetBug() const { return NegativeScratchOffsetBug; } 925 926 bool hasNegativeUnalignedScratchOffsetBug() const { 927 return NegativeUnalignedScratchOffsetBug; 928 } 929 930 bool hasMFMAInlineLiteralBug() const { 931 return HasMFMAInlineLiteralBug; 932 } 933 934 bool has12DWordStoreHazard() const { 935 return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS; 936 } 937 938 // \returns true if the subtarget supports DWORDX3 load/store instructions. 939 bool hasDwordx3LoadStores() const { 940 return CIInsts; 941 } 942 943 bool hasReadM0MovRelInterpHazard() const { 944 return getGeneration() == AMDGPUSubtarget::GFX9; 945 } 946 947 bool hasReadM0SendMsgHazard() const { 948 return getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS && 949 getGeneration() <= AMDGPUSubtarget::GFX9; 950 } 951 952 bool hasReadM0LdsDmaHazard() const { 953 return getGeneration() == AMDGPUSubtarget::GFX9; 954 } 955 956 bool hasReadM0LdsDirectHazard() const { 957 return getGeneration() == AMDGPUSubtarget::GFX9; 958 } 959 960 bool hasVcmpxPermlaneHazard() const { 961 return HasVcmpxPermlaneHazard; 962 } 963 964 bool hasVMEMtoScalarWriteHazard() const { 965 return HasVMEMtoScalarWriteHazard; 966 } 967 968 bool hasSMEMtoVectorWriteHazard() const { 969 return HasSMEMtoVectorWriteHazard; 970 } 971 972 bool hasLDSMisalignedBug() const { 973 return LDSMisalignedBug && !EnableCuMode; 974 } 975 976 bool hasInstFwdPrefetchBug() const { 977 return HasInstFwdPrefetchBug; 978 } 979 980 bool hasVcmpxExecWARHazard() const { 981 return HasVcmpxExecWARHazard; 982 } 983 984 bool hasLdsBranchVmemWARHazard() const { 985 return HasLdsBranchVmemWARHazard; 986 } 987 988 // Has one cycle hazard on transcendental instruction feeding a 989 // non transcendental VALU. 990 bool hasTransForwardingHazard() const { return GFX940Insts; } 991 992 // Has one cycle hazard on a VALU instruction partially writing dst with 993 // a shift of result bits feeding another VALU instruction. 994 bool hasDstSelForwardingHazard() const { return GFX940Insts; } 995 996 // Cannot use op_sel with v_dot instructions. 997 bool hasDOTOpSelHazard() const { return GFX940Insts; } 998 999 // Does not have HW interlocs for VALU writing and then reading SGPRs. 1000 bool hasVDecCoExecHazard() const { 1001 return GFX940Insts; 1002 } 1003 1004 bool hasNSAtoVMEMBug() const { 1005 return HasNSAtoVMEMBug; 1006 } 1007 1008 bool hasNSAClauseBug() const { return HasNSAClauseBug; } 1009 1010 bool hasHardClauses() const { return getGeneration() >= GFX10; } 1011 1012 bool hasGFX90AInsts() const { return GFX90AInsts; } 1013 1014 bool hasVOP3DPP() const { return getGeneration() >= GFX11; } 1015 1016 bool hasLdsDirect() const { return getGeneration() >= GFX11; } 1017 1018 bool hasVALUPartialForwardingHazard() const { 1019 return getGeneration() >= GFX11; 1020 } 1021 1022 bool hasVALUTransUseHazard() const { return getGeneration() >= GFX11; } 1023 1024 /// Return if operations acting on VGPR tuples require even alignment. 1025 bool needsAlignedVGPRs() const { return GFX90AInsts; } 1026 1027 /// Return true if the target has the S_PACK_HL_B32_B16 instruction. 1028 bool hasSPackHL() const { return GFX11Insts; } 1029 1030 /// Return true if the target's EXP instruction has the COMPR flag, which 1031 /// affects the meaning of the EN (enable) bits. 1032 bool hasCompressedExport() const { return !GFX11Insts; } 1033 1034 /// Return true if the target's EXP instruction supports the NULL export 1035 /// target. 1036 bool hasNullExportTarget() const { return !GFX11Insts; } 1037 1038 bool hasVOPDInsts() const { return HasVOPDInsts; } 1039 1040 /// Return true if the target has the S_DELAY_ALU instruction. 1041 bool hasDelayAlu() const { return GFX11Insts; } 1042 1043 bool hasPackedTID() const { return HasPackedTID; } 1044 1045 // GFX940 is a derivation to GFX90A. hasGFX940Insts() being true implies that 1046 // hasGFX90AInsts is also true. 1047 bool hasGFX940Insts() const { return GFX940Insts; } 1048 1049 /// Return the maximum number of waves per SIMD for kernels using \p SGPRs 1050 /// SGPRs 1051 unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const; 1052 1053 /// Return the maximum number of waves per SIMD for kernels using \p VGPRs 1054 /// VGPRs 1055 unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const; 1056 1057 /// Return occupancy for the given function. Used LDS and a number of 1058 /// registers if provided. 1059 /// Note, occupancy can be affected by the scratch allocation as well, but 1060 /// we do not have enough information to compute it. 1061 unsigned computeOccupancy(const Function &F, unsigned LDSSize = 0, 1062 unsigned NumSGPRs = 0, unsigned NumVGPRs = 0) const; 1063 1064 /// \returns true if the flat_scratch register should be initialized with the 1065 /// pointer to the wave's scratch memory rather than a size and offset. 1066 bool flatScratchIsPointer() const { 1067 return getGeneration() >= AMDGPUSubtarget::GFX9; 1068 } 1069 1070 /// \returns true if the flat_scratch register is initialized by the HW. 1071 /// In this case it is readonly. 1072 bool flatScratchIsArchitected() const { return HasArchitectedFlatScratch; } 1073 1074 /// \returns true if the machine has merged shaders in which s0-s7 are 1075 /// reserved by the hardware and user SGPRs start at s8 1076 bool hasMergedShaders() const { 1077 return getGeneration() >= GFX9; 1078 } 1079 1080 // \returns true if the target supports the pre-NGG legacy geometry path. 1081 bool hasLegacyGeometry() const { return getGeneration() < GFX11; } 1082 1083 /// \returns SGPR allocation granularity supported by the subtarget. 1084 unsigned getSGPRAllocGranule() const { 1085 return AMDGPU::IsaInfo::getSGPRAllocGranule(this); 1086 } 1087 1088 /// \returns SGPR encoding granularity supported by the subtarget. 1089 unsigned getSGPREncodingGranule() const { 1090 return AMDGPU::IsaInfo::getSGPREncodingGranule(this); 1091 } 1092 1093 /// \returns Total number of SGPRs supported by the subtarget. 1094 unsigned getTotalNumSGPRs() const { 1095 return AMDGPU::IsaInfo::getTotalNumSGPRs(this); 1096 } 1097 1098 /// \returns Addressable number of SGPRs supported by the subtarget. 1099 unsigned getAddressableNumSGPRs() const { 1100 return AMDGPU::IsaInfo::getAddressableNumSGPRs(this); 1101 } 1102 1103 /// \returns Minimum number of SGPRs that meets the given number of waves per 1104 /// execution unit requirement supported by the subtarget. 1105 unsigned getMinNumSGPRs(unsigned WavesPerEU) const { 1106 return AMDGPU::IsaInfo::getMinNumSGPRs(this, WavesPerEU); 1107 } 1108 1109 /// \returns Maximum number of SGPRs that meets the given number of waves per 1110 /// execution unit requirement supported by the subtarget. 1111 unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const { 1112 return AMDGPU::IsaInfo::getMaxNumSGPRs(this, WavesPerEU, Addressable); 1113 } 1114 1115 /// \returns Reserved number of SGPRs. This is common 1116 /// utility function called by MachineFunction and 1117 /// Function variants of getReservedNumSGPRs. 1118 unsigned getBaseReservedNumSGPRs(const bool HasFlatScratch) const; 1119 /// \returns Reserved number of SGPRs for given machine function \p MF. 1120 unsigned getReservedNumSGPRs(const MachineFunction &MF) const; 1121 1122 /// \returns Reserved number of SGPRs for given function \p F. 1123 unsigned getReservedNumSGPRs(const Function &F) const; 1124 1125 /// \returns max num SGPRs. This is the common utility 1126 /// function called by MachineFunction and Function 1127 /// variants of getMaxNumSGPRs. 1128 unsigned getBaseMaxNumSGPRs(const Function &F, 1129 std::pair<unsigned, unsigned> WavesPerEU, 1130 unsigned PreloadedSGPRs, 1131 unsigned ReservedNumSGPRs) const; 1132 1133 /// \returns Maximum number of SGPRs that meets number of waves per execution 1134 /// unit requirement for function \p MF, or number of SGPRs explicitly 1135 /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF. 1136 /// 1137 /// \returns Value that meets number of waves per execution unit requirement 1138 /// if explicitly requested value cannot be converted to integer, violates 1139 /// subtarget's specifications, or does not meet number of waves per execution 1140 /// unit requirement. 1141 unsigned getMaxNumSGPRs(const MachineFunction &MF) const; 1142 1143 /// \returns Maximum number of SGPRs that meets number of waves per execution 1144 /// unit requirement for function \p F, or number of SGPRs explicitly 1145 /// requested using "amdgpu-num-sgpr" attribute attached to function \p F. 1146 /// 1147 /// \returns Value that meets number of waves per execution unit requirement 1148 /// if explicitly requested value cannot be converted to integer, violates 1149 /// subtarget's specifications, or does not meet number of waves per execution 1150 /// unit requirement. 1151 unsigned getMaxNumSGPRs(const Function &F) const; 1152 1153 /// \returns VGPR allocation granularity supported by the subtarget. 1154 unsigned getVGPRAllocGranule() const { 1155 return AMDGPU::IsaInfo::getVGPRAllocGranule(this); 1156 } 1157 1158 /// \returns VGPR encoding granularity supported by the subtarget. 1159 unsigned getVGPREncodingGranule() const { 1160 return AMDGPU::IsaInfo::getVGPREncodingGranule(this); 1161 } 1162 1163 /// \returns Total number of VGPRs supported by the subtarget. 1164 unsigned getTotalNumVGPRs() const { 1165 return AMDGPU::IsaInfo::getTotalNumVGPRs(this); 1166 } 1167 1168 /// \returns Addressable number of VGPRs supported by the subtarget. 1169 unsigned getAddressableNumVGPRs() const { 1170 return AMDGPU::IsaInfo::getAddressableNumVGPRs(this); 1171 } 1172 1173 /// \returns Minimum number of VGPRs that meets given number of waves per 1174 /// execution unit requirement supported by the subtarget. 1175 unsigned getMinNumVGPRs(unsigned WavesPerEU) const { 1176 return AMDGPU::IsaInfo::getMinNumVGPRs(this, WavesPerEU); 1177 } 1178 1179 /// \returns Maximum number of VGPRs that meets given number of waves per 1180 /// execution unit requirement supported by the subtarget. 1181 unsigned getMaxNumVGPRs(unsigned WavesPerEU) const { 1182 return AMDGPU::IsaInfo::getMaxNumVGPRs(this, WavesPerEU); 1183 } 1184 1185 /// \returns max num VGPRs. This is the common utility function 1186 /// called by MachineFunction and Function variants of getMaxNumVGPRs. 1187 unsigned getBaseMaxNumVGPRs(const Function &F, 1188 std::pair<unsigned, unsigned> WavesPerEU) const; 1189 /// \returns Maximum number of VGPRs that meets number of waves per execution 1190 /// unit requirement for function \p F, or number of VGPRs explicitly 1191 /// requested using "amdgpu-num-vgpr" attribute attached to function \p F. 1192 /// 1193 /// \returns Value that meets number of waves per execution unit requirement 1194 /// if explicitly requested value cannot be converted to integer, violates 1195 /// subtarget's specifications, or does not meet number of waves per execution 1196 /// unit requirement. 1197 unsigned getMaxNumVGPRs(const Function &F) const; 1198 1199 unsigned getMaxNumAGPRs(const Function &F) const { 1200 return getMaxNumVGPRs(F); 1201 } 1202 1203 /// \returns Maximum number of VGPRs that meets number of waves per execution 1204 /// unit requirement for function \p MF, or number of VGPRs explicitly 1205 /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF. 1206 /// 1207 /// \returns Value that meets number of waves per execution unit requirement 1208 /// if explicitly requested value cannot be converted to integer, violates 1209 /// subtarget's specifications, or does not meet number of waves per execution 1210 /// unit requirement. 1211 unsigned getMaxNumVGPRs(const MachineFunction &MF) const; 1212 1213 void getPostRAMutations( 1214 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) 1215 const override; 1216 1217 std::unique_ptr<ScheduleDAGMutation> 1218 createFillMFMAShadowMutation(const TargetInstrInfo *TII) const; 1219 1220 bool isWave32() const { 1221 return getWavefrontSize() == 32; 1222 } 1223 1224 bool isWave64() const { 1225 return getWavefrontSize() == 64; 1226 } 1227 1228 const TargetRegisterClass *getBoolRC() const { 1229 return getRegisterInfo()->getBoolRC(); 1230 } 1231 1232 /// \returns Maximum number of work groups per compute unit supported by the 1233 /// subtarget and limited by given \p FlatWorkGroupSize. 1234 unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override { 1235 return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize); 1236 } 1237 1238 /// \returns Minimum flat work group size supported by the subtarget. 1239 unsigned getMinFlatWorkGroupSize() const override { 1240 return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this); 1241 } 1242 1243 /// \returns Maximum flat work group size supported by the subtarget. 1244 unsigned getMaxFlatWorkGroupSize() const override { 1245 return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this); 1246 } 1247 1248 /// \returns Number of waves per execution unit required to support the given 1249 /// \p FlatWorkGroupSize. 1250 unsigned 1251 getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const override { 1252 return AMDGPU::IsaInfo::getWavesPerEUForWorkGroup(this, FlatWorkGroupSize); 1253 } 1254 1255 /// \returns Minimum number of waves per execution unit supported by the 1256 /// subtarget. 1257 unsigned getMinWavesPerEU() const override { 1258 return AMDGPU::IsaInfo::getMinWavesPerEU(this); 1259 } 1260 1261 void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx, 1262 SDep &Dep) const override; 1263 1264 // \returns true if it's beneficial on this subtarget for the scheduler to 1265 // cluster stores as well as loads. 1266 bool shouldClusterStores() const { return getGeneration() >= GFX11; } 1267 }; 1268 1269 } // end namespace llvm 1270 1271 #endif // LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H 1272