Skip to content

Commit 7997c3c

Browse files
authored
[SPIRV] Lower LLVM IR Type of array of zero length to spirv type of array of length 1 (#15663)
Cherry-pick of KhronosGroup/SPIRV-LLVM-Translator#2743. The LLVM-IR type of zero-length array does not seem to have a mapping into SPIR-V type, rather it outputs an error since the obvious choice of zero-length array is not valid in SPIR-V. This, for example, prohibits us from using unbounded arrays in SYCL device kernels because they are typically represented in LLVM-IR through zero-length arrays. This PR introduces a workaround to this by lowering a zero-length array in LLVM-IR to a 1-length array in SPIR-V.
1 parent 6ba05b7 commit 7997c3c

File tree

3 files changed

+9
-12
lines changed

3 files changed

+9
-12
lines changed

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -453,24 +453,19 @@ SPIRVType *LLVMToSPIRVBase::transType(Type *T) {
453453
if (T->isArrayTy()) {
454454
// SPIR-V 1.3 s3.32.6: Length is the number of elements in the array.
455455
// It must be at least 1.
456-
if (T->getArrayNumElements() < 1) {
457-
std::string Str;
458-
llvm::raw_string_ostream OS(Str);
459-
OS << *T;
460-
SPIRVCK(T->getArrayNumElements() >= 1, InvalidArraySize, OS.str());
461-
}
456+
const auto ArraySize =
457+
T->getArrayNumElements() ? T->getArrayNumElements() : 1;
462458
Type *ElTy = T->getArrayElementType();
463459
SPIRVType *TransType = BM->addArrayType(
464460
transType(ElTy),
465461
static_cast<SPIRVConstant *>(transValue(
466-
ConstantInt::get(getSizetType(), T->getArrayNumElements(), false),
467-
nullptr)));
462+
ConstantInt::get(getSizetType(), ArraySize, false), nullptr)));
468463
mapType(T, TransType);
469464
if (ElTy->isPointerTy()) {
470465
mapType(
471466
ArrayType::get(TypedPointerType::get(Type::getInt8Ty(*Ctx),
472467
ElTy->getPointerAddressSpace()),
473-
T->getArrayNumElements()),
468+
ArraySize),
474469
TransType);
475470
}
476471
return TransType;

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVErrorEnum.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ _SPIRV_OP(InvalidMemoryModel, "Expects 0-3.")
1010
_SPIRV_OP(InvalidFunctionControlMask, "")
1111
_SPIRV_OP(InvalidBuiltinSetName, "Expects OpenCL.std.")
1212
_SPIRV_OP(InvalidFunctionCall, "Unexpected llvm intrinsic:\n")
13-
_SPIRV_OP(InvalidArraySize, "Array size must be at least 1:")
1413
_SPIRV_OP(InvalidBitWidth, "Invalid bit width in input:")
1514
_SPIRV_OP(InvalidModule, "Invalid SPIR-V module:")
1615
_SPIRV_OP(InvalidLlvmModule, "Invalid LLVM module:")

llvm-spirv/test/negative/zero-length-array.ll renamed to llvm-spirv/test/zero-length-array.ll

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
; REQUIRES: spirv-dis
12
; RUN: llvm-as %s -o %t.bc
2-
; RUN: not llvm-spirv %t.bc -o %t.spv 2>&1 | FileCheck %s
3+
; RUN: llvm-spirv %t.bc -o %t.spv
4+
; RUN: spirv-dis %t.spv | FileCheck %s
35

4-
; CHECK: InvalidArraySize: Array size must be at least 1: [0 x i32]
6+
; CHECK: [[REGISTER:%[a-zA-Z0-9_]+]] = OpConstant %uint 1
7+
; CHECK: OpTypeArray %uint [[REGISTER]]
58

69
source_filename = "test.cl"
710
target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"

0 commit comments

Comments
 (0)