Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions S/SPIRV_LLVM_Backend/build_tarballs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ LLVM_SRCDIR=$(pwd)
atomic_patch -p1 $WORKSPACE/srcdir/patches/avoid_builtin_available.patch
atomic_patch -p1 $WORKSPACE/srcdir/patches/fix_insertvalue.patch
atomic_patch -p1 $WORKSPACE/srcdir/patches/atomic_cmpxchg_64bit.patch
atomic_patch -p1 $WORKSPACE/srcdir/patches/alloca_aggregate_type.patch

install_license LICENSE.TXT

Expand Down
73 changes: 73 additions & 0 deletions S/SPIRV_LLVM_Backend/bundled/patches/alloca_aggregate_type.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
From 4fdb0945f3a3eeb2602dc5460563922b2e50e027 Mon Sep 17 00:00:00 2001
From: Simeon David Schaub <[email protected]>
Date: Sun, 19 Oct 2025 19:49:09 +0200
Subject: [PATCH] [SPIRV] fix `alloca` -> `OpVariable` lowering

fixes #163777

Test was written with help from Copilot
---
lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 3 +-
test/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/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 702206b8e0dc..52357f53df19 100644
--- a/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -1553,7 +1553,8 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
return;
} else if (isTodoType(Pointer)) {
eraseTodoType(Pointer);
- if (!isa<CallInst>(Pointer) && !isa<GetElementPtrInst>(Pointer)) {
+ if (!isa<CallInst>(Pointer) && !isa<GetElementPtrInst>(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/test/CodeGen/SPIRV/alloca-aggregate-type.ll b/test/CodeGen/SPIRV/alloca-aggregate-type.ll
new file mode 100644
index 000000000000..82cbae2d8d90
--- /dev/null
+++ b/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
+}
--
2.51.0