[llvm] [SPIR-V] Fix OpTypeImage capability requirements for Vulkan (PR #192626)
Arseniy Obolenskiy via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 17 03:32:58 PDT 2026
https://github.com/aobolensk created https://github.com/llvm/llvm-project/pull/192626
Emit StorageImageMultisample for 2D multisampled storage images and ImageMSArray for 2D multisampled arrayed images
>From a37471a6b01eed7cebef185fc47c071e00c5fe21 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Fri, 17 Apr 2026 12:31:34 +0200
Subject: [PATCH] [SPIR-V] Fix OpTypeImage capability requirements for Vulkan
Emit StorageImageMultisample for 2D multisampled storage images and ImageMSArray for 2D multisampled arrayed images
---
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 8 +++-
llvm/test/CodeGen/SPIRV/image_dim.ll | 44 +++++++++++++++++--
2 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index aec9b15df9189..ac4decc455c33 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -965,7 +965,9 @@ void RequirementHandler::initAvailableCapabilitiesForVulkan(
Capability::StorageImageArrayDynamicIndexing,
Capability::DerivativeControl, Capability::MinLod,
Capability::ImageQuery, Capability::ImageGatherExtended,
- Capability::Addresses, Capability::VulkanMemoryModelKHR});
+ Capability::Addresses, Capability::VulkanMemoryModelKHR,
+ Capability::StorageImageMultisample,
+ Capability::ImageMSArray});
// Became core in Vulkan 1.2
if (ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
@@ -1059,8 +1061,12 @@ static void addOpTypeImageReqs(const MachineInstr &MI,
break;
case SPIRV::Dim::DIM_2D:
if (IsMultisampled && NoSampler)
+ Reqs.addRequirements(SPIRV::Capability::StorageImageMultisample);
+ if (IsMultisampled && IsArrayed)
Reqs.addRequirements(SPIRV::Capability::ImageMSArray);
break;
+ case SPIRV::Dim::DIM_3D:
+ break;
case SPIRV::Dim::DIM_Cube:
Reqs.addRequirements(SPIRV::Capability::Shader);
if (IsArrayed)
diff --git a/llvm/test/CodeGen/SPIRV/image_dim.ll b/llvm/test/CodeGen/SPIRV/image_dim.ll
index 7c97e87bd4734..693e26a98455f 100644
--- a/llvm/test/CodeGen/SPIRV/image_dim.ll
+++ b/llvm/test/CodeGen/SPIRV/image_dim.ll
@@ -1,8 +1,46 @@
-; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; Test OpTypeImage dimension-based capability requirements.
+; target("spirv.Image", SampledType, Dim, Depth, Arrayed, MS, Sampled, Format)
-; CHECK-SPIRV-DAG: OpCapability Sampled1D
-; CHECK-SPIRV-DAG: OpCapability SampledBuffer
+; RUN: split-file %s %t
+;; OpenCL: 1D and Buffer sampled images require Sampled1D and SampledBuffer.
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %t/opencl.ll -o - | FileCheck %s --check-prefix=CHECK-OPENCL
+
+;; Vulkan: 2D multisampled storage images require StorageImageMultisample;
+;; 2D multisampled arrayed images additionally require ImageMSArray.
+;; 3D images require no extra capabilities.
+; RUN: llc -O0 -mtriple=spirv-vulkan-library %t/vulkan.ll -o - | FileCheck %s --check-prefix=CHECK-VULKAN
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-vulkan-library %t/vulkan.ll -o - -filetype=obj | spirv-val %}
+
+; CHECK-OPENCL-DAG: OpCapability Sampled1D
+; CHECK-OPENCL-DAG: OpCapability SampledBuffer
+
+; CHECK-VULKAN-DAG: OpCapability StorageImageMultisample
+; CHECK-VULKAN-DAG: OpCapability ImageMSArray
+; CHECK-VULKAN-NOT: OpCapability ImageCubeArray
+
+;--- opencl.ll
define spir_kernel void @test_image_dim(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 0) %image1d, target("spirv.Image", void, 5, 0, 0, 0, 0, 0, 0) %image1d_buffer) {
ret void
}
+
+;--- vulkan.ll
+define void @test_2d_ms_storage(
+ target("spirv.Image", float, 1, 0, 0, 1, 2, 3) %image2d_ms_storage
+) #0 {
+ ret void
+}
+
+define void @test_2d_ms_arrayed_storage(
+ target("spirv.Image", float, 1, 0, 1, 1, 2, 3) %image2d_ms_arrayed_storage
+) #0 {
+ ret void
+}
+
+define void @test_3d(
+ target("spirv.Image", float, 2, 0, 0, 0, 2, 3) %image3d_storage
+) #0 {
+ ret void
+}
+
+attributes #0 = { convergent noinline norecurse "frame-pointer"="all" }
More information about the llvm-commits
mailing list