Skip to content

Commit 417d637

Browse files
svenvhsys-ce-bb
authored andcommitted
Report unmet version requirement as error (#2372)
When restricting the allowed SPIR-V version using `--spirv-max-version`, some constructs may not be translatable due to being unavailable in older SPIR-V versions. Instead of asserting, report an error. It would be nice to also report the construct leading to the version conflict, but that information isn't readily available at this point. Original commit: KhronosGroup/SPIRV-LLVM-Translator@cebf8ecc9ec099b
1 parent b3ac271 commit 417d637

File tree

3 files changed

+67
-11
lines changed

3 files changed

+67
-11
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ _SPIRV_OP(InvalidInstruction, "Can't translate llvm instruction:\n")
2020
_SPIRV_OP(InvalidWordCount,
2121
"Can't encode instruction with word count greater than 65535:\n")
2222
_SPIRV_OP(Requires1_1, "Feature requires SPIR-V 1.1 or greater:")
23+
_SPIRV_OP(RequiresVersion, "Cannot fulfill SPIR-V version restriction:\n")
2324
_SPIRV_OP(RequiresExtension,
2425
"Feature requires the following SPIR-V extension:\n")
2526
_SPIRV_OP(InvalidMagicNumber,

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@
5858

5959
namespace SPIRV {
6060

61+
namespace {
62+
std::string to_string(uint32_t Version) {
63+
std::string Res(formatVersionNumber(Version));
64+
Res += " (" + std::to_string(Version) + ")";
65+
return Res;
66+
}
67+
68+
std::string to_string(VersionNumber Version) {
69+
return to_string(static_cast<uint32_t>(Version));
70+
}
71+
} // Anonymous namespace
72+
6173
SPIRVModule::SPIRVModule()
6274
: AutoAddCapability(true), ValidateCapability(false), IsValid(true) {}
6375

@@ -173,7 +185,16 @@ class SPIRVModuleImpl : public SPIRVModule {
173185
void insertEntryNoId(SPIRVEntry *Entry) override { EntryNoId.insert(Entry); }
174186

175187
void setSPIRVVersion(SPIRVWord Ver) override {
176-
assert(this->isAllowedToUseVersion(static_cast<VersionNumber>(Ver)));
188+
if (!this->isAllowedToUseVersion(static_cast<VersionNumber>(Ver))) {
189+
std::stringstream SS;
190+
SS << "SPIR-V version was restricted to at most "
191+
<< to_string(getMaximumAllowedSPIRVVersion())
192+
<< " but a construct from the input requires SPIR-V version "
193+
<< to_string(Ver) << " or above\n";
194+
getErrorLog().checkError(false, SPIRVEC_RequiresVersion, SS.str());
195+
setInvalid();
196+
return;
197+
}
177198
SPIRVVersion = Ver;
178199
}
179200

@@ -2098,16 +2119,6 @@ void SPIRVModuleImpl::addUnknownStructField(SPIRVTypeStruct *Struct, unsigned I,
20982119
UnknownStructFieldMap[Struct].push_back(std::make_pair(I, ID));
20992120
}
21002121

2101-
static std::string to_string(uint32_t Version) {
2102-
std::string Res(formatVersionNumber(Version));
2103-
Res += " (" + std::to_string(Version) + ")";
2104-
return Res;
2105-
}
2106-
2107-
static std::string to_string(VersionNumber Version) {
2108-
return to_string(static_cast<uint32_t>(Version));
2109-
}
2110-
21112122
std::istream &operator>>(std::istream &I, SPIRVModule &M) {
21122123
SPIRVDecoder Decoder(I, M);
21132124
SPIRVModuleImpl &MI = *static_cast<SPIRVModuleImpl *>(&M);
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; Check whether the translator reports an error for a module that uses a
2+
; construct only available in a SPIR-V version that's higher than what was
3+
; requested using --spirv-max-version.
4+
5+
; RUN: llvm-as < %s -o %t.bc
6+
; RUN: not llvm-spirv --spirv-max-version=1.0 %t.bc 2>&1 | FileCheck %s
7+
; RUN: not llvm-spirv --spirv-max-version=1.1 %t.bc 2>&1 | FileCheck %s
8+
; RUN: not llvm-spirv --spirv-max-version=1.2 %t.bc 2>&1 | FileCheck %s
9+
; RUN: llvm-spirv --spirv-max-version=1.3 %t.bc -o %t.spv
10+
; RUN: spirv-val %t.spv
11+
12+
; CHECK: RequiresVersion: Cannot fulfill SPIR-V version restriction:
13+
; CHECK-NEXT: SPIR-V version was restricted to at most 1.{{[012]}} ([[#]]) but a construct from the input requires SPIR-V version 1.3 (66304) or above
14+
15+
; ModuleID = 'foo.bc'
16+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
17+
target triple = "spir64"
18+
19+
; Function Attrs: convergent
20+
declare dso_local spir_func <4 x i32> @_Z16sub_group_balloti(i32) local_unnamed_addr #1
21+
22+
; Function Attrs: nounwind
23+
define dso_local spir_kernel void @testVersionReq() local_unnamed_addr #0 !kernel_arg_addr_space !3 !kernel_arg_access_qual !3 !kernel_arg_type !3 !kernel_arg_base_type !3 !kernel_arg_type_qual !3 {
24+
entry:
25+
%1 = tail call spir_func <4 x i32> @_Z16sub_group_balloti(i32 0) #1
26+
ret void
27+
}
28+
29+
attributes #0 = { nounwind }
30+
attributes #1 = { convergent }
31+
32+
!spirv.MemoryModel = !{!0}
33+
!opencl.enable.FP_CONTRACT = !{}
34+
!spirv.Source = !{!1}
35+
!opencl.spir.version = !{!0}
36+
!opencl.ocl.version = !{!0}
37+
!opencl.used.extensions = !{!2}
38+
!opencl.used.optional.core.features = !{!2}
39+
!spirv.Generator = !{!2}
40+
41+
!0 = !{i32 1, i32 2}
42+
!1 = !{i32 3, i32 102000}
43+
!2 = !{}
44+
!3 = !{}

0 commit comments

Comments
 (0)