[llvm-branch-commits] [clang] [lld] [llvm] AMDGPU: Remove xnack and sramecc subtarget features (PR #212792)

Matt Arsenault via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Aug 8 06:56:50 PDT 2026


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/212792

>From 884e8f6c725096fc2108bc80b9c0eb8190696af5 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 28 Jul 2026 23:14:28 +0200
Subject: [PATCH 1/2] AMDGPU: Remove xnack and sramecc subtarget features

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 at anthropic.com>
---
 .../Driver/amdgpu-assembler-xnack-sramecc.s   | 53 +++++-----
 lld/test/ELF/amdgpu-tid.s                     | 44 ++++++---
 llvm/docs/AMDGPUUsage.rst                     |  7 ++
 llvm/lib/Target/AMDGPU/AMDGPU.td              | 26 +----
 llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td  |  2 +-
 .../AMDGPU/AsmParser/AMDGPUAsmParser.cpp      |  3 +-
 .../Disassembler/AMDGPUDisassembler.cpp       | 23 ++++-
 .../AMDGPU/Disassembler/AMDGPUDisassembler.h  |  5 +-
 llvm/lib/Target/AMDGPU/GCNSubtarget.h         |  4 +-
 .../MCTargetDesc/AMDGPUTargetStreamer.cpp     |  3 +-
 .../Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp    | 98 +++++--------------
 llvm/lib/TargetParser/AMDGPUTargetParser.cpp  | 37 +++++--
 .../AMDGPU/amdgcn-target-directive-conflict.s | 46 ++++++---
 .../amdgcn_target_directive_from_eflags.s     | 58 ++++++++---
 llvm/test/MC/AMDGPU/hsa-diag-v4.s             |  8 +-
 llvm/test/MC/AMDGPU/hsa-tg-split.s            |  4 +-
 llvm/test/MC/AMDGPU/hsa-v4.s                  |  4 +-
 .../MC/AMDGPU/hsa-v5-uses-dynamic-stack.s     |  8 +-
 llvm/test/MC/AMDGPU/user-sgpr-count.s         |  2 +-
 llvm/test/MC/AMDGPU/xnack-mask.s              |  6 +-
 .../tools/llvm-objdump/ELF/AMDGPU/kd-cov5.s   |  6 +-
 .../tools/llvm-objdump/ELF/AMDGPU/kd-gfx10.s  | 28 +++---
 .../tools/llvm-objdump/ELF/AMDGPU/kd-gfx90a.s | 21 ++--
 .../tools/llvm-objdump/ELF/AMDGPU/kd-gfx950.s |  8 +-
 .../tools/llvm-objdump/ELF/AMDGPU/kd-sgpr.s   | 21 ++--
 .../tools/llvm-objdump/ELF/AMDGPU/kd-vgpr.s   | 21 ++--
 .../llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx10.s |  3 +-
 .../llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx9.s  |  7 +-
 .../llvm-objdump/ELF/AMDGPU/kd-zeroed-raw.s   |  8 +-
 29 files changed, 309 insertions(+), 255 deletions(-)

diff --git a/clang/test/Driver/amdgpu-assembler-xnack-sramecc.s b/clang/test/Driver/amdgpu-assembler-xnack-sramecc.s
index d1c495e681f06..3f72014753512 100644
--- a/clang/test/Driver/amdgpu-assembler-xnack-sramecc.s
+++ b/clang/test/Driver/amdgpu-assembler-xnack-sramecc.s
@@ -1,33 +1,38 @@
 // REQUIRES: amdgpu-registered-target
 
 /// Assembling a .s file that has no target ID directive (.amdgcn_target). The
-/// xnack/sramecc mode requested on the command line, either with
-/// -mxnack/-msramecc or via the -mcpu target ID modifiers, is forwarded to the
-/// assembler as a target feature and recorded in the object's e_flags.
+/// xnack/sramecc mode is a property of the assembly / object, so specifying it
+/// on the command line, either with -mxnack/-msramecc or via the -mcpu target
+/// ID modifiers, is not preserved: the driver no longer forwards these to the
+/// assembler, and the resulting object uses the "any" setting in its e_flags.
+/// To pin a mode, the .s file must contain a .amdgcn_target directive.
 
-/// The mode is forwarded to the assembler as a target feature.
 // RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -mno-xnack -c %s 2>&1 | \
-// RUN:   FileCheck -check-prefix=XNACK-OFF %s
-// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906:xnack- -c %s 2>&1 | \
-// RUN:   FileCheck -check-prefix=XNACK-OFF %s
-// XNACK-OFF: "-cc1as"
-// XNACK-OFF-SAME: "-target-feature" "-xnack"
+// RUN:   FileCheck -check-prefix=CC1AS %s
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -mxnack -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=CC1AS %s
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -mno-sramecc -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=CC1AS %s
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906:xnack+ -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=CC1AS %s
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906:sramecc- -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=CC1AS %s
 
-// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -msramecc -c %s 2>&1 | \
-// RUN:   FileCheck -check-prefix=SRAMECC-ON %s
-// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906:sramecc+ -c %s 2>&1 | \
-// RUN:   FileCheck -check-prefix=SRAMECC-ON %s
-// SRAMECC-ON: "-cc1as"
-// SRAMECC-ON-SAME: "-target-feature" "+sramecc"
+/// The assembler is invoked with the plain target-cpu and no xnack/sramecc
+/// target feature.
+// CC1AS: "-cc1as"
+// CC1AS-SAME: "-target-cpu" "gfx906"
+// CC1AS-NOT: "-target-feature"
+
+/// End to end: the mode requested on the command line is not reflected in the
+/// object, which keeps the "any" xnack/sramecc e_flags.
+// RUN: %clang --target=amdgcn-amd-amdhsa -mcpu=gfx906 -mno-xnack -c %s -o %t.o 2>&1 | \
+// RUN:   FileCheck -check-prefix=UNUSED %s
+// RUN: llvm-readobj --file-headers %t.o | FileCheck -check-prefix=ANY %s
 
-/// End to end: the requested mode is reflected in the object's e_flags.
-// RUN: %clang --target=amdgcn-amd-amdhsa -mcpu=gfx906 -mno-xnack -c %s -o %t.o
-// RUN: llvm-readobj --file-headers %t.o | FileCheck -check-prefix=OBJ-XNACK-OFF %s
 // RUN: %clang --target=amdgcn-amd-amdhsa -mcpu=gfx906:xnack+ -c %s -o %t.o
-// RUN: llvm-readobj --file-headers %t.o | FileCheck -check-prefix=OBJ-XNACK-ON %s
-// RUN: %clang --target=amdgcn-amd-amdhsa -mcpu=gfx906:sramecc- -c %s -o %t.o
-// RUN: llvm-readobj --file-headers %t.o | FileCheck -check-prefix=OBJ-SRAMECC-OFF %s
+// RUN: llvm-readobj --file-headers %t.o | FileCheck -check-prefix=ANY %s
 
-// OBJ-XNACK-OFF: EF_AMDGPU_FEATURE_XNACK_OFF_V4 (0x200)
-// OBJ-XNACK-ON: EF_AMDGPU_FEATURE_XNACK_ON_V4 (0x300)
-// OBJ-SRAMECC-OFF: EF_AMDGPU_FEATURE_SRAMECC_OFF_V4 (0x800)
+// UNUSED: warning: argument unused during compilation: '-mno-xnack'
+// ANY: EF_AMDGPU_FEATURE_SRAMECC_ANY_V4 (0x400)
+// ANY: EF_AMDGPU_FEATURE_XNACK_ANY_V4 (0x100)
diff --git a/lld/test/ELF/amdgpu-tid.s b/lld/test/ELF/amdgpu-tid.s
index 66d04d85243f2..630266d16b2e2 100644
--- a/lld/test/ELF/amdgpu-tid.s
+++ b/lld/test/ELF/amdgpu-tid.s
@@ -1,16 +1,18 @@
 # REQUIRES: amdgpu
 
-# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa -mattr=-xnack --amdhsa-code-object-version=4 -filetype=obj %s -o %t-xnack-off0.o
-# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa -mattr=-xnack --amdhsa-code-object-version=4 -filetype=obj %s -o %t-xnack-off1.o
+# RUN: split-file %s %t
+
+# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %t/xnack-off.s -o %t-xnack-off0.o
+# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %t/xnack-off.s -o %t-xnack-off1.o
 # RUN: ld.lld -shared %t-xnack-off0.o %t-xnack-off1.o -o %t-xnack-off2.so
 # RUN: llvm-readobj --file-headers %t-xnack-off2.so | FileCheck --check-prefix=XNACK-OFF %s
 
-# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa -mattr=+xnack --amdhsa-code-object-version=4 -filetype=obj %s -o %t-xnack-on0.o
-# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa -mattr=+xnack --amdhsa-code-object-version=4 -filetype=obj %s -o %t-xnack-on1.o
+# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %t/xnack-on.s -o %t-xnack-on0.o
+# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %t/xnack-on.s -o %t-xnack-on1.o
 # RUN: ld.lld -shared %t-xnack-on0.o %t-xnack-on1.o -o %t-xnack-on2.so
 # RUN: llvm-readobj --file-headers %t-xnack-on2.so | FileCheck --check-prefix=XNACK-ON %s
 
-# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %s -o %t-xnack-any.o
+# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %t/empty.s -o %t-xnack-any.o
 # RUN: ld.lld -shared %t-xnack-off0.o %t-xnack-any.o -o %t-xnack-off3.so
 # RUN: llvm-readobj --file-headers %t-xnack-off3.so | FileCheck --check-prefix=XNACK-OFF %s
 # RUN: ld.lld -shared %t-xnack-on0.o %t-xnack-any.o -o %t-xnack-on3.so
@@ -22,17 +24,17 @@
 # XNACK-ON:           EF_AMDGPU_FEATURE_XNACK_ON_V4 (0x300)
 # XNACK-INCOMPATIBLE: incompatible xnack:
 
-# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa -mattr=-sramecc --amdhsa-code-object-version=4 -filetype=obj %s -o %t-sramecc-off0.o
-# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa -mattr=-sramecc --amdhsa-code-object-version=4 -filetype=obj %s -o %t-sramecc-off1.o
+# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %t/sramecc-off.s -o %t-sramecc-off0.o
+# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %t/sramecc-off.s -o %t-sramecc-off1.o
 # RUN: ld.lld -shared %t-sramecc-off0.o %t-sramecc-off1.o -o %t-sramecc-off2.so
 # RUN: llvm-readobj --file-headers %t-sramecc-off2.so | FileCheck --check-prefix=SRAMECC-OFF %s
 
-# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa -mattr=+sramecc --amdhsa-code-object-version=4 -filetype=obj %s -o %t-sramecc-on0.o
-# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa -mattr=+sramecc --amdhsa-code-object-version=4 -filetype=obj %s -o %t-sramecc-on1.o
+# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %t/sramecc-on.s -o %t-sramecc-on0.o
+# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %t/sramecc-on.s -o %t-sramecc-on1.o
 # RUN: ld.lld -shared %t-sramecc-on0.o %t-sramecc-on1.o -o %t-sramecc-on2.so
 # RUN: llvm-readobj --file-headers %t-sramecc-on2.so | FileCheck --check-prefix=SRAMECC-ON %s
 
-# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %s -o %t-sramecc-any.o
+# RUN: llvm-mc -triple amdgpu9.06-amd-amdhsa --amdhsa-code-object-version=4 -filetype=obj %t/empty.s -o %t-sramecc-any.o
 # RUN: ld.lld -shared %t-sramecc-off0.o %t-sramecc-any.o -o %t-sramecc-off3.so
 # RUN: llvm-readobj --file-headers %t-sramecc-off3.so | FileCheck --check-prefix=SRAMECC-OFF %s
 # RUN: ld.lld -shared %t-sramecc-on0.o %t-sramecc-any.o -o %t-sramecc-on3.so
@@ -44,13 +46,13 @@
 # SRAMECC-ON:           EF_AMDGPU_FEATURE_SRAMECC_ON_V4 (0xC00)
 # SRAMECC-INCOMPATIBLE: incompatible sramecc:
 
-# RUN: llvm-mc -triple amdgpu9.00-amd-amdhsa --amdhsa-code-object-version=6 --amdgpu-force-generic-version=1 -filetype=obj %s -o %t-genericv1_0.o
-# RUN: llvm-mc -triple amdgpu9.00-amd-amdhsa --amdhsa-code-object-version=6 --amdgpu-force-generic-version=1 -filetype=obj %s -o %t-genericv1_1.o
+# RUN: llvm-mc -triple amdgpu9.00-amd-amdhsa --amdhsa-code-object-version=6 --amdgpu-force-generic-version=1 -filetype=obj %t/empty.s -o %t-genericv1_0.o
+# RUN: llvm-mc -triple amdgpu9.00-amd-amdhsa --amdhsa-code-object-version=6 --amdgpu-force-generic-version=1 -filetype=obj %t/empty.s -o %t-genericv1_1.o
 # RUN: ld.lld -shared %t-genericv1_0.o %t-genericv1_1.o -o %t-genericv1_2.so
 # RUN: llvm-readobj --file-headers %t-genericv1_2.so | FileCheck --check-prefix=GENERICV1 %s
 
-# RUN: llvm-mc -triple amdgpu9.00-amd-amdhsa --amdhsa-code-object-version=6 --amdgpu-force-generic-version=2 -filetype=obj %s -o %t-genericv2_0.o
-# RUN: llvm-mc -triple amdgpu9.00-amd-amdhsa --amdhsa-code-object-version=6 --amdgpu-force-generic-version=2 -filetype=obj %s -o %t-genericv2_1.o
+# RUN: llvm-mc -triple amdgpu9.00-amd-amdhsa --amdhsa-code-object-version=6 --amdgpu-force-generic-version=2 -filetype=obj %t/empty.s -o %t-genericv2_0.o
+# RUN: llvm-mc -triple amdgpu9.00-amd-amdhsa --amdhsa-code-object-version=6 --amdgpu-force-generic-version=2 -filetype=obj %t/empty.s -o %t-genericv2_1.o
 # RUN: ld.lld -shared %t-genericv2_0.o %t-genericv2_1.o -o %t-genericv2_2.so
 # RUN: llvm-readobj --file-headers %t-genericv2_2.so | FileCheck --check-prefix=GENERICV2 %s
 
@@ -59,3 +61,17 @@
 # GENERICV1:            EF_AMDGPU_GENERIC_VERSION_V1 (0x1000000)
 # GENERICV2:            EF_AMDGPU_GENERIC_VERSION_V2 (0x2000000)
 # GENERIC-INCOMPATIBLE: incompatible generic version
+
+#--- empty.s
+
+#--- xnack-off.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx906:xnack-"
+
+#--- xnack-on.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx906:xnack+"
+
+#--- sramecc-off.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx906:sramecc-"
+
+#--- sramecc-on.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx906:sramecc+"
diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst
index 87ba811e1a686..891952216a434 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 c909f2748e0b0..55fc77898965e 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
->;
-
 // Whether the hardware supports WGP (work-group processor) execution
 // mode, as opposed to the per-kernel CU-mode selection
 // (FeatureCuMode).
@@ -1135,12 +1120,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"
 >;
@@ -2351,7 +2330,7 @@ def FeatureISAVersion12_50_Common : FeatureSet<
    FeatureSetPrioIncWgInst,
    FeatureSWakeupBarrier,
    Feature45BitNumRecordsBufferResource,
-   FeatureXNACK,
+   FeatureSupportsXNACK,
    FeatureClusters,
    FeatureD16Writes32BitVgpr,
    FeatureMcastLoadInsts,
@@ -2425,7 +2404,6 @@ def FeatureISAVersion12_5_Generic: FeatureSet<
   [FeatureAddressableLocalMemorySize327680,
    FeatureSetregVGPRMSBFixup,
    FeatureRequiresCOV6,
-   FeatureSupportsXNACK,
    FeatureGFX125xLowestRateWMMA,
    FeatureTransCoexecutionHazard,
    FeatureWMMACoexecutionHazards,
@@ -2882,7 +2860,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 e6ea319017436..174c77fd14f44 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 4c3038db2c747..00bf48c835d08 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 c21a3df1471d9..dc6eb14fbb0cb 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())
@@ -103,27 +104,40 @@ void AMDGPUDisassembler::emitTargetIDIfSupported(raw_ostream &OS,
     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;
     }
   }
@@ -2484,8 +2498,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 4a8f7e66721b2..ec5fdb76c4568 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 c42ca8e19ef9c..db3bf50b7a2b8 100644
--- a/llvm/lib/Target/AMDGPU/GCNSubtarget.h
+++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.h
@@ -346,9 +346,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 463387f064ef0..806d8af72d100 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
@@ -566,8 +566,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 38329d6295538..5b0ce24d05fee 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 d8abaf7474cd6..1caa4db1a771b 100644
--- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
+++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
@@ -597,9 +597,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;
 
@@ -614,7 +619,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
@@ -685,15 +692,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)
@@ -704,7 +723,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 {
@@ -716,7 +736,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 -mattr=+xnack,+sramecc %t/sramecc.s 2>&1 | FileCheck --check-prefix=SRAMECC --implicit-check-not=warning %s
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -mattr=+xnack,+sramecc %t/both.s 2>&1 | FileCheck --check-prefix=BOTH --implicit-check-not=warning %s
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa %t/xnack.s 2>&1 | FileCheck --check-prefix=XNACK --implicit-check-not=warning %s
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa %t/sramecc.s 2>&1 | FileCheck --check-prefix=SRAMECC --implicit-check-not=warning %s
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa %t/both.s 2>&1 | FileCheck --check-prefix=BOTH --implicit-check-not=warning %s
 
-// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx908 -mattr=+xnack,+sramecc %t/xnack-legacy.s 2>&1 | FileCheck --check-prefix=XNACK-LEGACY --implicit-check-not=warning %s
-// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx908 -mattr=+xnack,+sramecc %t/sramecc-legacy.s 2>&1 | FileCheck --check-prefix=SRAMECC-LEGACY --implicit-check-not=warning %s
-// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx908 -mattr=+xnack,+sramecc %t/both-legacy.s 2>&1 | FileCheck --check-prefix=BOTH-LEGACY --implicit-check-not=warning %s
+// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx908 %t/xnack-legacy.s 2>&1 | FileCheck --check-prefix=XNACK-LEGACY --implicit-check-not=warning %s
+// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx908 %t/sramecc-legacy.s 2>&1 | FileCheck --check-prefix=SRAMECC-LEGACY --implicit-check-not=warning %s
+// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx908 %t/both-legacy.s 2>&1 | FileCheck --check-prefix=BOTH-LEGACY --implicit-check-not=warning %s
 
-// When the directive specifies modes but the command line leaves them
-// unspecified (Any), there is no conflict and no warning is emitted.
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa %t/both.s 2>&1 | FileCheck --check-prefix=NOCONFLICT --implicit-check-not=warning %s
+// When a single directive specifies modes and nothing conflicts, no warning is
+// emitted.
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa %t/noconflict.s 2>&1 | FileCheck --check-prefix=NOCONFLICT --implicit-check-not=warning %s
 
 // The object emission path honors the directive's xnack/sramecc settings in the
-// e_flags even when the command line does not specify them.
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/both.s -o %t/both.o
+// e_flags.
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/noconflict.s -o %t/both.o
 // RUN: llvm-readobj --file-headers %t/both.o | FileCheck --check-prefix=OBJ %s
 
-// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx908 -filetype=obj %t/both-legacy.s -o %t/both-legacy.o
+// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx908 -filetype=obj %t/noconflict-legacy.s -o %t/both-legacy.o
 // RUN: llvm-readobj --file-headers %t/both-legacy.o | FileCheck --check-prefix=OBJ-LEGACY %s
 
 //--- xnack.s
+.amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc+:xnack+"
 // XNACK: warning: .amdgcn_target directive has conflicting xnack settings
 .amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc+:xnack-"
 
 //--- sramecc.s
+.amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc+:xnack+"
 // SRAMECC: warning: .amdgcn_target directive has conflicting sramecc settings
 .amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc-:xnack+"
 
 //--- both.s
+.amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc+:xnack+"
 // BOTH: warning: .amdgcn_target directive has conflicting xnack settings
 // BOTH: warning: .amdgcn_target directive has conflicting sramecc settings
-// NOCONFLICT: .amdgcn_target "amdgpu9.08-amd-amdhsa-unknown-gfx908:sramecc-:xnack-"
-// OBJ: EF_AMDGPU_FEATURE_SRAMECC_OFF_V4 (0x800)
-// OBJ: EF_AMDGPU_FEATURE_XNACK_OFF_V4 (0x200)
 .amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc-:xnack-"
 
 //--- xnack-legacy.s
+.amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc+:xnack+"
 // XNACK-LEGACY: warning: .amdgcn_target directive has conflicting xnack settings
 .amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc+:xnack-"
 
 //--- sramecc-legacy.s
+.amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc+:xnack+"
 // SRAMECC-LEGACY: warning: .amdgcn_target directive has conflicting sramecc settings
 .amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc-:xnack+"
 
 //--- both-legacy.s
+.amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc+:xnack+"
 // BOTH-LEGACY: warning: .amdgcn_target directive has conflicting xnack settings
 // BOTH-LEGACY: warning: .amdgcn_target directive has conflicting sramecc settings
+.amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc-:xnack-"
+
+//--- noconflict.s
+// NOCONFLICT: .amdgcn_target "amdgpu9.08-amd-amdhsa-unknown-gfx908:sramecc-:xnack-"
+// OBJ: EF_AMDGPU_FEATURE_SRAMECC_OFF_V4 (0x800)
+// OBJ: EF_AMDGPU_FEATURE_XNACK_OFF_V4 (0x200)
+.amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc-:xnack-"
+
+//--- noconflict-legacy.s
 // NOCONFLICT-LEGACY: .amdgcn_target "amdgcn-amd-amdhsa-unknown-gfx908:sramecc-:xnack-"
 // OBJ-LEGACY: EF_AMDGPU_FEATURE_SRAMECC_OFF_V4 (0x800)
 // OBJ-LEGACY: EF_AMDGPU_FEATURE_XNACK_OFF_V4 (0x200)
diff --git a/llvm/test/MC/AMDGPU/amdgcn_target_directive_from_eflags.s b/llvm/test/MC/AMDGPU/amdgcn_target_directive_from_eflags.s
index 3fd643f200134..6a40519c48a5d 100644
--- a/llvm/test/MC/AMDGPU/amdgcn_target_directive_from_eflags.s
+++ b/llvm/test/MC/AMDGPU/amdgcn_target_directive_from_eflags.s
@@ -1,46 +1,50 @@
 // Test that llvm-objdump emits the .amdgcn_target directive based on e_flags.
+// The xnack/sramecc mode is encoded in the assembly via a .amdgcn_target
+// directive, which sets the object's e_flags; objdump reproduces it.
 
-// RUN: llvm-mc -triple=amdgpu9.00-amd-amdhsa -filetype=obj %s -o %t-gfx900.o
+// RUN: split-file %s %t
+
+// RUN: llvm-mc -triple=amdgpu9.00-amd-amdhsa -filetype=obj %t/plain.s -o %t-gfx900.o
 // RUN: llvm-objdump --disassemble-all %t-gfx900.o | FileCheck --check-prefix=CHECK-GFX900 %s
 
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %s -o %t-gfx908.o
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/plain.s -o %t-gfx908.o
 // RUN: llvm-objdump --disassemble-all %t-gfx908.o | FileCheck --check-prefix=CHECK-GFX908 %s
 
-// RUN: llvm-mc -triple=amdgpu10.10-amd-amdhsa -filetype=obj %s -o %t-gfx1010.o
+// RUN: llvm-mc -triple=amdgpu10.10-amd-amdhsa -filetype=obj %t/plain.s -o %t-gfx1010.o
 // RUN: llvm-objdump --disassemble-all %t-gfx1010.o | FileCheck --check-prefix=CHECK-GFX1010 %s
 
-// RUN: llvm-mc -triple=amdgpu11.00-amd-amdhsa -filetype=obj %s -o %t-gfx1100.o
+// RUN: llvm-mc -triple=amdgpu11.00-amd-amdhsa -filetype=obj %t/plain.s -o %t-gfx1100.o
 // RUN: llvm-objdump --disassemble-all %t-gfx1100.o | FileCheck --check-prefix=CHECK-GFX1100 %s
 
-// RUN: llvm-mc -triple=amdgpu12.00-amd-amdhsa -filetype=obj %s -o %t-gfx1200.o
+// RUN: llvm-mc -triple=amdgpu12.00-amd-amdhsa -filetype=obj %t/plain.s -o %t-gfx1200.o
 // RUN: llvm-objdump --disassemble-all %t-gfx1200.o | FileCheck --check-prefix=CHECK-GFX1200 %s
 
 // Test xnack/sramecc combinations
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %s -o %t-default.o
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/plain.s -o %t-default.o
 // RUN: llvm-objdump --disassemble-all %t-default.o | FileCheck --check-prefix=CHECK-DEFAULT %s
 
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -mattr=+xnack,+sramecc -filetype=obj %s -o %t-both-on.o
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/both-on.s -o %t-both-on.o
 // RUN: llvm-objdump --disassemble-all %t-both-on.o | FileCheck --check-prefix=CHECK-BOTH-ON %s
 
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -mattr=-xnack,-sramecc -filetype=obj %s -o %t-both-off.o
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/both-off.s -o %t-both-off.o
 // RUN: llvm-objdump --disassemble-all %t-both-off.o | FileCheck --check-prefix=CHECK-BOTH-OFF %s
 
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -mattr=+xnack,-sramecc -filetype=obj %s -o %t-xnack-on.o
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/xnack-on.s -o %t-xnack-on.o
 // RUN: llvm-objdump --disassemble-all %t-xnack-on.o | FileCheck --check-prefix=CHECK-XNACK-ON %s
 
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -mattr=-xnack,+sramecc -filetype=obj %s -o %t-sramecc-on.o
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/sramecc-on.s -o %t-sramecc-on.o
 // RUN: llvm-objdump --disassemble-all %t-sramecc-on.o | FileCheck --check-prefix=CHECK-SRAMECC-ON %s
 
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -mattr=+xnack -filetype=obj %s -o %t-xnack-only.o
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/xnack-only.s -o %t-xnack-only.o
 // RUN: llvm-objdump --disassemble-all %t-xnack-only.o | FileCheck --check-prefix=CHECK-XNACK-ONLY %s
 
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj %s -o %t-xnack-off-only.o
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/xnack-off-only.s -o %t-xnack-off-only.o
 // RUN: llvm-objdump --disassemble-all %t-xnack-off-only.o | FileCheck --check-prefix=CHECK-XNACK-OFF-ONLY %s
 
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -mattr=+sramecc -filetype=obj %s -o %t-sramecc-only.o
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/sramecc-only.s -o %t-sramecc-only.o
 // RUN: llvm-objdump --disassemble-all %t-sramecc-only.o | FileCheck --check-prefix=CHECK-SRAMECC-ONLY %s
 
-// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -mattr=-sramecc -filetype=obj %s -o %t-sramecc-off-only.o
+// RUN: llvm-mc -triple=amdgpu9.08-amd-amdhsa -filetype=obj %t/sramecc-off-only.s -o %t-sramecc-off-only.o
 // RUN: llvm-objdump --disassemble-all %t-sramecc-off-only.o | FileCheck --check-prefix=CHECK-SRAMECC-OFF-ONLY %s
 
 // CHECK-GFX900: .amdgcn_target "amdgpu-amd-amdhsa-unknown-gfx900"
@@ -70,3 +74,29 @@
 // CHECK-SRAMECC-ONLY: .amdgcn_target "amdgpu-amd-amdhsa-unknown-gfx908:sramecc+"
 
 // CHECK-SRAMECC-OFF-ONLY: .amdgcn_target "amdgpu-amd-amdhsa-unknown-gfx908:sramecc-"
+
+//--- plain.s
+
+//--- both-on.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:sramecc+:xnack+"
+
+//--- both-off.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:sramecc-:xnack-"
+
+//--- xnack-on.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:sramecc-:xnack+"
+
+//--- sramecc-on.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:sramecc+:xnack-"
+
+//--- xnack-only.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack+"
+
+//--- xnack-off-only.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"
+
+//--- sramecc-only.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:sramecc+"
+
+//--- sramecc-off-only.s
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:sramecc-"
diff --git a/llvm/test/MC/AMDGPU/hsa-diag-v4.s b/llvm/test/MC/AMDGPU/hsa-diag-v4.s
index ac9fefe3a7d16..6696f23169cd6 100644
--- a/llvm/test/MC/AMDGPU/hsa-diag-v4.s
+++ b/llvm/test/MC/AMDGPU/hsa-diag-v4.s
@@ -1,10 +1,10 @@
-// RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu8.10-amd-amdhsa -mattr=+xnack %s -filetype=null 2>&1 | FileCheck %s -DMCPU=gfx810 --check-prefixes=ALL,GCN,GFX8,PREGFX10,NOWGP,AMDHSA
-// RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu10.10-amd-amdhsa -mattr=+xnack %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=ALL,GCN,GFX10PLUS,GFX10,AMDHSA
+// RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu8.10-amd-amdhsa %s -filetype=null 2>&1 | FileCheck %s -DMCPU=gfx810 --check-prefixes=ALL,GCN,GFX8,PREGFX10,NOWGP,AMDHSA
+// RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu10.10-amd-amdhsa %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=ALL,GCN,GFX10PLUS,GFX10,AMDHSA
 // RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu11.00-amd-amdhsa %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=ALL,GCN,GFX10PLUS,GFX11,AMDHSA
 // RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu12.00-amd-amdhsa %s -filetype=null 2>&1 | FileCheck %s -DMCPU=gfx1200 --check-prefixes=ALL,GCN,GFX10PLUS,GFX12,AMDHSA
 // RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu11.70-amd-amdhsa %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=ALL,GCN,GFX10PLUS,GFX1170,AMDHSA
-// RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu8.10-amd- -mattr=+xnack %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=ALL,GCN,NONAMDHSA
-// RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu9.0a-amd-amdhsa -mattr=+xnack %s -filetype=null 2>&1 | FileCheck %s -DMCPU=gfx90a --check-prefixes=ALL,GFX90A,PREGFX10,NOWGP,AMDHSA
+// RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu8.10-amd- %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=ALL,GCN,NONAMDHSA
+// RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu9.0a-amd-amdhsa %s -filetype=null 2>&1 | FileCheck %s -DMCPU=gfx90a --check-prefixes=ALL,GFX90A,PREGFX10,NOWGP,AMDHSA
 // RUN: not llvm-mc --amdhsa-code-object-version=4 -triple=amdgpu12.50-amd-amdhsa %s -filetype=null 2>&1 | FileCheck %s -DMCPU=gfx1250 --check-prefixes=ALL,GCN,GFX10PLUS,GFX1250,NOWGP,AMDHSA
 
 .text
diff --git a/llvm/test/MC/AMDGPU/hsa-tg-split.s b/llvm/test/MC/AMDGPU/hsa-tg-split.s
index d130b6301663a..7dc900ceb2485 100644
--- a/llvm/test/MC/AMDGPU/hsa-tg-split.s
+++ b/llvm/test/MC/AMDGPU/hsa-tg-split.s
@@ -1,5 +1,5 @@
-// RUN: llvm-mc -triple=amdgpu9.0a-amd-amdhsa -mattr=+xnack < %s | FileCheck --check-prefix=ASM %s
-// RUN: llvm-mc -triple=amdgpu9.0a-amd-amdhsa -mattr=+xnack -filetype=obj < %s > %t
+// RUN: llvm-mc -triple=amdgpu9.0a-amd-amdhsa < %s | FileCheck --check-prefix=ASM %s
+// RUN: llvm-mc -triple=amdgpu9.0a-amd-amdhsa -filetype=obj < %s > %t
 // RUN: llvm-objdump -s -j .rodata %t | FileCheck --check-prefix=OBJDUMP %s
 
 // OBJDUMP: Contents of section .rodata
diff --git a/llvm/test/MC/AMDGPU/hsa-v4.s b/llvm/test/MC/AMDGPU/hsa-v4.s
index 1203da71ce309..e3a0ceb730c87 100644
--- a/llvm/test/MC/AMDGPU/hsa-v4.s
+++ b/llvm/test/MC/AMDGPU/hsa-v4.s
@@ -1,5 +1,5 @@
-// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa -mattr=+xnack < %s | FileCheck --check-prefix=ASM %s
-// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa -mattr=+xnack -filetype=obj < %s > %t
+// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa < %s | FileCheck --check-prefix=ASM %s
+// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa -filetype=obj < %s > %t
 // RUN: llvm-readelf -S -r -s %t | FileCheck --check-prefix=READOBJ %s
 // RUN: llvm-objdump -s -j .rodata %t | FileCheck --check-prefix=OBJDUMP %s
 
diff --git a/llvm/test/MC/AMDGPU/hsa-v5-uses-dynamic-stack.s b/llvm/test/MC/AMDGPU/hsa-v5-uses-dynamic-stack.s
index 43f49a09c564f..d26ef2e76a475 100644
--- a/llvm/test/MC/AMDGPU/hsa-v5-uses-dynamic-stack.s
+++ b/llvm/test/MC/AMDGPU/hsa-v5-uses-dynamic-stack.s
@@ -1,10 +1,10 @@
-// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa -mattr=+xnack < %s | FileCheck --check-prefix=ASM %s
-// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa -mattr=+xnack -filetype=obj < %s > %t
+// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa < %s | FileCheck --check-prefix=ASM %s
+// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa -filetype=obj < %s > %t
 // RUN: llvm-readelf -S -r -s %t | FileCheck --check-prefix=READOBJ %s
 // RUN: llvm-objdump -s -j .rodata %t | FileCheck --check-prefix=OBJDUMP %s
 
-// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa --amdhsa-code-object-version=6 -mattr=+xnack < %s | FileCheck --check-prefix=ASM %s
-// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa --amdhsa-code-object-version=6 -mattr=+xnack -filetype=obj < %s > %t
+// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa --amdhsa-code-object-version=6 < %s | FileCheck --check-prefix=ASM %s
+// RUN: llvm-mc -triple=amdgpu9.04-amd-amdhsa --amdhsa-code-object-version=6 -filetype=obj < %s > %t
 // RUN: llvm-readelf -S -r -s %t | FileCheck --check-prefix=READOBJ %s
 // RUN: llvm-objdump -s -j .rodata %t | FileCheck --check-prefix=OBJDUMP %s
 
diff --git a/llvm/test/MC/AMDGPU/user-sgpr-count.s b/llvm/test/MC/AMDGPU/user-sgpr-count.s
index 33cfbcc8058b6..1e0cc176d0286 100644
--- a/llvm/test/MC/AMDGPU/user-sgpr-count.s
+++ b/llvm/test/MC/AMDGPU/user-sgpr-count.s
@@ -1,4 +1,4 @@
-// RUN: llvm-mc -triple=amdgpu9.0a-amd-amdhsa --amdhsa-code-object-version=4 -mattr=+xnack < %s | FileCheck --check-prefix=ASM %s
+// RUN: llvm-mc -triple=amdgpu9.0a-amd-amdhsa --amdhsa-code-object-version=4 < %s | FileCheck --check-prefix=ASM %s
 
 .amdgcn_target "amdgpu9.0a-amd-amdhsa--gfx90a:xnack+"
 // ASM: .amdgcn_target "amdgpu9.0a-amd-amdhsa-unknown-gfx90a:xnack+"
diff --git a/llvm/test/MC/AMDGPU/xnack-mask.s b/llvm/test/MC/AMDGPU/xnack-mask.s
index 8bc8911d9a905..e48ad97c10d21 100644
--- a/llvm/test/MC/AMDGPU/xnack-mask.s
+++ b/llvm/test/MC/AMDGPU/xnack-mask.s
@@ -1,10 +1,10 @@
 // RUN: not llvm-mc -triple=amdgpu6.00 %s -filetype=null 2>&1 | FileCheck -check-prefix=NOSICIVI10 --implicit-check-not=error: %s
 // RUN: not llvm-mc -triple=amdgpu7.01 %s -filetype=null 2>&1 | FileCheck -check-prefix=NOSICIVI10 --implicit-check-not=error: %s
 // RUN: not llvm-mc -triple=amdgpu8.02 %s -filetype=null 2>&1 | FileCheck -check-prefix=NOSICIVI10 --implicit-check-not=error: %s
-// RUN: not llvm-mc -triple=amdgpu10.10 -mattr=-xnack %s -filetype=null 2>&1 | FileCheck -check-prefix=NOSICIVI10 --implicit-check-not=error: %s
+// RUN: not llvm-mc -triple=amdgpu10.10 %s -filetype=null 2>&1 | FileCheck -check-prefix=NOSICIVI10 --implicit-check-not=error: %s
 
-// RUN: not llvm-mc -triple=amdgpu8.10 -mattr=+xnack %s -filetype=null 2>&1 | FileCheck -check-prefix=XNACKERR --implicit-check-not=error: %s
-// RUN: not llvm-mc -triple=amdgpu8.10 -mattr=+xnack -show-encoding %s | FileCheck -check-prefix=XNACK %s
+// RUN: not llvm-mc -triple=amdgpu8.10 %s -filetype=null 2>&1 | FileCheck -check-prefix=XNACKERR --implicit-check-not=error: %s
+// RUN: not llvm-mc -triple=amdgpu8.10 -show-encoding %s | FileCheck -check-prefix=XNACK %s
 
 s_mov_b64 xnack_mask, -1
 // NOSICIVI10: :[[@LINE-1]]:{{[0-9]+}}: error: xnack_mask register not available on this GPU
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-cov5.s b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-cov5.s
index 50c486ff6031b..cf3ad06196886 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-cov5.s
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-cov5.s
@@ -1,16 +1,16 @@
 ; RUN: sed 's/CODE_OBJECT_VERSION/5/g' %s \
-; RUN:   | llvm-mc --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack,+wavefrontsize32,-wavefrontsize64 -filetype=obj > %t.o
+; RUN:   | llvm-mc --triple=amdgcn-amd-amdhsa -mcpu=gfx1010 -mattr=+wavefrontsize32,-wavefrontsize64 -filetype=obj > %t.o
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd %t.o | FileCheck %s --check-prefixes=COV5,CHECK
 
 ; RUN: sed 's/CODE_OBJECT_VERSION/4/g' %s \
-; RUN:   | llvm-mc --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack,+wavefrontsize32,-wavefrontsize64 -filetype=obj > %t.o
+; RUN:   | llvm-mc --triple=amdgcn-amd-amdhsa -mcpu=gfx1010 -mattr=+wavefrontsize32,-wavefrontsize64 -filetype=obj > %t.o
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd %t.o | FileCheck %s --check-prefixes=COV4,CHECK
 
 ;; Make sure we override the default COV in the disassembler on COV6 (there
 ;; currently aren't any differences between 5 and 6, so set the default to 4 so
 ;; we can verify that the default is at least overridden)
 ; RUN: sed 's/CODE_OBJECT_VERSION/6/g' %s \
-; RUN:   | llvm-mc --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack,+wavefrontsize32,-wavefrontsize64 -filetype=obj > %t.o
+; RUN:   | llvm-mc --triple=amdgcn-amd-amdhsa -mcpu=gfx1010 -mattr=+wavefrontsize32,-wavefrontsize64 -filetype=obj > %t.o
 ; RUN: llvm-objdump -mllvm --amdhsa-code-object-version=4 --disassemble-symbols=kernel.kd %t.o | FileCheck %s --check-prefixes=COV5,CHECK
 
 ;; Verify that .amdhsa_uses_dynamic_stack is only printed on COV5+.
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx10.s b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx10.s
index 1bf3cb8ce2a01..f885df916b14a 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx10.s
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx10.s
@@ -3,10 +3,10 @@
 ; RUN: rm -rf %t && split-file %s %t && cd %t
 
 ;--- 1.s
-; RUN: llvm-mc --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack,+wavefrontsize32,-wavefrontsize64 -filetype=obj < 1.s > 1.o
-; RUN: echo '.amdhsa_code_object_version 5' > 1-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -mattr=+wavefrontsize32,-wavefrontsize64 -filetype=obj -mcpu=gfx1010 < 1.s > 1.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx1010:xnack-"\n.amdhsa_code_object_version 5\n' > 1-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 1.o | tail -n +8 | tee -a 1-disasm.s | FileCheck 1.s
-; RUN: llvm-mc --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack,+wavefrontsize32,-wavefrontsize64 -filetype=obj < 1-disasm.s > 1-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -mattr=+wavefrontsize32,-wavefrontsize64 -filetype=obj -mcpu=gfx1010 < 1-disasm.s > 1-disasm.o
 ; RUN: cmp 1.o 1-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -51,6 +51,7 @@
 ; CHECK-NEXT: .amdhsa_wavefront_size32 1
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx1010:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 32
@@ -59,10 +60,10 @@
 .end_amdhsa_kernel
 
 ;--- 2.s
-; RUN: llvm-mc --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack,+wavefrontsize64,-wavefrontsize32 -filetype=obj < 2.s > 2.o
-; RUN: echo '.amdhsa_code_object_version 5' > 2-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -mattr=+wavefrontsize64,-wavefrontsize32 -filetype=obj -mcpu=gfx1010 < 2.s > 2.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx1010:xnack-"\n.amdhsa_code_object_version 5\n' > 2-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 2.o | tail -n +8 | tee -a 2-disasm.s | FileCheck 2.s
-; RUN: llvm-mc --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack,+wavefrontsize64,-wavefrontsize32 -filetype=obj < 2-disasm.s > 2-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -mattr=+wavefrontsize64,-wavefrontsize32 -filetype=obj -mcpu=gfx1010 < 2-disasm.s > 2-disasm.o
 ; RUN: cmp 2.o 2-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -107,6 +108,7 @@
 ; CHECK-NEXT: .amdhsa_wavefront_size32 0
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx1010:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 32
@@ -115,10 +117,10 @@
 .end_amdhsa_kernel
 
 ;--- 3.s
-; RUN: llvm-mc --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack,+wavefrontsize64,-wavefrontsize32 -filetype=obj < 3.s > 3.o
-; RUN: echo '.amdhsa_code_object_version 5' > 3-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -mattr=+wavefrontsize64,-wavefrontsize32 -filetype=obj -mcpu=gfx1010 < 3.s > 3.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx1010:xnack-"\n.amdhsa_code_object_version 5\n' > 3-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 3.o | tail -n +8 | tee -a 3-disasm.s | FileCheck 3.s
-; RUN: llvm-mc --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack,+wavefrontsize64,-wavefrontsize32 -filetype=obj < 3-disasm.s > 3-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -mattr=+wavefrontsize64,-wavefrontsize32 -filetype=obj -mcpu=gfx1010 < 3-disasm.s > 3-disasm.o
 ; RUN: cmp 3.o 3-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -163,6 +165,7 @@
 ; CHECK-NEXT: .amdhsa_wavefront_size32 0
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx1010:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 32
@@ -171,10 +174,10 @@
 .end_amdhsa_kernel
 
 ;--- 4.s
-; RUN: llvm-mc --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack,+wavefrontsize64,-wavefrontsize32 -filetype=obj < 4.s > 4.o
-; RUN: echo '.amdhsa_code_object_version 5' > 4-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -mattr=+wavefrontsize64,-wavefrontsize32 -filetype=obj -mcpu=gfx1010 < 4.s > 4.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx1010:xnack-"\n.amdhsa_code_object_version 5\n' > 4-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 4.o | tail -n +8 | tee -a 4-disasm.s | FileCheck 4.s
-; RUN: llvm-mc --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack,+wavefrontsize64,-wavefrontsize32 -filetype=obj < 4-disasm.s > 4-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -mattr=+wavefrontsize64,-wavefrontsize32 -filetype=obj -mcpu=gfx1010 < 4-disasm.s > 4-disasm.o
 ; RUN: cmp 4.o 4-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -219,6 +222,7 @@
 ; CHECK-NEXT: .amdhsa_wavefront_size32 0
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx1010:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 32
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx90a.s b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx90a.s
index 89ca1084727d7..08842c355d1a8 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx90a.s
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx90a.s
@@ -3,10 +3,10 @@
 ; RUN: rm -rf %t && split-file %s %t && cd %t
 
 ;--- 1.s
-; RUN: llvm-mc --triple=amdgpu9.0a-amd-amdhsa -mattr=-xnack -filetype=obj < 1.s > 1.o
-; RUN: echo '.amdhsa_code_object_version 5' > 1-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx90a < 1.s > 1.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx90a:xnack-"\n.amdhsa_code_object_version 5\n' > 1-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 1.o | tail -n +8 | tee -a 1-disasm.s | FileCheck 1.s
-; RUN: llvm-mc --triple=amdgpu9.0a-amd-amdhsa -mattr=-xnack -filetype=obj < 1-disasm.s > 1-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx90a < 1-disasm.s > 1-disasm.o
 ; RUN: cmp 1.o 1-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -48,6 +48,7 @@
 ; CHECK-NEXT: .amdhsa_user_sgpr_private_segment_size 0
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx90a:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 0
@@ -56,10 +57,10 @@
 .end_amdhsa_kernel
 
 ;--- 2.s
-; RUN: llvm-mc --triple=amdgpu9.0a-amd-amdhsa -mattr=-xnack -filetype=obj < 2.s > 2.o
-; RUN: echo '.amdhsa_code_object_version 5' > 2-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx90a < 2.s > 2.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx90a:xnack-"\n.amdhsa_code_object_version 5\n' > 2-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 2.o | tail -n +8 | tee -a 2-disasm.s | FileCheck 2.s
-; RUN: llvm-mc --triple=amdgpu9.0a-amd-amdhsa -mattr=-xnack -filetype=obj < 2-disasm.s > 2-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx90a < 2-disasm.s > 2-disasm.o
 ; RUN: cmp 2.o 2-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -101,6 +102,7 @@
 ; CHECK-NEXT: .amdhsa_user_sgpr_private_segment_size 0
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx90a:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 32
@@ -109,10 +111,10 @@
 .end_amdhsa_kernel
 
 ;--- 3.s
-; RUN: llvm-mc --triple=amdgpu9.0a-amd-amdhsa -mattr=-xnack -filetype=obj < 3.s > 3.o
-; RUN: echo '.amdhsa_code_object_version 5' > 3-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx90a < 3.s > 3.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx90a:xnack-"\n.amdhsa_code_object_version 5\n' > 3-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 3.o | tail -n +8 | tee -a 3-disasm.s | FileCheck 3.s
-; RUN: llvm-mc --triple=amdgpu9.0a-amd-amdhsa -mattr=-xnack -filetype=obj < 3-disasm.s > 3-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx90a < 3-disasm.s > 3-disasm.o
 ; RUN: cmp 3.o 3-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -156,6 +158,7 @@
 ; CHECK-NEXT: .amdhsa_user_sgpr_kernarg_preload_length  2
 ; CHECK-NEXT: .amdhsa_user_sgpr_kernarg_preload_offset  1
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx90a:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 32
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx950.s b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx950.s
index c376b62f3b309..ee24d96654f11 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx950.s
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx950.s
@@ -3,9 +3,10 @@
 ; RUN: rm -rf %t && split-file %s %t && cd %t
 
 ;--- 1.s
-; RUN: llvm-mc --triple=amdgpu9.50-amd-amdhsa -mattr=-xnack -filetype=obj < 1.s > 1.o
-; RUN: llvm-objdump --disassemble-symbols=kernel.kd 1.o | tail -n +8 | tee 1-disasm.s | FileCheck 1.s
-; RUN: llvm-mc --triple=amdgpu9.50-amd-amdhsa -mattr=-xnack -filetype=obj < 1-disasm.s > 1-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx950 < 1.s > 1.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx950:xnack-"\n' > 1-disasm.s
+; RUN: llvm-objdump --disassemble-symbols=kernel.kd 1.o | tail -n +8 | tee -a 1-disasm.s | FileCheck 1.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx950 < 1-disasm.s > 1-disasm.o
 ; FIxMe: cmp 1.o 1-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT:	.amdhsa_group_segment_fixed_size 163840
@@ -44,6 +45,7 @@
 ; CHECK-NEXT:	.amdhsa_user_sgpr_private_segment_size 0
 ; CHECK-NEXT:	.amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT:.end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx950:xnack-"
 .amdhsa_kernel kernel
   .amdhsa_group_segment_fixed_size 163840
   .amdhsa_next_free_vgpr 0
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-sgpr.s b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-sgpr.s
index 203d3f63f09c2..e3b884c4a49c6 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-sgpr.s
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-sgpr.s
@@ -4,10 +4,10 @@
 
 ;--- 1.s
 ;; Only set next_free_sgpr.
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 1.s > 1.o
-; RUN: echo '.amdhsa_code_object_version 5' > 1-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 1.s > 1.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"\n.amdhsa_code_object_version 5\n' > 1-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 1.o | tail -n +8 | tee -a 1-disasm.s | FileCheck 1.s
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 1-disasm.s > 1-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 1-disasm.s > 1-disasm.o
 ; RUN: cmp 1.o 1-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -47,6 +47,7 @@
 ; CHECK-NEXT: .amdhsa_user_sgpr_private_segment_size 0
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 0
@@ -58,10 +59,10 @@
 
 ;--- 2.s
 ;; Only set other directives.
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 2.s > 2.o
-; RUN: echo '.amdhsa_code_object_version 5' > 2-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 2.s > 2.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"\n.amdhsa_code_object_version 5\n' > 2-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 2.o | tail -n +8 | tee -a 2-disasm.s | FileCheck 2.s
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 2-disasm.s > 2-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 2-disasm.s > 2-disasm.o
 ; RUN: cmp 2.o 2-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -101,6 +102,7 @@
 ; CHECK-NEXT: .amdhsa_user_sgpr_private_segment_size 0
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 0
@@ -112,10 +114,10 @@
 
 ;--- 3.s
 ;; Set all affecting directives.
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 3.s > 3.o
-; RUN: echo '.amdhsa_code_object_version 5' > 3-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 3.s > 3.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"\n.amdhsa_code_object_version 5\n' > 3-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 3.o | tail -n +8 | tee -a 3-disasm.s | FileCheck 3.s
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 3-disasm.s > 3-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 3-disasm.s > 3-disasm.o
 ; RUN: cmp 3.o 3-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -155,6 +157,7 @@
 ; CHECK-NEXT: .amdhsa_user_sgpr_private_segment_size 0
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 0
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-vgpr.s b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-vgpr.s
index 1f7df1ff7a459..9c14169cfe1f4 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-vgpr.s
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-vgpr.s
@@ -3,10 +3,10 @@
 ; RUN: rm -rf %t && split-file %s %t && cd %t
 
 ;--- 1.s
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 1.s > 1.o
-; RUN: echo '.amdhsa_code_object_version 5' > 1-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 1.s > 1.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"\n.amdhsa_code_object_version 5\n' > 1-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 1.o | tail -n +8 | tee -a 1-disasm.s | FileCheck 1.s
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 1-disasm.s > 1-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 1-disasm.s > 1-disasm.o
 ; RUN: cmp 1.o 1-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -46,6 +46,7 @@
 ; CHECK-NEXT: .amdhsa_user_sgpr_private_segment_size 0
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 23
@@ -53,10 +54,10 @@
 .end_amdhsa_kernel
 
 ;--- 2.s
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 2.s > 2.o
-; RUN: echo '.amdhsa_code_object_version 5' > 2-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 2.s > 2.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"\n.amdhsa_code_object_version 5\n' > 2-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 2.o | tail -n +8 | tee -a 2-disasm.s | FileCheck 2.s
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 2-disasm.s > 2-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 2-disasm.s > 2-disasm.o
 ; RUN: cmp 2.o 2-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -96,6 +97,7 @@
 ; CHECK-NEXT: .amdhsa_user_sgpr_private_segment_size 0
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 14
@@ -103,10 +105,10 @@
 .end_amdhsa_kernel
 
 ;--- 3.s
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 3.s > 3.o
-; RUN: echo '.amdhsa_code_object_version 5' > 3-disasm.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 3.s > 3.o
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"\n.amdhsa_code_object_version 5\n' > 3-disasm.s
 ; RUN: llvm-objdump --disassemble-symbols=kernel.kd 3.o | tail -n +8 | tee -a 3-disasm.s | FileCheck 3.s
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj < 3-disasm.s > 3-disasm.o
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -filetype=obj -mcpu=gfx908 < 3-disasm.s > 3-disasm.o
 ; RUN: cmp 3.o 3-disasm.o
 ; CHECK: .amdhsa_kernel kernel
 ; CHECK-NEXT: .amdhsa_group_segment_fixed_size 0
@@ -146,6 +148,7 @@
 ; CHECK-NEXT: .amdhsa_user_sgpr_private_segment_size 0
 ; CHECK-NEXT: .amdhsa_uses_dynamic_stack 0
 ; CHECK-NEXT: .end_amdhsa_kernel
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel kernel
   .amdhsa_next_free_vgpr 32
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx10.s b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx10.s
index aef30b4c44d13..f1fe23507414c 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx10.s
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx10.s
@@ -1,6 +1,6 @@
 ;; Entirely zeroed kernel descriptor (for GFX10).
 
-; RUN: llvm-mc %s --triple=amdgpu10.10-amd-amdhsa -mattr=-xnack -filetype=obj -o %t
+; RUN: llvm-mc %s --triple=amdgcn-amd-amdhsa -mcpu=gfx1010 -filetype=obj -o %t
 ; RUN: llvm-objdump -s -d -j .text %t | FileCheck --check-prefix=OBJDUMP %s
 
 ;; TODO:
@@ -67,6 +67,7 @@
 ; OBJDUMP-NEXT:         .amdhsa_uses_dynamic_stack 0
 ; OBJDUMP-NEXT: .end_amdhsa_kernel
 
+.amdgcn_target "amdgcn-amd-amdhsa--gfx1010:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel my_kernel
   .amdhsa_group_segment_fixed_size 0
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx9.s b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx9.s
index cfad7e7d86123..caa6f661ac8e7 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx9.s
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-gfx9.s
@@ -1,9 +1,9 @@
 ;; Entirely zeroed kernel descriptor (for GFX9).
 
-; RUN: llvm-mc %s --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj -o %t1
-; RUN: echo '.amdhsa_code_object_version 5' > %t2.s
+; RUN: llvm-mc %s --triple=amdgcn-amd-amdhsa -mcpu=gfx908 -filetype=obj -o %t1
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"\n.amdhsa_code_object_version 5\n' > %t2.s
 ; RUN: llvm-objdump --disassemble-symbols=my_kernel.kd %t1 | tail -n +8 >> %t2.s
-; RUN: llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj -o %t2 %t2.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -mcpu=gfx908 -filetype=obj -o %t2 %t2.s
 ; RUN: diff %t1 %t2
 
 ; RUN: llvm-objdump -s -j .text %t1 | FileCheck --check-prefix=OBJDUMP %s
@@ -16,6 +16,7 @@
 ;; This file and kd-zeroed-raw.s produce the same output for the kernel
 ;; descriptor - a block of 64 zeroed bytes.
 
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"
 .amdhsa_code_object_version 5
 .amdhsa_kernel my_kernel
   .amdhsa_group_segment_fixed_size 0
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-raw.s b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-raw.s
index 288683cd1dd48..bbddb1b80190e 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-raw.s
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-zeroed-raw.s
@@ -1,6 +1,7 @@
-; RUN: llvm-mc %s --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj -o %t1
-; RUN: llvm-objdump --disassemble-symbols=my_kernel.kd %t1 \
-; RUN: | tail -n +8 | llvm-mc --triple=amdgpu9.08-amd-amdhsa -mattr=-xnack -filetype=obj -o %t2
+; RUN: llvm-mc %s --triple=amdgcn-amd-amdhsa -mcpu=gfx908 -filetype=obj -o %t1
+; RUN: printf '.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"\n' > %t2.s
+; RUN: llvm-objdump --disassemble-symbols=my_kernel.kd %t1 | tail -n +8 >> %t2.s
+; RUN: llvm-mc --triple=amdgcn-amd-amdhsa -mcpu=gfx908 -filetype=obj -o %t2 %t2.s
 ; RUN: llvm-objdump -s -j .text %t2 | FileCheck --check-prefix=OBJDUMP %s
 
 ;; Not running lit-test over gfx10 (see kd-zeroed-gfx10.s for details).
@@ -18,6 +19,7 @@
 
 ;; The entire object is zeroed out.
 
+.amdgcn_target "amdgcn-amd-amdhsa--gfx908:xnack-"
 .type	my_kernel.kd, @object
 .size my_kernel.kd, 64
 my_kernel.kd:

>From af83c911182a4ee3222553d49efd6799de865aad Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 30 Jul 2026 09:37:01 +0200
Subject: [PATCH 2/2] maintain cc1 behavior

---
 .../Driver/amdgpu-assembler-xnack-sramecc.s   | 53 +++++++++----------
 .../llvm/TargetParser/AMDGPUTargetParser.h    |  8 +++
 .../Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp    | 24 ++-------
 llvm/lib/TargetParser/AMDGPUTargetParser.cpp  | 52 +++++++++++++++---
 4 files changed, 81 insertions(+), 56 deletions(-)

diff --git a/clang/test/Driver/amdgpu-assembler-xnack-sramecc.s b/clang/test/Driver/amdgpu-assembler-xnack-sramecc.s
index 3f72014753512..d1c495e681f06 100644
--- a/clang/test/Driver/amdgpu-assembler-xnack-sramecc.s
+++ b/clang/test/Driver/amdgpu-assembler-xnack-sramecc.s
@@ -1,38 +1,33 @@
 // REQUIRES: amdgpu-registered-target
 
 /// Assembling a .s file that has no target ID directive (.amdgcn_target). The
-/// xnack/sramecc mode is a property of the assembly / object, so specifying it
-/// on the command line, either with -mxnack/-msramecc or via the -mcpu target
-/// ID modifiers, is not preserved: the driver no longer forwards these to the
-/// assembler, and the resulting object uses the "any" setting in its e_flags.
-/// To pin a mode, the .s file must contain a .amdgcn_target directive.
+/// xnack/sramecc mode requested on the command line, either with
+/// -mxnack/-msramecc or via the -mcpu target ID modifiers, is forwarded to the
+/// assembler as a target feature and recorded in the object's e_flags.
 
+/// The mode is forwarded to the assembler as a target feature.
 // RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -mno-xnack -c %s 2>&1 | \
-// RUN:   FileCheck -check-prefix=CC1AS %s
-// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -mxnack -c %s 2>&1 | \
-// RUN:   FileCheck -check-prefix=CC1AS %s
-// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -mno-sramecc -c %s 2>&1 | \
-// RUN:   FileCheck -check-prefix=CC1AS %s
-// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906:xnack+ -c %s 2>&1 | \
-// RUN:   FileCheck -check-prefix=CC1AS %s
-// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906:sramecc- -c %s 2>&1 | \
-// RUN:   FileCheck -check-prefix=CC1AS %s
+// RUN:   FileCheck -check-prefix=XNACK-OFF %s
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906:xnack- -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=XNACK-OFF %s
+// XNACK-OFF: "-cc1as"
+// XNACK-OFF-SAME: "-target-feature" "-xnack"
 
-/// The assembler is invoked with the plain target-cpu and no xnack/sramecc
-/// target feature.
-// CC1AS: "-cc1as"
-// CC1AS-SAME: "-target-cpu" "gfx906"
-// CC1AS-NOT: "-target-feature"
-
-/// End to end: the mode requested on the command line is not reflected in the
-/// object, which keeps the "any" xnack/sramecc e_flags.
-// RUN: %clang --target=amdgcn-amd-amdhsa -mcpu=gfx906 -mno-xnack -c %s -o %t.o 2>&1 | \
-// RUN:   FileCheck -check-prefix=UNUSED %s
-// RUN: llvm-readobj --file-headers %t.o | FileCheck -check-prefix=ANY %s
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -msramecc -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=SRAMECC-ON %s
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906:sramecc+ -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=SRAMECC-ON %s
+// SRAMECC-ON: "-cc1as"
+// SRAMECC-ON-SAME: "-target-feature" "+sramecc"
 
+/// End to end: the requested mode is reflected in the object's e_flags.
+// RUN: %clang --target=amdgcn-amd-amdhsa -mcpu=gfx906 -mno-xnack -c %s -o %t.o
+// RUN: llvm-readobj --file-headers %t.o | FileCheck -check-prefix=OBJ-XNACK-OFF %s
 // RUN: %clang --target=amdgcn-amd-amdhsa -mcpu=gfx906:xnack+ -c %s -o %t.o
-// RUN: llvm-readobj --file-headers %t.o | FileCheck -check-prefix=ANY %s
+// RUN: llvm-readobj --file-headers %t.o | FileCheck -check-prefix=OBJ-XNACK-ON %s
+// RUN: %clang --target=amdgcn-amd-amdhsa -mcpu=gfx906:sramecc- -c %s -o %t.o
+// RUN: llvm-readobj --file-headers %t.o | FileCheck -check-prefix=OBJ-SRAMECC-OFF %s
 
-// UNUSED: warning: argument unused during compilation: '-mno-xnack'
-// ANY: EF_AMDGPU_FEATURE_SRAMECC_ANY_V4 (0x400)
-// ANY: EF_AMDGPU_FEATURE_XNACK_ANY_V4 (0x100)
+// OBJ-XNACK-OFF: EF_AMDGPU_FEATURE_XNACK_OFF_V4 (0x200)
+// OBJ-XNACK-ON: EF_AMDGPU_FEATURE_XNACK_ON_V4 (0x300)
+// OBJ-SRAMECC-OFF: EF_AMDGPU_FEATURE_SRAMECC_OFF_V4 (0x800)
diff --git a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
index f8e283db55fec..d3530b40959ea 100644
--- a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
+++ b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
@@ -293,6 +293,14 @@ class LLVM_ABI TargetID {
   static std::optional<TargetID>
   parseTargetIDString(StringRef TargetIDDirective);
 
+  /// Construct a TargetID for triple \p TT and processor \p CPU, taking the
+  /// xnack/sramecc modes from the subtarget \p FeatureString (a comma-separated
+  /// "+xnack,-sramecc" list). Unspecified modes keep the processor's default.
+  /// The assembler uses this because it has no target directive to carry the
+  /// mode.
+  static TargetID createFromSubtargetFeatures(const Triple &TT, StringRef CPU,
+                                              StringRef FeatureString);
+
   /// Returns true if \p Other denotes the same target as *this, i.e. the same
   /// processor and xnack/sramecc settings on a compatible triple. This is a
   /// semantic equality that looks through spelling differences.
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 5b0ce24d05fee..aed7a496efbbd 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -1086,25 +1086,11 @@ VOPD::InstInfo getVOPDInstInfo(unsigned VOPDOpcode,
 
 TargetID createAMDGPUTargetID(const MCSubtargetInfo &STI,
                               StringRef FeatureString) {
-  // 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(parseArchAMDGCN(STI.getCPU()), STI.getTargetTriple(),
-                  XnackSetting,
-                  STI.getFeatureBits().test(FeatureSupportsSRAMECC)
-                      ? TargetIDSetting::Any
-                      : TargetIDSetting::Unsupported);
+  // In codegen the mode comes from module flags and FeatureString is empty, so
+  // the processor defaults apply. The assembler has no target directive, so it
+  // pins the mode via the +xnack/-xnack/+sramecc/-sramecc feature string.
+  return TargetID::createFromSubtargetFeatures(STI.getTargetTriple(),
+                                               STI.getCPU(), FeatureString);
 }
 
 namespace IsaInfo {
diff --git a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
index 1caa4db1a771b..90d9439f7acab 100644
--- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
+++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
@@ -588,14 +588,11 @@ static GPUKind getGPUKindFromTargetID(const Triple &TT, StringRef TargetIDStr) {
              : parseArchAMDGCN(CPUName);
 }
 
-// Compute the xnack/sramecc settings for processor \p Arch from the
-// processor+features string \p TargetIDStr
-// (e.g. "gfx90a:xnack+:sramecc-"). Returns false if a modifier names an unknown
-// or repeated feature, names one the processor does not support, or has a
-// malformed sign.
-static bool computeTargetIDFeatures(GPUKind Arch, StringRef TargetIDStr,
-                                    TargetIDSetting &XnackSetting,
-                                    TargetIDSetting &SramEccSetting) {
+// Compute the default xnack/sramecc settings for processor \p Arch, before any
+// explicit feature modifiers are applied.
+static void getDefaultTargetIDFeatures(GPUKind Arch,
+                                       TargetIDSetting &XnackSetting,
+                                       TargetIDSetting &SramEccSetting) {
   unsigned ArchAttr = getArchAttrAMDGCN(Arch);
   // xnack with on/off modes defaults to Any; supported without on/off modes is
   // hardwired On (e.g. gfx1250); unsupported is Unsupported.
@@ -607,6 +604,18 @@ static bool computeTargetIDFeatures(GPUKind Arch, StringRef TargetIDStr,
     XnackSetting = TargetIDSetting::On;
   SramEccSetting = (ArchAttr & FEATURE_SRAMECC) ? TargetIDSetting::Any
                                                 : TargetIDSetting::Unsupported;
+}
+
+// Compute the xnack/sramecc settings for processor \p Arch from the
+// processor+features string \p TargetIDStr
+// (e.g. "gfx90a:xnack+:sramecc-"). Returns false if a modifier names an unknown
+// or repeated feature, names one the processor does not support, or has a
+// malformed sign.
+static bool computeTargetIDFeatures(GPUKind Arch, StringRef TargetIDStr,
+                                    TargetIDSetting &XnackSetting,
+                                    TargetIDSetting &SramEccSetting) {
+  unsigned ArchAttr = getArchAttrAMDGCN(Arch);
+  getDefaultTargetIDFeatures(Arch, XnackSetting, SramEccSetting);
 
   // The first component is the processor; the rest are feature modifiers of the
   // form "<feature><+|->".
@@ -651,6 +660,33 @@ TargetID::TargetID(const Triple &TT, StringRef TargetIDStr)
   computeTargetIDFeatures(Arch, TargetIDStr, XnackSetting, SramEccSetting);
 }
 
+TargetID TargetID::createFromSubtargetFeatures(const Triple &TT, StringRef CPU,
+                                               StringRef FeatureString) {
+  GPUKind Arch = parseArchAMDGCN(CPU);
+  TargetIDSetting XnackSetting, SramEccSetting;
+  getDefaultTargetIDFeatures(Arch, XnackSetting, SramEccSetting);
+
+  // Apply the +/-xnack and +/-sramecc modifiers from the feature string, only
+  // for targets that can toggle the corresponding mode.
+  bool XnackToggleable = XnackSetting == TargetIDSetting::Any;
+  bool SramEccToggleable = SramEccSetting != TargetIDSetting::Unsupported;
+  SmallVector<StringRef, 4> Features;
+  FeatureString.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+  for (StringRef Feature : Features) {
+    TargetIDSetting Sign =
+        getTargetIDSettingFromFeatureString(Feature.take_front());
+    if (Sign == TargetIDSetting::Unsupported)
+      continue;
+    StringRef Name = Feature.drop_front();
+    if (Name == "xnack" && XnackToggleable)
+      XnackSetting = Sign;
+    else if (Name == "sramecc" && SramEccToggleable)
+      SramEccSetting = Sign;
+  }
+
+  return TargetID(Arch, TT, XnackSetting, SramEccSetting);
+}
+
 std::optional<TargetID> TargetID::parse(const Triple &TT,
                                         StringRef ProcAndFeatures) {
   if (!TT.isAMDGCN())



More information about the llvm-branch-commits mailing list