[llvm] [SPIRV] fix `alloca` -> `OpVariable` lowering (PR #164175)

Juan Manuel Martinez CaamaƱo via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 11 04:07:17 PDT 2026


https://github.com/jmmartinez updated https://github.com/llvm/llvm-project/pull/164175

>From 0f61c01274dbb0e4624d0ea9d236bc90e2b5b273 Mon Sep 17 00:00:00 2001
From: Simeon David Schaub <simeon at schaub.rocks>
Date: Sun, 19 Oct 2025 19:49:09 +0200
Subject: [PATCH 1/3] [SPIRV] fix `alloca` -> `OpVariable` lowering

fixes #163777

Test was written with help from Copilot
---
 llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp |  3 +-
 .../CodeGen/SPIRV/alloca-aggregate-type.ll    | 36 +++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index c84f41dada005..e7c739f47ee4f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -1909,7 +1909,8 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
       return;
     } else if (isTodoType(Pointer)) {
       eraseTodoType(Pointer);
-      if (!isa<CallInst>(Pointer) && !isaGEP(Pointer)) {
+      if (!isa<CallInst>(Pointer) && !isaGEP(Pointer) &&
+          !isa<AllocaInst>(Pointer)) {
         //  If this wouldn't be the first spv_ptrcast but existing type info is
         //  uncomplete, update spv_assign_ptr_type arguments.
         if (CallInst *AssignCI = GR->findAssignPtrTypeInstr(Pointer)) {
diff --git a/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll b/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll
new file mode 100644
index 0000000000000..82cbae2d8d908
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll
@@ -0,0 +1,36 @@
+; Test that alloca with aggregate type generates correct OpVariable
+; with the array type as the pointee, not a pointer-to-pointer type
+;
+; This test verifies that when we have an alloca of an array containing
+; structs with pointers, the OpVariable uses the correct array type
+; instead of incorrectly using a pointer-to-pointer type.
+
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: %[[#Int8:]] = OpTypeInt 8 0
+; CHECK-DAG: %[[#Int64:]] = OpTypeInt 64 0
+; CHECK-DAG: %[[#Int32:]] = OpTypeInt 32 0
+; CHECK-DAG: %[[#One:]] = OpConstant %[[#Int32]] 1
+; CHECK-DAG: %[[#Two:]] = OpConstant %[[#Int32]] 2
+; CHECK-DAG: %[[#PtrCross:]] = OpTypePointer CrossWorkgroup %[[#Int8]]
+; CHECK-DAG: %[[#Array1:]] = OpTypeArray %[[#Int64]] %[[#One]]
+; CHECK-DAG: %[[#Struct1:]] = OpTypeStruct %[[#PtrCross]] %[[#Int64]] %[[#Array1]] %[[#Int64]]
+; CHECK-DAG: %[[#Array2:]] = OpTypeArray %[[#Array1]] %[[#Two]]
+; CHECK-DAG: %[[#Struct2:]] = OpTypeStruct %[[#Struct1]] %[[#Array2]]
+; CHECK-DAG: %[[#Struct3:]] = OpTypeStruct %[[#Struct2]]
+; CHECK-DAG: %[[#ArrayStruct:]] = OpTypeArray %[[#Struct3]] %[[#One]]
+; CHECK-DAG: %[[#PtrFunc:]] = OpTypePointer Function %[[#ArrayStruct]]
+
+; Verify OpVariable uses the array type, not pointer-to-pointer
+; CHECK: %[[#Var:]] = OpVariable %[[#PtrFunc]] Function
+
+target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
+target triple = "spirv64-unknown-unknown"
+
+define spir_kernel void @test_alloca_aggregate() local_unnamed_addr {
+entry:
+  %y = alloca [1 x { { { ptr addrspace(1), i64, [1 x i64], i64 }, [2 x [1 x i64]] } }], align 8
+  %ptr = load ptr addrspace(1), ptr %y, align 8
+  ret void
+}

>From 3e15ac9dc7d7746b396337bee396a2405e35bb52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?=
 <jmartinezcaamao at gmail.com>
Date: Wed, 11 Mar 2026 10:41:15 +0100
Subject: [PATCH 2/3] Remove triple and datalayout from test

---
 llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll b/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll
index 82cbae2d8d908..dda7c6993e426 100644
--- a/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll
+++ b/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll
@@ -25,9 +25,6 @@
 ; Verify OpVariable uses the array type, not pointer-to-pointer
 ; CHECK: %[[#Var:]] = OpVariable %[[#PtrFunc]] Function
 
-target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
-target triple = "spirv64-unknown-unknown"
-
 define spir_kernel void @test_alloca_aggregate() local_unnamed_addr {
 entry:
   %y = alloca [1 x { { { ptr addrspace(1), i64, [1 x i64], i64 }, [2 x [1 x i64]] } }], align 8

>From d0a0f9d007383586d6afd285f57420e8a50055fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?=
 <jmartinezcaamao at gmail.com>
Date: Wed, 11 Mar 2026 10:41:41 +0100
Subject: [PATCH 3/3] Remove unnecesary attributes

---
 llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll b/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll
index dda7c6993e426..4609efc63b3e5 100644
--- a/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll
+++ b/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll
@@ -25,9 +25,9 @@
 ; Verify OpVariable uses the array type, not pointer-to-pointer
 ; CHECK: %[[#Var:]] = OpVariable %[[#PtrFunc]] Function
 
-define spir_kernel void @test_alloca_aggregate() local_unnamed_addr {
+define void @test_alloca_aggregate() {
 entry:
-  %y = alloca [1 x { { { ptr addrspace(1), i64, [1 x i64], i64 }, [2 x [1 x i64]] } }], align 8
+  %y = alloca [1 x { { { ptr addrspace(1), i64, [1 x i64], i64 }, [2 x [1 x i64]] } }]
   %ptr = load ptr addrspace(1), ptr %y, align 8
   ret void
 }



More information about the llvm-commits mailing list