Skip to content

Commit dfa5dfe

Browse files
committed
[SPIRV] fix alloca -> OpVariable lowering
fixes #163777 Test was written with help from Copilot
1 parent 5614d36 commit dfa5dfe

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,7 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
17061706
return;
17071707
} else if (isTodoType(Pointer)) {
17081708
eraseTodoType(Pointer);
1709-
if (!isa<CallInst>(Pointer) && !isa<GetElementPtrInst>(Pointer)) {
1709+
if (!isa<CallInst>(Pointer) && !isa<GetElementPtrInst>(Pointer) && !isa<AllocaInst>(Pointer)) {
17101710
// If this wouldn't be the first spv_ptrcast but existing type info is
17111711
// uncomplete, update spv_assign_ptr_type arguments.
17121712
if (CallInst *AssignCI = GR->findAssignPtrTypeInstr(Pointer)) {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; Test that alloca with aggregate type generates correct OpVariable
2+
; with the array type as the pointee, not a pointer-to-pointer type
3+
;
4+
; This test verifies that when we have an alloca of an array containing
5+
; structs with pointers, the OpVariable uses the correct array type
6+
; instead of incorrectly using a pointer-to-pointer type.
7+
8+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
9+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
10+
11+
; CHECK-DAG: %[[#Int8:]] = OpTypeInt 8 0
12+
; CHECK-DAG: %[[#Int64:]] = OpTypeInt 64 0
13+
; CHECK-DAG: %[[#Int32:]] = OpTypeInt 32 0
14+
; CHECK-DAG: %[[#One:]] = OpConstant %[[#Int32]] 1
15+
; CHECK-DAG: %[[#Two:]] = OpConstant %[[#Int32]] 2
16+
; CHECK-DAG: %[[#PtrCross:]] = OpTypePointer CrossWorkgroup %[[#Int8]]
17+
; CHECK-DAG: %[[#Array1:]] = OpTypeArray %[[#Int64]] %[[#One]]
18+
; CHECK-DAG: %[[#Struct1:]] = OpTypeStruct %[[#PtrCross]] %[[#Int64]] %[[#Array1]] %[[#Int64]]
19+
; CHECK-DAG: %[[#Array2:]] = OpTypeArray %[[#Array1]] %[[#Two]]
20+
; CHECK-DAG: %[[#Struct2:]] = OpTypeStruct %[[#Struct1]] %[[#Array2]]
21+
; CHECK-DAG: %[[#Struct3:]] = OpTypeStruct %[[#Struct2]]
22+
; CHECK-DAG: %[[#ArrayStruct:]] = OpTypeArray %[[#Struct3]] %[[#One]]
23+
; CHECK-DAG: %[[#PtrFunc:]] = OpTypePointer Function %[[#ArrayStruct]]
24+
25+
; Verify OpVariable uses the array type, not pointer-to-pointer
26+
; CHECK: %[[#Var:]] = OpVariable %[[#PtrFunc]] Function
27+
28+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
29+
target triple = "spirv64-unknown-unknown"
30+
31+
define spir_kernel void @test_alloca_aggregate() local_unnamed_addr {
32+
entry:
33+
%y = alloca [1 x { { { ptr addrspace(1), i64, [1 x i64], i64 }, [2 x [1 x i64]] } }], align 8
34+
%ptr = load ptr addrspace(1), ptr %y, align 8
35+
ret void
36+
}

0 commit comments

Comments
 (0)