Skip to content

Commit

Permalink
Translate LLVM-IR zero-length arrays to 1-length arrays in SPIR-V (#2743
Browse files Browse the repository at this point in the history
)

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 attempts to introduce a workaround to this by lowering a zero-length array in LLVM-IR to a 1-length array in SPIR-V.
  • Loading branch information
lbushi25 authored Oct 8, 2024
1 parent 8a0638e commit 38db490
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 12 deletions.
13 changes: 4 additions & 9 deletions lib/SPIRV/SPIRVWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,24 +449,19 @@ SPIRVType *LLVMToSPIRVBase::transType(Type *T) {
if (T->isArrayTy()) {
// SPIR-V 1.3 s3.32.6: Length is the number of elements in the array.
// It must be at least 1.
if (T->getArrayNumElements() < 1) {
std::string Str;
llvm::raw_string_ostream OS(Str);
OS << *T;
SPIRVCK(T->getArrayNumElements() >= 1, InvalidArraySize, OS.str());
}
const auto ArraySize =
T->getArrayNumElements() ? T->getArrayNumElements() : 1;
Type *ElTy = T->getArrayElementType();
SPIRVType *TransType = BM->addArrayType(
transType(ElTy),
static_cast<SPIRVConstant *>(transValue(
ConstantInt::get(getSizetType(), T->getArrayNumElements(), false),
nullptr)));
ConstantInt::get(getSizetType(), ArraySize, false), nullptr)));
mapType(T, TransType);
if (ElTy->isPointerTy()) {
mapType(
ArrayType::get(TypedPointerType::get(Type::getInt8Ty(*Ctx),
ElTy->getPointerAddressSpace()),
T->getArrayNumElements()),
ArraySize),
TransType);
}
return TransType;
Expand Down
1 change: 0 additions & 1 deletion lib/SPIRV/libSPIRV/SPIRVErrorEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ _SPIRV_OP(InvalidMemoryModel, "Expects 0-3.")
_SPIRV_OP(InvalidFunctionControlMask, "")
_SPIRV_OP(InvalidBuiltinSetName, "Expects OpenCL.std.")
_SPIRV_OP(InvalidFunctionCall, "Unexpected llvm intrinsic:\n")
_SPIRV_OP(InvalidArraySize, "Array size must be at least 1:")
_SPIRV_OP(InvalidBitWidth, "Invalid bit width in input:")
_SPIRV_OP(InvalidModule, "Invalid SPIR-V module:")
_SPIRV_OP(InvalidLlvmModule, "Invalid LLVM module:")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
; RUN: llvm-as %s -o %t.bc
; RUN: not llvm-spirv %t.bc -o %t.spv 2>&1 | FileCheck %s
; RUN: llvm-spirv %t.bc -o %t.spv
; RUN: spirv-dis %t.spv | FileCheck %s

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

source_filename = "test.cl"
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"
Expand Down

0 comments on commit 38db490

Please sign in to comment.