Skip to content

Commit bbe9438

Browse files
victor-edsjsji
authored andcommitted
Handle constant sized array allocations using no extension (#2713)
In LLVM, array allocations might have constant size: %array = alloca i32, i64 4, align 4 Represent this kind of allocations using OpVariable + OpBitcast. Before this patch, the SPV_INTEL_variable_length_array extension was used. Signed-off-by: Victor Perez <[email protected]> Original commit: KhronosGroup/SPIRV-LLVM-Translator@ea2fcc172f6861e
1 parent 7be7837 commit bbe9438

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,14 +2268,14 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
22682268
SPIRVValue *Length = transValue(Alc->getArraySize(), BB);
22692269
assert(Length && "Couldn't translate array size!");
22702270

2271-
if (isSpecConstantOpCode(Length->getOpCode())) {
2272-
// SPIR-V arrays length can be expressed using a specialization
2273-
// constant.
2271+
if (isConstantOpCode(Length->getOpCode())) {
2272+
// Length can be any constant instruction, either a specialization
2273+
// constant or a non-specialization constant.
22742274
//
2275-
// Spec Constant Length Arrays need special treatment, as the allocation
2276-
// type will be 'OpTypePointer(Function, OpTypeArray(ElementType,
2277-
// Length))', we need to bitcast the obtained pointer to the expected
2278-
// type: 'OpTypePointer(Function, ElementType).
2275+
// Array allocations need special treatment: as the allocation type will
2276+
// be 'OpTypePointer(Function, OpTypeArray(ElementType, Length))', we
2277+
// need to bitcast the obtained pointer to the expected type:
2278+
// 'OpTypePointer(Function, ElementType).
22792279
SPIRVType *AllocationType = BM->addPointerType(
22802280
StorageClassFunction,
22812281
BM->addArrayType(transType(Alc->getAllocatedType()), Length));

llvm-spirv/test/array-alloca.ll

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -o %t.spv
3+
4+
; Validation test.
5+
; RUN: spirv-val %t.spv
6+
7+
; SPIR-V codegen test.
8+
; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
9+
10+
; Roundtrip test.
11+
; RUN: llvm-spirv -r %t.spv -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK-LLVM
12+
13+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
14+
target triple = "spir64-unknown-unknown"
15+
16+
; CHECK-SPIRV: Decorate [[#ARR:]] Alignment 4
17+
; CHECK-SPIRV: Decorate [[#BITARR:]] Alignment 4
18+
19+
; CHECK-SPIRV: TypeInt [[#I32:]] 32 0
20+
; CHECK-SPIRV: TypeInt [[#I64:]] 64 0
21+
; CHECK-SPIRV: Constant [[#I64]] [[#SIZE:]] 4 0
22+
; CHECK-SPIRV: TypeVoid [[#VOID:]]
23+
; CHECK-SPIRV: TypeFunction [[#FUNCTY:]] [[#VOID]]
24+
; CHECK-SPIRV: TypePointer [[#PTRTY:]] [[#FUNCSTORAGE:]] [[#I32]]
25+
; CHECK-SPIRV: TypeArray [[#ARRTY:]] [[#I32]] [[#SIZE]]
26+
; CHECK-SPIRV: TypePointer [[#ARRPTRTY:]] [[#FUNCSTORAGE]] [[#ARRTY]]
27+
28+
; CHECK-SPIRV: Function [[#VOID]] {{.*}} [[#FUNCTY]]
29+
; CHECK-SPIRV: Variable [[#ARRPTRTY]] [[#ARR]] [[#FUNCSTORAGE]]
30+
; CHECK-SPIRV: Bitcast [[#PTRTY]] [[#BITARR]] [[#ARR]]
31+
32+
; Generated LLVM is different, but equivalent as an array type is allocated.
33+
; CHECK-LLVM: define spir_func void @test_array_alloca()
34+
; CHECK-LLVM: %[[#ALLOC:]] = alloca [4 x i32], align 4
35+
; CHECK-LLVM: %{{.*}} = bitcast ptr %[[#ALLOC]] to ptr
36+
define dso_local void @test_array_alloca() #0 {
37+
%arr = alloca i32, i64 4, align 4
38+
ret void
39+
}
40+
41+
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
42+
43+
!opencl.enable.FP_CONTRACT = !{}
44+
!opencl.spir.version = !{!1}
45+
!opencl.ocl.version = !{!1}
46+
!opencl.used.extensions = !{!2}
47+
!opencl.used.optional.core.features = !{!3}
48+
!opencl.compiler.options = !{!2}
49+
50+
!1 = !{i32 1, i32 2}
51+
!2 = !{}
52+
!3 = !{}

0 commit comments

Comments
 (0)