|
| 1 | +From 4fdb0945f3a3eeb2602dc5460563922b2e50e027 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Simeon David Schaub < [email protected]> |
| 3 | +Date: Sun, 19 Oct 2025 19:49:09 +0200 |
| 4 | +Subject: [PATCH] [SPIRV] fix `alloca` -> `OpVariable` lowering |
| 5 | + |
| 6 | +fixes #163777 |
| 7 | + |
| 8 | +Test was written with help from Copilot |
| 9 | +--- |
| 10 | + lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 3 +- |
| 11 | + test/CodeGen/SPIRV/alloca-aggregate-type.ll | 36 +++++++++++++++++++++ |
| 12 | + 2 files changed, 38 insertions(+), 1 deletion(-) |
| 13 | + create mode 100644 llvm/test/CodeGen/SPIRV/alloca-aggregate-type.ll |
| 14 | + |
| 15 | +diff --git a/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp |
| 16 | +index 702206b8e0dc..52357f53df19 100644 |
| 17 | +--- a/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp |
| 18 | ++++ b/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp |
| 19 | +@@ -1553,7 +1553,8 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast( |
| 20 | + return; |
| 21 | + } else if (isTodoType(Pointer)) { |
| 22 | + eraseTodoType(Pointer); |
| 23 | +- if (!isa<CallInst>(Pointer) && !isa<GetElementPtrInst>(Pointer)) { |
| 24 | ++ if (!isa<CallInst>(Pointer) && !isa<GetElementPtrInst>(Pointer) && |
| 25 | ++ !isa<AllocaInst>(Pointer)) { |
| 26 | + // If this wouldn't be the first spv_ptrcast but existing type info is |
| 27 | + // uncomplete, update spv_assign_ptr_type arguments. |
| 28 | + if (CallInst *AssignCI = GR->findAssignPtrTypeInstr(Pointer)) { |
| 29 | +diff --git a/test/CodeGen/SPIRV/alloca-aggregate-type.ll b/test/CodeGen/SPIRV/alloca-aggregate-type.ll |
| 30 | +new file mode 100644 |
| 31 | +index 000000000000..82cbae2d8d90 |
| 32 | +--- /dev/null |
| 33 | ++++ b/test/CodeGen/SPIRV/alloca-aggregate-type.ll |
| 34 | +@@ -0,0 +1,36 @@ |
| 35 | ++; Test that alloca with aggregate type generates correct OpVariable |
| 36 | ++; with the array type as the pointee, not a pointer-to-pointer type |
| 37 | ++; |
| 38 | ++; This test verifies that when we have an alloca of an array containing |
| 39 | ++; structs with pointers, the OpVariable uses the correct array type |
| 40 | ++; instead of incorrectly using a pointer-to-pointer type. |
| 41 | ++ |
| 42 | ++; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s |
| 43 | ++; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} |
| 44 | ++ |
| 45 | ++; CHECK-DAG: %[[#Int8:]] = OpTypeInt 8 0 |
| 46 | ++; CHECK-DAG: %[[#Int64:]] = OpTypeInt 64 0 |
| 47 | ++; CHECK-DAG: %[[#Int32:]] = OpTypeInt 32 0 |
| 48 | ++; CHECK-DAG: %[[#One:]] = OpConstant %[[#Int32]] 1 |
| 49 | ++; CHECK-DAG: %[[#Two:]] = OpConstant %[[#Int32]] 2 |
| 50 | ++; CHECK-DAG: %[[#PtrCross:]] = OpTypePointer CrossWorkgroup %[[#Int8]] |
| 51 | ++; CHECK-DAG: %[[#Array1:]] = OpTypeArray %[[#Int64]] %[[#One]] |
| 52 | ++; CHECK-DAG: %[[#Struct1:]] = OpTypeStruct %[[#PtrCross]] %[[#Int64]] %[[#Array1]] %[[#Int64]] |
| 53 | ++; CHECK-DAG: %[[#Array2:]] = OpTypeArray %[[#Array1]] %[[#Two]] |
| 54 | ++; CHECK-DAG: %[[#Struct2:]] = OpTypeStruct %[[#Struct1]] %[[#Array2]] |
| 55 | ++; CHECK-DAG: %[[#Struct3:]] = OpTypeStruct %[[#Struct2]] |
| 56 | ++; CHECK-DAG: %[[#ArrayStruct:]] = OpTypeArray %[[#Struct3]] %[[#One]] |
| 57 | ++; CHECK-DAG: %[[#PtrFunc:]] = OpTypePointer Function %[[#ArrayStruct]] |
| 58 | ++ |
| 59 | ++; Verify OpVariable uses the array type, not pointer-to-pointer |
| 60 | ++; CHECK: %[[#Var:]] = OpVariable %[[#PtrFunc]] Function |
| 61 | ++ |
| 62 | ++target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1" |
| 63 | ++target triple = "spirv64-unknown-unknown" |
| 64 | ++ |
| 65 | ++define spir_kernel void @test_alloca_aggregate() local_unnamed_addr { |
| 66 | ++entry: |
| 67 | ++ %y = alloca [1 x { { { ptr addrspace(1), i64, [1 x i64], i64 }, [2 x [1 x i64]] } }], align 8 |
| 68 | ++ %ptr = load ptr addrspace(1), ptr %y, align 8 |
| 69 | ++ ret void |
| 70 | ++} |
| 71 | +-- |
| 72 | +2.51.0 |
| 73 | + |
0 commit comments