[Mlir-commits] [mlir] 36b95fa - [mlir][SPIR-V] Add Weak linkage type and SPV_AMD_weak_linkage extension (#195660)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon May 4 22:52:44 PDT 2026
Author: Arseniy Obolenskiy
Date: 2026-05-05T07:52:40+02:00
New Revision: 36b95facbc5f2cd6169ccc576fd172417d8acf4e
URL: https://github.com/llvm/llvm-project/commit/36b95facbc5f2cd6169ccc576fd172417d8acf4e
DIFF: https://github.com/llvm/llvm-project/commit/36b95facbc5f2cd6169ccc576fd172417d8acf4e.diff
LOG: [mlir][SPIR-V] Add Weak linkage type and SPV_AMD_weak_linkage extension (#195660)
- add 'Weak' linkage type (SPV_AMD_weak_linkage)
- deduce the Linkage capability and linkage-type extension from
linkage_attributes in UpdateVCE pass
---------
Co-authored-by: Jakub Kuderski <kubakuderski at gmail.com>
Added:
mlir/test/Target/SPIRV/linkage-types.mlir
Modified:
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
mlir/lib/Dialect/SPIRV/Transforms/UpdateVCEPass.cpp
mlir/test/Dialect/SPIRV/Transforms/vce-deduction.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
index c13d24942a9e9..282195c7a8c87 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
@@ -369,6 +369,7 @@ def SPV_AMD_shader_fragment_mask : I32EnumAttrCase<"SPV_AMD_shad
def SPV_AMD_shader_image_load_store_lod : I32EnumAttrCase<"SPV_AMD_shader_image_load_store_lod", 2004>;
def SPV_AMD_texture_gather_bias_lod : I32EnumAttrCase<"SPV_AMD_texture_gather_bias_lod", 2005>;
def SPV_AMD_shader_early_and_late_fragment_tests : I32EnumAttrCase<"SPV_AMD_shader_early_and_late_fragment_tests", 2006>;
+def SPV_AMD_weak_linkage : I32EnumAttrCase<"SPV_AMD_weak_linkage", 2007>;
def SPV_GOOGLE_decorate_string : I32EnumAttrCase<"SPV_GOOGLE_decorate_string", 3000>;
def SPV_GOOGLE_hlsl_functionality1 : I32EnumAttrCase<"SPV_GOOGLE_hlsl_functionality1", 3001>;
@@ -456,7 +457,7 @@ def SPIRV_ExtensionAttr :
SPV_AMD_gpu_shader_half_float_fetch, SPV_AMD_shader_ballot,
SPV_AMD_shader_explicit_vertex_parameter, SPV_AMD_shader_fragment_mask,
SPV_AMD_shader_image_load_store_lod, SPV_AMD_texture_gather_bias_lod,
- SPV_AMD_shader_early_and_late_fragment_tests,
+ SPV_AMD_shader_early_and_late_fragment_tests, SPV_AMD_weak_linkage,
SPV_GOOGLE_decorate_string, SPV_GOOGLE_hlsl_functionality1, SPV_GOOGLE_user_type,
SPV_INTEL_device_side_avc_motion_estimation, SPV_INTEL_media_block_io,
SPV_INTEL_shader_integer_functions2, SPV_INTEL_subgroups, SPV_INTEL_vector_compute,
@@ -3718,10 +3719,16 @@ def SPIRV_LT_LinkOnceODR : I32EnumAttrCase<"LinkOnceODR", 2> {
Capability<[SPIRV_C_Linkage]>
];
}
+def SPIRV_LT_Weak : I32EnumAttrCase<"Weak", 3> {
+ list<Availability> availability = [
+ Extension<[SPV_AMD_weak_linkage]>,
+ Capability<[SPIRV_C_Linkage]>
+ ];
+}
def SPIRV_LinkageTypeAttr :
SPIRV_I32EnumAttr<"LinkageType", "valid SPIR-V LinkageType", "linkage_type", [
- SPIRV_LT_Export, SPIRV_LT_Import, SPIRV_LT_LinkOnceODR
+ SPIRV_LT_Export, SPIRV_LT_Import, SPIRV_LT_LinkOnceODR, SPIRV_LT_Weak
]>;
def SPIRV_LC_None : I32BitEnumAttrCaseNone<"None">;
diff --git a/mlir/lib/Dialect/SPIRV/Transforms/UpdateVCEPass.cpp b/mlir/lib/Dialect/SPIRV/Transforms/UpdateVCEPass.cpp
index a72d891f3aad6..febfc0f7f57f5 100644
--- a/mlir/lib/Dialect/SPIRV/Transforms/UpdateVCEPass.cpp
+++ b/mlir/lib/Dialect/SPIRV/Transforms/UpdateVCEPass.cpp
@@ -153,6 +153,25 @@ void UpdateVCEPass::runOnOperation() {
valueTypes.append(op->operand_type_begin(), op->operand_type_end());
valueTypes.append(op->result_type_begin(), op->result_type_end());
+ // Per the SPIR-V spec Decoration table, the `LinkageAttributes` decoration
+ // requires the `Linkage` capability, and specific linkage types pull in
+ // additional extensions (e.g., `LinkOnceODR` -> `SPV_KHR_linkonce_odr`).
+ auto requireLinkage = [&](spirv::LinkageType linkageType) -> LogicalResult {
+ if (auto caps = spirv::getCapabilities(linkageType)) {
+ SmallVector<ArrayRef<spirv::Capability>, 1> capCandidates = {*caps};
+ if (failed(checkAndUpdateCapabilityRequirements(
+ op, targetEnv, capCandidates, deducedCapabilities)))
+ return failure();
+ }
+ if (auto exts = spirv::getExtensions(linkageType)) {
+ SmallVector<ArrayRef<spirv::Extension>, 1> extCandidates = {*exts};
+ if (failed(checkAndUpdateExtensionRequirements(
+ op, targetEnv, extCandidates, deducedExtensions)))
+ return failure();
+ }
+ return success();
+ };
+
// Special treatment for global variables, whose type requirements are
// conveyed by type attributes.
if (auto globalVar = dyn_cast<spirv::GlobalVariableOp>(op)) {
@@ -168,8 +187,17 @@ void UpdateVCEPass::runOnOperation() {
deducedCapabilities)))
return WalkResult::interrupt();
}
+
+ if (auto linkage = globalVar.getLinkageAttributes())
+ if (failed(requireLinkage(linkage->getLinkageType().getValue())))
+ return WalkResult::interrupt();
}
+ if (auto funcOp = dyn_cast<spirv::FuncOp>(op))
+ if (auto linkage = funcOp.getLinkageAttributes())
+ if (failed(requireLinkage(linkage->getLinkageType().getValue())))
+ return WalkResult::interrupt();
+
// If the op is FunctionLike make sure to process input and result types.
if (auto funcOpInterface = dyn_cast<FunctionOpInterface>(op)) {
llvm::append_range(valueTypes, funcOpInterface.getArgumentTypes());
diff --git a/mlir/test/Dialect/SPIRV/Transforms/vce-deduction.mlir b/mlir/test/Dialect/SPIRV/Transforms/vce-deduction.mlir
index d382ca5691fab..c9f3edc078b85 100644
--- a/mlir/test/Dialect/SPIRV/Transforms/vce-deduction.mlir
+++ b/mlir/test/Dialect/SPIRV/Transforms/vce-deduction.mlir
@@ -303,3 +303,31 @@ spirv.module Physical64 GLSL450 attributes {
spirv.GlobalVariable @recursive:
!spirv.ptr<!spirv.struct<rec, (!spirv.ptr<!spirv.struct<rec>, StorageBuffer>)>, StorageBuffer>
}
+
+// CHECK: requires #spirv.vce<v1.0, [Linkage, Shader, Matrix], [SPV_KHR_linkonce_odr]>
+spirv.module Logical GLSL450 attributes {
+ spirv.target_env = #spirv.target_env<
+ #spirv.vce<v1.5, [Shader, Linkage], [SPV_KHR_linkonce_odr]>,
+ #spirv.resource_limits<>>
+} {
+ spirv.func @linkonce_odr_fn() "None" attributes {
+ linkage_attributes = #spirv.linkage_attributes<
+ linkage_name = "linkonce_odr_fn",
+ linkage_type = <LinkOnceODR>>
+ } {
+ spirv.Return
+ }
+}
+
+// CHECK: requires #spirv.vce<v1.0, [Linkage, Shader, Matrix], [SPV_AMD_weak_linkage]>
+spirv.module Logical GLSL450 attributes {
+ spirv.target_env = #spirv.target_env<
+ #spirv.vce<v1.5, [Shader, Linkage], [SPV_AMD_weak_linkage]>,
+ #spirv.resource_limits<>>
+} {
+ spirv.GlobalVariable @weak_var {
+ linkage_attributes = #spirv.linkage_attributes<
+ linkage_name = "weak_var",
+ linkage_type = <Weak>>
+ } : !spirv.ptr<i32, Private>
+}
diff --git a/mlir/test/Target/SPIRV/linkage-types.mlir b/mlir/test/Target/SPIRV/linkage-types.mlir
new file mode 100644
index 0000000000000..bd9932f42ad6f
--- /dev/null
+++ b/mlir/test/Target/SPIRV/linkage-types.mlir
@@ -0,0 +1,45 @@
+// RUN: mlir-translate --no-implicit-module --test-spirv-roundtrip --split-input-file %s | FileCheck %s
+
+// SPV_AMD_weak_linkage's Weak value isn't in the bundled SPIRV-Tools grammar,
+// so this file skips the spirv-val step that other Target/SPIRV tests run.
+
+spirv.module Logical GLSL450 requires
+ #spirv.vce<v1.0, [Shader, Linkage], [SPV_KHR_linkonce_odr]> {
+ // CHECK: spirv.func @linkonce_odr_fn() "None" attributes
+ // CHECK-SAME: linkage_attributes = #spirv.linkage_attributes<linkage_name = "linkonce_odr_fn", linkage_type = <LinkOnceODR>>
+ spirv.func @linkonce_odr_fn() "None" attributes {
+ linkage_attributes = #spirv.linkage_attributes<
+ linkage_name = "linkonce_odr_fn",
+ linkage_type = <LinkOnceODR>>
+ } {
+ spirv.Return
+ }
+}
+
+// -----
+
+spirv.module Logical GLSL450 requires
+ #spirv.vce<v1.0, [Shader, Linkage], [SPV_AMD_weak_linkage]> {
+ // CHECK: spirv.func @weak_fn() "None" attributes
+ // CHECK-SAME: linkage_attributes = #spirv.linkage_attributes<linkage_name = "weak_fn", linkage_type = <Weak>>
+ spirv.func @weak_fn() "None" attributes {
+ linkage_attributes = #spirv.linkage_attributes<
+ linkage_name = "weak_fn",
+ linkage_type = <Weak>>
+ } {
+ spirv.Return
+ }
+}
+
+// -----
+
+spirv.module Logical GLSL450 requires
+ #spirv.vce<v1.0, [Shader, Linkage], [SPV_AMD_weak_linkage]> {
+ // CHECK: spirv.GlobalVariable @weak_var
+ // CHECK-SAME: linkage_attributes = #spirv.linkage_attributes<linkage_name = "weak_var", linkage_type = <Weak>>
+ spirv.GlobalVariable @weak_var {
+ linkage_attributes = #spirv.linkage_attributes<
+ linkage_name = "weak_var",
+ linkage_type = <Weak>>
+ } : !spirv.ptr<i32, Private>
+}
More information about the Mlir-commits
mailing list