[llvm] AMDGPU: Only disassemble .amdhsa_reserve_xnack_mask on xnack targets (PR #212789)

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


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

>From f249d87c9bfd4b7f8f58992ed83a56df8c1dfd7d Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 29 Jul 2026 15:27:57 +0200
Subject: [PATCH] AMDGPU: Only disassemble .amdhsa_reserve_xnack_mask on xnack
 targets

The disassembler unconditionally printed .amdhsa_reserve_xnack_mask when
emitting a kernel descriptor. Targets that do not support xnack have no
xnack mask to reserve, and the assembler streamer already only emits the
directive when the subtarget supports xnack. Match that behavior in the
disassembler so the round-trip is consistent and gfx11/gfx12 descriptors
no longer carry a spurious directive.

As a guard against a malformed binary, if the object's ELF e_flags
erroneously select xnack "on" for a target that does not support xnack,
still print the directive so the invalid state remains visible in the
disassembly rather than being silently dropped.

Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
---
 .../Disassembler/AMDGPUDisassembler.cpp       | 14 +++--
 .../AMDGPU/Disassembler/AMDGPUDisassembler.h  |  3 +
 .../tools/llvm-objdump/ELF/AMDGPU/kd-gfx11.s  |  4 --
 .../tools/llvm-objdump/ELF/AMDGPU/kd-gfx12.s  |  2 -
 .../AMDGPU/kd-xnack-unsupported-eflags.yaml   | 55 +++++++++++++++++++
 5 files changed, 68 insertions(+), 10 deletions(-)
 create mode 100644 llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-xnack-unsupported-eflags.yaml

diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 526d9f1bf8eb4..c21a3df1471d9 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -123,6 +123,7 @@ void AMDGPUDisassembler::emitTargetIDIfSupported(raw_ostream &OS,
       break;
     case ELF::EF_AMDGPU_FEATURE_XNACK_ON_V4:
       OS << ":xnack+";
+      XnackOnFromEFlags = true;
       break;
     }
   }
@@ -2480,10 +2481,15 @@ Expected<bool> AMDGPUDisassembler::decodeCOMPUTE_PGM_RSRC1(
   KdStream << Indent << ".amdhsa_reserve_vcc " << 0 << '\n';
   if (!hasArchitectedFlatScratch())
     KdStream << Indent << ".amdhsa_reserve_flat_scratch " << 0 << '\n';
-  bool ReservedXnackMask = STI.hasFeature(AMDGPU::FeatureXNACK);
-  assert(!ReservedXnackMask || STI.hasFeature(AMDGPU::FeatureSupportsXNACK));
-  KdStream << Indent << ".amdhsa_reserve_xnack_mask " << ReservedXnackMask
-           << '\n';
+  // 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;
+  if (STI.hasFeature(AMDGPU::FeatureSupportsXNACK) || ReservedXnackMask) {
+    KdStream << Indent << ".amdhsa_reserve_xnack_mask " << ReservedXnackMask
+             << '\n';
+  }
   KdStream << Indent << ".amdhsa_next_free_sgpr " << NextFreeSGPR << "\n";
 
   CHECK_RESERVED_BITS(COMPUTE_PGM_RSRC1_PRIORITY);
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
index d0859d144722f..4a8f7e66721b2 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
@@ -47,6 +47,9 @@ 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;
   unsigned CodeObjectVersion;
   const MCExpr *UCVersionW64Expr;
   const MCExpr *UCVersionW32Expr;
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx11.s b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx11.s
index 8e81fb41e6869..a7a04fbc8cf89 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx11.s
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx11.s
@@ -19,7 +19,6 @@
 ; CHECK-NEXT: ; IMAGE_OP 0
 ; CHECK-NEXT: .amdhsa_next_free_vgpr 32
 ; CHECK-NEXT: .amdhsa_reserve_vcc 0
-; CHECK-NEXT: .amdhsa_reserve_xnack_mask 0
 ; CHECK-NEXT: .amdhsa_next_free_sgpr 8
 ; CHECK-NEXT: .amdhsa_float_round_mode_32 0
 ; CHECK-NEXT: .amdhsa_float_round_mode_16_64 0
@@ -76,7 +75,6 @@
 ; CHECK-NEXT: ; IMAGE_OP 0
 ; CHECK-NEXT: .amdhsa_next_free_vgpr 32
 ; CHECK-NEXT: .amdhsa_reserve_vcc 0
-; CHECK-NEXT: .amdhsa_reserve_xnack_mask 0
 ; CHECK-NEXT: .amdhsa_next_free_sgpr 8
 ; CHECK-NEXT: .amdhsa_float_round_mode_32 0
 ; CHECK-NEXT: .amdhsa_float_round_mode_16_64 0
@@ -134,7 +132,6 @@
 ; CHECK-NEXT: ; IMAGE_OP 0
 ; CHECK-NEXT: .amdhsa_next_free_vgpr 32
 ; CHECK-NEXT: .amdhsa_reserve_vcc 0
-; CHECK-NEXT: .amdhsa_reserve_xnack_mask 0
 ; CHECK-NEXT: .amdhsa_next_free_sgpr 8
 ; CHECK-NEXT: .amdhsa_float_round_mode_32 0
 ; CHECK-NEXT: .amdhsa_float_round_mode_16_64 0
@@ -192,7 +189,6 @@
 ; CHECK-NEXT: ; IMAGE_OP 0
 ; CHECK-NEXT: .amdhsa_next_free_vgpr 32
 ; CHECK-NEXT: .amdhsa_reserve_vcc 0
-; CHECK-NEXT: .amdhsa_reserve_xnack_mask 0
 ; CHECK-NEXT: .amdhsa_next_free_sgpr 8
 ; CHECK-NEXT: .amdhsa_float_round_mode_32 0
 ; CHECK-NEXT: .amdhsa_float_round_mode_16_64 0
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx12.s b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx12.s
index 71d74d0813fad..42f905cf49cf7 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx12.s
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-gfx12.s
@@ -17,7 +17,6 @@
 ; CHECK-NEXT: ; IMAGE_OP 0
 ; CHECK-NEXT: .amdhsa_next_free_vgpr 32
 ; CHECK-NEXT: .amdhsa_reserve_vcc 0
-; CHECK-NEXT: .amdhsa_reserve_xnack_mask 0
 ; CHECK-NEXT: .amdhsa_next_free_sgpr 8
 ; CHECK-NEXT: .amdhsa_float_round_mode_32 0
 ; CHECK-NEXT: .amdhsa_float_round_mode_16_64 0
@@ -71,7 +70,6 @@
 ; CHECK-NEXT: ; IMAGE_OP 0
 ; CHECK-NEXT: .amdhsa_next_free_vgpr 32
 ; CHECK-NEXT: .amdhsa_reserve_vcc 0
-; CHECK-NEXT: .amdhsa_reserve_xnack_mask 0
 ; CHECK-NEXT: .amdhsa_next_free_sgpr 8
 ; CHECK-NEXT: .amdhsa_float_round_mode_32 0
 ; CHECK-NEXT: .amdhsa_float_round_mode_16_64 0
diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-xnack-unsupported-eflags.yaml b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-xnack-unsupported-eflags.yaml
new file mode 100644
index 0000000000000..311daa0ffc255
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/kd-xnack-unsupported-eflags.yaml
@@ -0,0 +1,55 @@
+# Test that the disassembler surfaces .amdhsa_reserve_xnack_mask when an
+# object's ELF e_flags erroneously select xnack "on" for a target that does not
+# support xnack (gfx1200). The directive is normally suppressed for such
+# targets, but must be printed here so the invalid state remains visible.
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: llvm-objdump --disassemble-symbols=kernel.kd %t.o | FileCheck %s
+
+# CHECK: .amdgcn_target "amdgpu-amd-amdhsa-unknown-gfx1200:xnack+"
+# CHECK: .amdhsa_kernel kernel
+# CHECK: .amdhsa_reserve_xnack_mask 1
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_AMDGPU_HSA
+  ABIVersion:      0x3
+  Type:            ET_REL
+  Machine:         EM_AMDGPU
+  Flags:           [ EF_AMDGPU_MACH_AMDGCN_GFX1200, EF_AMDGPU_FEATURE_XNACK_ON_V4, EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4 ]
+  SectionHeaderStringTable: .strtab
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x4
+    Content:         00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CE0800000000004000000000000
+  - Name:            .rela.text
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .text
+    Relocations:
+      - Offset:          0x10
+        Symbol:          kernel
+        Type:            R_AMDGPU_REL64
+        Addend:          16
+  - Type:            SectionHeaderTable
+    Sections:
+      - Name:            .strtab
+      - Name:            .text
+      - Name:            .rela.text
+      - Name:            .symtab
+Symbols:
+  - Name:            kernel.kd
+    Type:            STT_OBJECT
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Size:            0x40
+  - Name:            kernel
+    Binding:         STB_GLOBAL
+    Other:           [ STV_PROTECTED ]
+...



More information about the llvm-commits mailing list