[llvm] [SPIR-V] Enable structurizer for kernel environment (PR #166079)

Dmitry Sidorov via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 2 09:27:26 PST 2025


https://github.com/MrSidims created https://github.com/llvm/llvm-project/pull/166079

None

>From a81d55a6084725cfba67aa922b2b92a090563687 Mon Sep 17 00:00:00 2001
From: "Sidorov, Dmitry" <dmitry.sidorov at intel.com>
Date: Sun, 2 Nov 2025 18:24:56 +0100
Subject: [PATCH] [SPIR-V] Enable structurizer for kernel environment

---
 llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp  |  2 +
 .../CodeGen/SPIRV/structurizer/kernel-loop.ll | 80 +++++++++++++++++++
 2 files changed, 82 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/structurizer/kernel-loop.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index 7dd0b95cd9763..eba99f6dacb59 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -181,7 +181,9 @@ void SPIRVPassConfig::addISelPrepare() {
     // If an address space cast is not removed while targeting Vulkan, lowering
     // will fail during MIR lowering.
     addPass(createInferAddressSpacesPass());
+  }
 
+  if (TM.getSubtargetImpl()->isShader() || TM.getSubtargetImpl()->isKernel()) {
     // 1.  Simplify loop for subsequent transformations. After this steps, loops
     // have the following properties:
     //  - loops have a single entry edge (pre-header to loop header).
diff --git a/llvm/test/CodeGen/SPIRV/structurizer/kernel-loop.ll b/llvm/test/CodeGen/SPIRV/structurizer/kernel-loop.ll
new file mode 100644
index 0000000000000..56dc916ac7bd3
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/structurizer/kernel-loop.ll
@@ -0,0 +1,80 @@
+; RUN: llc -mtriple=spirv64-unknown-opencl -O0 %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-opencl %s -o - -filetype=obj | spirv-val %}
+
+; This test verifies that the structurizer pass runs for OpenCL kernels,
+; generating structured control flow with OpLoopMerge instructions and
+; translating loop metadata to appropriate LoopControl operands.
+
+; CHECK: OpEntryPoint Kernel %[[#kernel_unroll:]] "test_kernel_unroll"
+; CHECK: OpEntryPoint Kernel %[[#kernel_dontunroll:]] "test_kernel_dontunroll"
+
+; Verify unroll metadata is translated to Unroll LoopControl
+; CHECK: %[[#kernel_unroll]] = OpFunction
+; CHECK: OpLabel
+; CHECK: OpLoopMerge %[[#]] %[[#]] Unroll
+; CHECK: OpFunctionEnd
+
+; Verify dont_unroll metadata is translated to DontUnroll LoopControl
+; CHECK: %[[#kernel_dontunroll]] = OpFunction
+; CHECK: OpLabel
+; CHECK: OpLoopMerge %[[#]] %[[#]] DontUnroll
+; CHECK: OpFunctionEnd
+
+define spir_kernel void @test_kernel_unroll(ptr addrspace(1) %out) {
+entry:
+  %i = alloca i32, align 4
+  store i32 0, ptr %i, align 4
+  br label %for.cond
+
+for.cond:
+  %0 = load i32, ptr %i, align 4
+  %cmp = icmp slt i32 %0, 10
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:
+  %1 = load i32, ptr %i, align 4
+  %arrayidx = getelementptr inbounds i32, ptr addrspace(1) %out, i64 0
+  store i32 %1, ptr addrspace(1) %arrayidx, align 4
+  br label %for.inc
+
+for.inc:
+  %2 = load i32, ptr %i, align 4
+  %inc = add nsw i32 %2, 1
+  store i32 %inc, ptr %i, align 4
+  br label %for.cond, !llvm.loop !0
+
+for.end:
+  ret void
+}
+
+define spir_kernel void @test_kernel_dontunroll(ptr addrspace(1) %out) {
+entry:
+  %i = alloca i32, align 4
+  store i32 0, ptr %i, align 4
+  br label %for.cond
+
+for.cond:
+  %0 = load i32, ptr %i, align 4
+  %cmp = icmp slt i32 %0, 10
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:
+  %1 = load i32, ptr %i, align 4
+  %arrayidx = getelementptr inbounds i32, ptr addrspace(1) %out, i64 0
+  store i32 %1, ptr addrspace(1) %arrayidx, align 4
+  br label %for.inc
+
+for.inc:
+  %2 = load i32, ptr %i, align 4
+  %inc = add nsw i32 %2, 1
+  store i32 %inc, ptr %i, align 4
+  br label %for.cond, !llvm.loop !2
+
+for.end:
+  ret void
+}
+
+!0 = distinct !{!0, !1}
+!1 = !{!"llvm.loop.unroll.full"}
+!2 = distinct !{!2, !3}
+!3 = !{!"llvm.loop.unroll.disable"}



More information about the llvm-commits mailing list