[llvm-branch-commits] [llvm] AMDGPU: Remove xnack and sramecc subtarget features (PR #212792)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jul 29 08:18:02 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
Now that these are controlled by module flags, the subtarget
features were just used for assembler and disassembler controls.
Now that the assembler and disassembler can infer these from
the e_flags and target directives, they are no longer necessary.
Co-authored-by: Claude (Opus 4.8) <noreply@<!-- -->anthropic.com>
---
Patch is 59.89 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/212792.diff
27 Files Affected:
- (modified) llvm/docs/AMDGPUUsage.rst (+7)
- (modified) llvm/lib/Target/AMDGPU/AMDGPU.td (+2-24)
- (modified) llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td (+1-1)
- (modified) llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (+1-2)
- (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+20-6)
- (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h (+2-3)
- (modified) llvm/lib/Target/AMDGPU/GCNSubtarget.h (+1-3)
- (modified) llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp (+1-2)
- (modified) llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp (+27-71)
- (modified) llvm/lib/TargetParser/AMDGPUTargetParser.cpp (+29-8)
- (modified) llvm/test/MC/AMDGPU/amdgcn-target-directive-conflict.s (+30-16)
- (modified) llvm/test/MC/AMDGPU/amdgcn_target_directive_from_eflags.s (+44-14)
- (modified) llvm/test/MC/AMDGPU/hsa-diag-v4.s (+4-4)
- (modified) llvm/test/MC/AMDGPU/hsa-tg-split.s (+2-2)
- (modified) llvm/test/MC/AMDGPU/hsa-v4.s (+2-2)
- (modified) llvm/test/MC/AMDGPU/hsa-v5-uses-dynamic-stack.s (+4-4)
- (modified) llvm/test/MC/AMDGPU/user-sgpr-count.s (+1-1)
- (modified) llvm/test/MC/AMDGPU/xnack-mask.s (+3-3)
- (modified) llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-cov5.s (+3-3)
- (modified) llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx10.s (+16-12)
- (modified) llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx90a.s (+12-9)
- (modified) llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx950.s (+5-3)
- (modified) llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-sgpr.s (+12-9)
- (modified) llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-vgpr.s (+12-9)
- (modified) llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx10.s (+2-1)
- (modified) llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx9.s (+4-3)
- (modified) llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-raw.s (+5-3)
``````````diff
diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst
index 2a4f290effc6d..4f91f7ffb69ac 100644
--- a/llvm/docs/AMDGPUUsage.rst
+++ b/llvm/docs/AMDGPUUsage.rst
@@ -1014,6 +1014,13 @@ consumed by the AMDGPU backend during code generation.
produce an error. Modules with **any** (absent flag) are compatible
with any setting.
+ XNACK is disabled if ``SH_MEM_CONFIG.ADDRESS_MODE = GPUVM`` on chips
+ that support XNACK. The current default kernel driver setting is XNACK
+ disabled on the graphics ring and XNACK enabled on the compute ring.
+ If XNACK is enabled, the VMEM latency can be worse. If XNACK is
+ disabled, the 2 SGPRs otherwise reserved for the XNACK mask can be used
+ for general purposes.
+
* - ``amdgpu.sramecc``
- ``i32``
- Error
diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.td b/llvm/lib/Target/AMDGPU/AMDGPU.td
index fbfd0e2f6937f..374204f7224dc 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPU.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPU.td
@@ -223,21 +223,6 @@ defm XNACKOnOffModes : AMDGPUSubtargetFeature<"xnack-on-off-modes",
InlineIgnore
>;
-// XNACK is disabled if SH_MEM_CONFIG.ADDRESS_MODE = GPUVM on chips that support
-// XNACK. The current default kernel driver setting is:
-// - graphics ring: XNACK disabled
-// - compute ring: XNACK enabled
-//
-// If XNACK is enabled, the VMEM latency can be worse.
-// If XNACK is disabled, the 2 SGPRs can be used for general purposes.
-def FeatureXNACK : SubtargetFeature<"xnack",
- "EnableXNACK",
- "true",
- "Enable XNACK support",
- [FeatureSupportsXNACK],
- InlineIgnore
->;
-
def FeatureCuMode : SubtargetFeature<"cumode",
"EnableCuMode",
"true",
@@ -1080,12 +1065,6 @@ def FeatureSupportsSRAMECC : SubtargetFeature<"sramecc-support",
[], InlineIgnore
>;
-def FeatureSRAMECC : SubtargetFeature<"sramecc",
- "EnableSRAMECC",
- "true",
- "Enable SRAMECC"
->;
-
defm NoSdstCMPX : AMDGPUSubtargetFeature<"no-sdst-cmpx",
"V_CMPX does not write VCC/SGPR in addition to EXEC"
>;
@@ -2273,7 +2252,7 @@ def FeatureISAVersion12_50_Common : FeatureSet<
FeatureSetPrioIncWgInst,
FeatureSWakeupBarrier,
Feature45BitNumRecordsBufferResource,
- FeatureXNACK,
+ FeatureSupportsXNACK,
FeatureClusters,
FeatureD16Writes32BitVgpr,
FeatureMcastLoadInsts,
@@ -2347,7 +2326,6 @@ def FeatureISAVersion12_5_Generic: FeatureSet<
[FeatureAddressableLocalMemorySize327680,
FeatureSetregVGPRMSBFixup,
FeatureRequiresCOV6,
- FeatureSupportsXNACK,
FeatureGFX125xLowestRateWMMA,
FeatureTransCoexecutionHazard,
FeatureWMMACoexecutionHazards,
@@ -2799,7 +2777,7 @@ def HasUnrestrictedSOffset : Predicate<"!Subtarget->hasRestrictedSOffset()">,
def D16PreservesUnusedBits :
Predicate<"Subtarget->d16PreservesUnusedBits()">,
- AssemblerPredicate<(all_of FeatureGFX9Insts, (not FeatureSRAMECC))>;
+ AssemblerPredicate<(all_of FeatureGFX9Insts, (not FeatureSupportsSRAMECC))>;
def LDSRequiresM0Init : Predicate<"Subtarget->ldsRequiresM0Init()">;
def NotLDSRequiresM0Init : Predicate<"!Subtarget->ldsRequiresM0Init()">;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
index d03493d924b13..a11dd460407ca 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
// FIXME: These duplicate real SubtargetFeatures and should be unified
-// (e.g. FEATURE_XNACK mirrors FeatureXNACK).
+// (e.g. R600_FEATURE_FMA mirrors FeatureFMA).
class AMDGPUArchFeature<string spelling> {
string Spelling = spelling;
}
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index d3027d831aaf1..f040f07fb81dc 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -6297,8 +6297,7 @@ bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
return Error(IDRange.Start, "directive requires gfx8+", IDRange);
if (!isUInt<1>(Val))
return OutOfRangeError(ValRange);
- bool XnackOn = getTargetStreamer().getTargetID()->isXnackOnOrAny() ||
- getSTI().hasFeature(AMDGPU::FeatureXNACK);
+ bool XnackOn = getTargetStreamer().getTargetID()->isXnackOnOrAny();
if (Val != XnackOn) {
return getParser().Error(
IDRange.Start,
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index c9f4624014a5e..eb7999f102a6f 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -60,6 +60,7 @@ AMDGPUDisassembler::AMDGPUDisassembler(const MCSubtargetInfo &STI,
MAI(Ctx.getAsmInfo()),
HwModeRegClass(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)),
TargetMaxInstBytes(MAI.getMaxInstLength(&STI)),
+ TargetID(AMDGPU::createAMDGPUTargetID(STI, "")),
CodeObjectVersion(AMDGPU::getDefaultAMDHSACodeObjectVersion()) {
// ToDo: AMDGPUDisassembler supports only VI ISA.
if (!STI.hasFeature(AMDGPU::FeatureGCN3Encoding) && !isGFX10Plus())
@@ -98,32 +99,46 @@ void AMDGPUDisassembler::emitTargetIDIfSupported(raw_ostream &OS,
}
#undef X
- // Add xnack and sramecc from ELF flags (v4 format)
+ // Add xnack and sramecc from ELF flags (v4 format), recording the decoded
+ // modes in TargetID for later use (e.g. .amdhsa_reserve_xnack_mask).
if (CodeObjectVersion >= AMDGPU::AMDHSA_COV4) {
unsigned SrameccSetting = EFlags & ELF::EF_AMDGPU_FEATURE_SRAMECC_V4;
switch (SrameccSetting) {
case ELF::EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
+ break;
case ELF::EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
+ TargetID.setSramEccSetting(AMDGPU::TargetIDSetting::Any);
break;
case ELF::EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
+ TargetID.setSramEccSetting(AMDGPU::TargetIDSetting::Off);
OS << ":sramecc-";
break;
case ELF::EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
+ TargetID.setSramEccSetting(AMDGPU::TargetIDSetting::On);
OS << ":sramecc+";
break;
}
+ // Targets that hardwire xnack on (e.g. gfx1250) don't expose it as a
+ // selectable modifier, so don't print it.
+ bool XnackHardwiredOn = TargetID.isXnackSupported() &&
+ !STI.hasFeature(AMDGPU::FeatureXNACKOnOffModes);
unsigned XnackSetting = EFlags & ELF::EF_AMDGPU_FEATURE_XNACK_V4;
switch (XnackSetting) {
case ELF::EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
+ break;
case ELF::EF_AMDGPU_FEATURE_XNACK_ANY_V4:
+ TargetID.setXnackSetting(AMDGPU::TargetIDSetting::Any);
break;
case ELF::EF_AMDGPU_FEATURE_XNACK_OFF_V4:
- OS << ":xnack-";
+ TargetID.setXnackSetting(AMDGPU::TargetIDSetting::Off);
+ if (!XnackHardwiredOn)
+ OS << ":xnack-";
break;
case ELF::EF_AMDGPU_FEATURE_XNACK_ON_V4:
- OS << ":xnack+";
- XnackOnFromEFlags = true;
+ TargetID.setXnackSetting(AMDGPU::TargetIDSetting::On);
+ if (!XnackHardwiredOn)
+ OS << ":xnack+";
break;
}
}
@@ -2472,8 +2487,7 @@ Expected<bool> AMDGPUDisassembler::decodeCOMPUTE_PGM_RSRC1(
// Only print the directive on xnack-supporting targets (matching the
// asmprinter), unless the binary erronously set xnack on an unsupported
// target
- bool ReservedXnackMask =
- STI.hasFeature(AMDGPU::FeatureXNACK) || XnackOnFromEFlags;
+ bool ReservedXnackMask = TargetID.isXnackOnOrAny();
if (STI.hasFeature(AMDGPU::FeatureSupportsXNACK) || ReservedXnackMask) {
KdStream << Indent << ".amdhsa_reserve_xnack_mask " << ReservedXnackMask
<< '\n';
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
index c38637020782a..5277de4cacff4 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
@@ -22,6 +22,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/Support/DataExtractor.h"
+#include "llvm/TargetParser/AMDGPUTargetParser.h"
#include <memory>
namespace llvm {
@@ -47,9 +48,7 @@ class AMDGPUDisassembler : public MCDisassembler {
mutable uint64_t Literal;
mutable bool HasLiteral;
mutable std::optional<bool> EnableWavefrontSize32;
-
- // If the object's ELF e_flags enable xnack. TODO: Replace with TargetID
- mutable bool XnackOnFromEFlags = false;
+ mutable AMDGPU::TargetID TargetID;
unsigned CodeObjectVersion;
const MCExpr *UCVersionW64Expr;
const MCExpr *UCVersionW32Expr;
diff --git a/llvm/lib/Target/AMDGPU/GCNSubtarget.h b/llvm/lib/Target/AMDGPU/GCNSubtarget.h
index c7937d8d33ed5..647c36e7409a7 100644
--- a/llvm/lib/Target/AMDGPU/GCNSubtarget.h
+++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.h
@@ -352,9 +352,7 @@ class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
return HasUnalignedScratchAccess && HasUnalignedAccessMode;
}
- bool isXNACKEnabled() const {
- return enableXNACK() || TargetID.isXnackOnOrAny();
- }
+ bool isXNACKEnabled() const { return TargetID.isXnackOnOrAny(); }
bool hasRelaxedBufferOOBMode() const { return BufferOOBRelaxed; }
bool hasRelaxedTBufferOOBMode() const { return TBufferOOBRelaxed; }
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
index ea752e44b7fad..b5cedeaf6321e 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
@@ -564,8 +564,7 @@ void AMDGPUTargetAsmStreamer::EmitAmdhsaKernelDescriptor(
case AMDGPU::AMDHSA_COV4:
case AMDGPU::AMDHSA_COV5:
if (STI.hasFeature(AMDGPU::FeatureSupportsXNACK)) {
- bool XnackOn = getTargetID()->isXnackOnOrAny() ||
- STI.hasFeature(AMDGPU::FeatureXNACK);
+ bool XnackOn = getTargetID()->isXnackOnOrAny();
OS << "\t\t.amdhsa_reserve_xnack_mask " << XnackOn << '\n';
}
break;
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 25b36d99960a1..b271e3ebefd34 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -1086,75 +1086,25 @@ VOPD::InstInfo getVOPDInstInfo(unsigned VOPDOpcode,
TargetID createAMDGPUTargetID(const MCSubtargetInfo &STI,
StringRef FeatureString) {
- TargetID TargetID(parseArchAMDGCN(STI.getCPU()), STI.getTargetTriple(),
- STI.getFeatureBits().test(FeatureXNACKOnOffModes)
- ? TargetIDSetting::Any
- : TargetIDSetting::Unsupported,
- STI.getFeatureBits().test(FeatureSupportsSRAMECC)
- ? TargetIDSetting::Any
- : TargetIDSetting::Unsupported);
-
- // Check if xnack or sramecc is explicitly enabled or disabled. In the
- // absence of the target features we assume we must generate code that can run
- // in any environment.
- SubtargetFeatures Features(FeatureString);
- std::optional<bool> XnackRequested;
- std::optional<bool> SramEccRequested;
-
- for (const std::string &Feature : Features.getFeatures()) {
- if (Feature == "+xnack")
- XnackRequested = true;
- else if (Feature == "-xnack")
- XnackRequested = false;
- else if (Feature == "+sramecc")
- SramEccRequested = true;
- else if (Feature == "-sramecc")
- SramEccRequested = false;
- }
-
- // Only allow changing xnack setting if the target supports on/off modes.
- // Targets without on/off mode support keep their initial setting
- // (Unsupported).
-
- bool XnackSupported = STI.getFeatureBits().test(FeatureXNACKOnOffModes);
- bool SramEccSupported = TargetID.isSramEccSupported();
-
- if (XnackRequested) {
- if (XnackSupported) {
- TargetID.setXnackSetting(*XnackRequested ? TargetIDSetting::On
- : TargetIDSetting::Off);
- } else {
- // If a specific xnack setting was requested and this GPU does not support
- // xnack emit a warning. Setting will remain set to "Unsupported".
- if (*XnackRequested) {
- errs() << "warning: xnack 'On' was requested for a processor that does "
- "not support it!\n";
- } else {
- errs() << "warning: xnack 'Off' was requested for a processor that "
- "does not support it!\n";
- }
- }
- }
-
- if (SramEccRequested) {
- if (SramEccSupported) {
- TargetID.setSramEccSetting(*SramEccRequested ? TargetIDSetting::On
- : TargetIDSetting::Off);
- } else {
- // If a specific sramecc setting was requested and this GPU does not
- // support sramecc emit a warning. Setting will remain set to
- // "Unsupported".
- if (*SramEccRequested) {
- errs() << "warning: sramecc 'On' was requested for a processor that "
- "does not support it!\n";
- } else {
- errs() << "warning: sramecc 'Off' was requested for a processor that "
- "does not support it!\n";
- }
- }
- }
+ // xnack/sramecc are derived from capability features alone; the actual mode
+ // comes later from module flags / directives / e_flags. A target supporting
+ // xnack without on/off modes has it hardwired On (gfx1250).
+ bool SupportsXNACK = STI.getFeatureBits().test(FeatureSupportsXNACK);
+ bool XNACKOnOffModes = STI.getFeatureBits().test(FeatureXNACKOnOffModes);
+
+ TargetIDSetting XnackSetting;
+ if (!SupportsXNACK)
+ XnackSetting = TargetIDSetting::Unsupported;
+ else if (XNACKOnOffModes)
+ XnackSetting = TargetIDSetting::Any;
+ else
+ XnackSetting = TargetIDSetting::On;
- return TargetID;
+ return TargetID(parseArchAMDGCN(STI.getCPU()), STI.getTargetTriple(),
+ XnackSetting,
+ STI.getFeatureBits().test(FeatureSupportsSRAMECC)
+ ? TargetIDSetting::Any
+ : TargetIDSetting::Unsupported);
}
namespace IsaInfo {
@@ -1353,8 +1303,11 @@ unsigned getNumExtraSGPRs(const MCSubtargetInfo &STI, bool VCCUsed,
unsigned getNumExtraSGPRs(const MCSubtargetInfo &STI, bool VCCUsed,
bool FlatScrUsed) {
- return getNumExtraSGPRs(STI, VCCUsed, FlatScrUsed,
- STI.getFeatureBits().test(AMDGPU::FeatureXNACK));
+ // Without a TargetID mode, only hardwired-on xnack (gfx1250) is knowable from
+ // the subtarget, and it reserves SGPRs.
+ bool XNACKUsed = STI.getFeatureBits().test(AMDGPU::FeatureSupportsXNACK) &&
+ !STI.getFeatureBits().test(AMDGPU::FeatureXNACKOnOffModes);
+ return getNumExtraSGPRs(STI, VCCUsed, FlatScrUsed, XNACKUsed);
}
static unsigned getGranulatedNumRegisterBlocks(unsigned NumRegs,
@@ -2478,7 +2431,10 @@ unsigned getDynamicVGPRBlockSize(const Function &F) {
}
bool hasXNACK(const MCSubtargetInfo &STI) {
- return STI.hasFeature(AMDGPU::FeatureXNACK);
+ // Only hardwired-on xnack (gfx1250) is knowable from the subtarget alone;
+ // toggleable targets take their mode from the TargetID.
+ return STI.hasFeature(AMDGPU::FeatureSupportsXNACK) &&
+ !STI.hasFeature(AMDGPU::FeatureXNACKOnOffModes);
}
bool hasMIMG_R128(const MCSubtargetInfo &STI) {
diff --git a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
index de6ed11f2d242..93263eda87300 100644
--- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
+++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
@@ -1059,9 +1059,14 @@ static bool computeTargetIDFeatures(GPUKind Arch, StringRef TargetIDStr,
TargetIDSetting &XnackSetting,
TargetIDSetting &SramEccSetting) {
unsigned ArchAttr = getArchAttrAMDGCN(Arch);
- XnackSetting = (ArchAttr & FEATURE_XNACK_ON_OFF_MODES)
- ? TargetIDSetting::Any
- : TargetIDSetting::Unsupported;
+ // xnack with on/off modes defaults to Any; supported without on/off modes is
+ // hardwired On (e.g. gfx1250); unsupported is Unsupported.
+ if (!(ArchAttr & FEATURE_XNACK))
+ XnackSetting = TargetIDSetting::Unsupported;
+ else if (ArchAttr & FEATURE_XNACK_ON_OFF_MODES)
+ XnackSetting = TargetIDSetting::Any;
+ else
+ XnackSetting = TargetIDSetting::On;
SramEccSetting = (ArchAttr & FEATURE_SRAMECC) ? TargetIDSetting::Any
: TargetIDSetting::Unsupported;
@@ -1076,7 +1081,9 @@ static bool computeTargetIDFeatures(GPUKind Arch, StringRef TargetIDStr,
StringRef FeatureString = Split[I];
if (FeatureString.consume_front("xnack")) {
TargetIDSetting Sign = getTargetIDSettingFromFeatureString(FeatureString);
- if (SeenXnack || XnackSetting == TargetIDSetting::Unsupported ||
+ // An xnack modifier is only valid with on/off modes: rejected when xnack
+ // is unsupported or hardwired on (e.g. gfx1250).
+ if (SeenXnack || !(ArchAttr & FEATURE_XNACK_ON_OFF_MODES) ||
Sign == TargetIDSetting::Unsupported)
Valid = false;
else
@@ -1147,15 +1154,27 @@ TargetID::parseTargetIDString(StringRef TargetIDDirective) {
return parse(Triple(Parts[0], Parts[1], Parts[2], Parts[3]), Parts[4]);
}
+// Returns true if \p Arch hardwires xnack on (supports xnack but has no on/off
+// modes, e.g. gfx1250), so xnack is not a selectable target-id modifier.
+static bool isXnackHardwiredOn(GPUKind Arch) {
+ unsigned ArchAttr = getArchAttrAMDGCN(Arch);
+ return (ArchAttr & FEATURE_XNACK) && !(ArchAttr & FEATURE_XNACK_ON_OFF_MODES);
+}
+
// Append the explicit (On/Off) sramecc/xnack feature modifiers in canonical
-// order, e.g. ":sramecc-:xnack+".
+// order, e.g. ":sramecc-:xnack+". Xnack is never emitted for hardwired-on
+// targets.
static void printFeatureModifiers(raw_ostream &OS, TargetIDSetting SramEcc,
- TargetIDSetting Xnack) {
+ TargetIDSetting Xnack,
+ bool XnackHardwiredOn) {
if (SramEcc == TargetIDSetting::Off)
OS << ":sramecc-";
else if (SramEcc == TargetIDSetting::On)
OS << ":sramecc+";
+ if (XnackHardwiredOn)
+ return;
+
if (Xnack == TargetIDSetting::Off)
OS << ":xnack-";
else if (Xnack == TargetIDSetting::On)
@@ -1166,7 +1185,8 @@ void TargetID::print(raw_ostream &StreamRep) const {
StreamRep << TargetTripleString << '-' << getArchNameAMDGCN(Arch);
if (IsAMDHSA)
- printFeatureModifiers(StreamRep, getSramEccSetting(), getXnackSetting());
+ printFeatureModifiers(StreamRep, getSramEccSetting(), getXnackSetting(),
+ isXnackHardwiredOn(Arch));
}
std::string TargetID::toString() const {
@@ -1178,7 +1198,8 @@ std::string TargetID::toString() const {
void TargetID::printCanonicalTargetIDString(raw_ostream &OS) const {
OS << getArchNameAMDGCN(Arch);
- printFeatureModifiers(OS, getSramEccSetting(), getXnackSetting());
+ printFeatureModifiers(OS, getSramEccSetting(), getXnackSetting(),
+ isXnackHardwiredOn(Arch));
}
std::string TargetID::getCanonicalFeatureString() const {
diff --git a/llvm/test/MC/AMDGPU/amdgcn-target-directive-conflict.s b/llvm/test/MC/AMDGPU/amdgcn-target-directive-conflict.s
index 4a93666474116..73cc40fab9e41 100644
--- a/llvm/test/MC/AMDGPU/amdgcn-target-directive-conflict.s
+++ b/llvm/test/MC/AMDGPU/amdgcn-target-directive-conflict.s
@@ -1,55 +1,69 @@
// RUN: split-file %s %t
// Test that .amdgcn_target emits separate warnings for conflicting xnack and
-// sramecc settings between the directive and the command line.
+// sramecc settings between two .amdgcn_target directives. The first directive
+// establishes the target id's xnack/sramecc modes; a second directive with
+// different specific modes conflicts.
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -mattr=+xnack,+sramecc %t/xnack.s 2>&1 | FileCheck --check-prefix=XNACK --implicit-check-not=warning %s
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -m...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/212792
More information about the llvm-branch-commits
mailing list