[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