[llvm-branch-commits] [mlir] [mlir][ROCDL] Add `rocdl.xnack` and `rocdl.sramecc` module attributes (PR #222444)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Sep 9 14:03:38 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-llvm
Author: Krzysztof Drewniak (krzysz00)
<details>
<summary>Changes</summary>
Since 27eeb7370281, the AMDGPU backend takes the xnack
and sramecc target-ID settings from the `amdgpu.xnack` and
`amdgpu.sramecc` module flags instead subtarget features, making the
old usage a hard error.
This commit adds `rocdl.xnack` and `rocdl.sramecc` module attributes
to the discardable attribute list the ROCDL dialect defines in order
to represent these flags and adds translations for them.
Omitting them means to leave these modifiers at
their default "either" state, which isn't the same as setting them to
false.
AI disclosure: Claude wrote this code and I reviewed it and tried to
reword the comments to something better.
---
Full diff: https://github.com/llvm/llvm-project/pull/222444.diff
5 Files Affected:
- (modified) mlir/include/mlir/Dialect/LLVMIR/ROCDLDialect.td (+13)
- (modified) mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp (+10)
- (modified) mlir/lib/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.cpp (+18)
- (modified) mlir/test/Dialect/LLVMIR/rocdl.mlir (+38)
- (modified) mlir/test/Target/LLVMIR/rocdl-module-flags.mlir (+29)
``````````diff
diff --git a/mlir/include/mlir/Dialect/LLVMIR/ROCDLDialect.td b/mlir/include/mlir/Dialect/LLVMIR/ROCDLDialect.td
index c92cdd49e8200..a05913bb2c15f 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/ROCDLDialect.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/ROCDLDialect.td
@@ -125,6 +125,14 @@ def ROCDL_Dialect : Dialect {
static constexpr ::llvm::StringLiteral getUniformWorkGroupSizeAttrName() {
return ::llvm::StringLiteral("rocdl.uniform_work_group_size");
}
+ /// Get the LLVM module flag key `rocdl.xnack` translates to.
+ static constexpr ::llvm::StringLiteral getModuleFlagKeyXnackName() {
+ return ::llvm::StringLiteral("amdgpu.xnack");
+ }
+ /// Get the LLVM module flag key `rocdl.sramecc` translates to.
+ static constexpr ::llvm::StringLiteral getModuleFlagKeySramEccName() {
+ return ::llvm::StringLiteral("amdgpu.sramecc");
+ }
/// Get the LLVM module flag key for the AMDGPU buffer OOB mode.
static constexpr ::llvm::StringLiteral
getModuleFlagKeyBufferOOBModeName() {
@@ -154,6 +162,11 @@ def ROCDL_Dialect : Dialect {
"::mlir::IntegerAttr":$max_flat_work_group_size,
"::mlir::IntegerAttr":$waves_per_eu,
"::mlir::BoolAttr":$unsafe_fp_atomics,
+ // Boolean attributes for explicitly enabling/disabling xnack or sramecc.
+ // Not setting these is a third "default"/"any" state, and not the same as
+ // false.
+ "::mlir::BoolAttr":$xnack,
+ "::mlir::BoolAttr":$sramecc,
// Correspond to LLVM metadata of the same name
"::mlir::UnitAttr":$last_use,
"::mlir::UnitAttr":$no_remote_memory,
diff --git a/mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp
index e5d2bed07d05c..b508475626a88 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp
@@ -103,6 +103,16 @@ LogicalResult ROCDLDialect::verifyOperationAttribute(Operation *op,
<< "' attribute attached to unexpected op";
}
}
+ // xnack/sramecc describe the whole code object.
+ if (attr.getName() == xnackAttrName.getName() ||
+ attr.getName() == srameccAttrName.getName()) {
+ if (!LLVM::satisfiesLLVMModule(op))
+ return op->emitError() << "'" << attr.getName().getValue()
+ << "' is only supported on modules";
+ if (!isa<BoolAttr>(attr.getValue()))
+ return op->emitError()
+ << "'" << attr.getName().getValue() << "' must be a boolean";
+ }
return success();
}
diff --git a/mlir/lib/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.cpp
index 18eb07a9e17df..00e4164a9f4aa 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.cpp
@@ -149,6 +149,24 @@ class ROCDLDialectLLVMIRTranslationInterface
else
llvmFunc->removeFnAttr("uniform-work-group-size");
}
+
+ bool isXnack =
+ dialect->getXnackAttrHelper().getName() == attribute.getName();
+ bool isSramecc =
+ dialect->getSrameccAttrHelper().getName() == attribute.getName();
+ if (isXnack || isSramecc) {
+ auto value = dyn_cast<BoolAttr>(attribute.getValue());
+ if (!value)
+ return op->emitOpError(Twine(attribute.getName()) +
+ " must be a boolean");
+ StringRef key = isXnack
+ ? ROCDL::ROCDLDialect::getModuleFlagKeyXnackName()
+ : ROCDL::ROCDLDialect::getModuleFlagKeySramEccName();
+ moduleTranslation.getLLVMModule()->addModuleFlag(
+ llvm::Module::Error, key,
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvmContext),
+ value.getValue()));
+ }
if (dialect->getUnsafeFpAtomicsAttrHelper().getName() ==
attribute.getName()) {
auto func = dyn_cast<LLVM::LLVMFuncOp>(op);
diff --git a/mlir/test/Dialect/LLVMIR/rocdl.mlir b/mlir/test/Dialect/LLVMIR/rocdl.mlir
index 6a6f99ac7d2e7..58e337ae771df 100644
--- a/mlir/test/Dialect/LLVMIR/rocdl.mlir
+++ b/mlir/test/Dialect/LLVMIR/rocdl.mlir
@@ -1856,6 +1856,44 @@ module {
// -----
+// CHECK-LABEL: module @module_target_id_settings
+// CHECK-SAME: attributes {rocdl.sramecc = false, rocdl.xnack = true}
+module @module_target_id_settings attributes {
+ rocdl.xnack = true, rocdl.sramecc = false} {
+}
+
+// -----
+
+// CHECK-LABEL: gpu.module @gpu_module_target_id_settings
+// CHECK-SAME: attributes {rocdl.sramecc = true, rocdl.xnack = false}
+gpu.module @gpu_module_target_id_settings attributes {
+ rocdl.xnack = false, rocdl.sramecc = true} {
+}
+
+// -----
+
+// expected-error at below {{'rocdl.xnack' is only supported on modules}}
+llvm.func private @xnack_on_func() attributes {rocdl.xnack = true}
+
+// -----
+
+// expected-error at below {{'rocdl.sramecc' is only supported on modules}}
+llvm.func private @sramecc_on_func() attributes {rocdl.sramecc = true}
+
+// -----
+
+// expected-error at below {{'rocdl.xnack' must be a boolean}}
+module attributes {rocdl.xnack = "on"} {
+}
+
+// -----
+
+// expected-error at below {{'rocdl.sramecc' must be a boolean}}
+module attributes {rocdl.sramecc = 1 : i32} {
+}
+
+// -----
+
// Just check these don't emit errors.
gpu.module @module_1 [#rocdl.target<O = 1, chip = "gfx900", abi = "500", link = ["my_device_lib.bc"], flags = {fast, daz, unsafe_math}>] {
}
diff --git a/mlir/test/Target/LLVMIR/rocdl-module-flags.mlir b/mlir/test/Target/LLVMIR/rocdl-module-flags.mlir
index 8e1db326e7f28..2f67770190b13 100644
--- a/mlir/test/Target/LLVMIR/rocdl-module-flags.mlir
+++ b/mlir/test/Target/LLVMIR/rocdl-module-flags.mlir
@@ -45,3 +45,32 @@ module {
// CHECK-LABEL: define void @generic_oob_relaxed()
// CHECK: !llvm.module.flags = !{![[GENERIC_BUFFER_RELAXED:[0-9]+]]
// CHECK-DAG: ![[GENERIC_BUFFER_RELAXED]] = !{i32 7, !"amdgpu.buffer.oob.mode", i32 1}
+
+// -----
+
+module attributes {rocdl.xnack = true, rocdl.sramecc = false} {
+ llvm.func @xnack_on_sramecc_off() {
+ llvm.return
+ }
+}
+
+// CHECK-LABEL: define void @xnack_on_sramecc_off()
+// CHECK: !llvm.module.flags = !{![[SRAMECC_OFF:[0-9]+]], ![[XNACK_ON:[0-9]+]]
+// CHECK-DAG: ![[SRAMECC_OFF]] = !{i32 1, !"amdgpu.sramecc", i32 0}
+// CHECK-DAG: ![[XNACK_ON]] = !{i32 1, !"amdgpu.xnack", i32 1}
+
+// -----
+
+// An unmentioned setting stays unmentioned: the backend reads that as "either",
+// which is not the same as the feature being disabled.
+
+module attributes {rocdl.xnack = false} {
+ llvm.func @xnack_off_sramecc_any() {
+ llvm.return
+ }
+}
+
+// CHECK-LABEL: define void @xnack_off_sramecc_any()
+// CHECK: !llvm.module.flags = !{![[XNACK_OFF:[0-9]+]]
+// CHECK-DAG: ![[XNACK_OFF]] = !{i32 1, !"amdgpu.xnack", i32 0}
+// CHECK-NOT: amdgpu.sramecc
``````````
</details>
https://github.com/llvm/llvm-project/pull/222444
More information about the llvm-branch-commits
mailing list