Skip to content

Conversation

@simeonschaub
Copy link
Contributor

fixes #163777

Test was written with help from Copilot

fixes llvm#163777

Test was written with help from Copilot
@llvmbot
Copy link
Member

llvmbot commented Oct 19, 2025

@llvm/pr-subscribers-backend-spir-v

Author: Simeon David Schaub (simeonschaub)

Changes

fixes #163777

Test was written with help from Copilot


Full diff: https://github.com/llvm/llvm-project/pull/164175.diff

2 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp (+1-1)
  • (added) llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll (+36)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index c6c618218006a4..678ecfe32174d2 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -1706,7 +1706,7 @@ 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/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll b/llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll
new file mode 100644
index 00000000000000..82cbae2d8d9089
--- /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
+}

@github-actions
Copy link

github-actions bot commented Oct 19, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

simeonschaub added a commit to JuliaPackaging/Yggdrasil that referenced this pull request Oct 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SPIRV] alloca generates OpVariable instruction for the wrong type

2 participants