Skip to content

Commit 031d998

Browse files
authored
[SPIRV] Error in backend for vararg functions (#169111)
SPIR-V doesn't support variadic functions, though we make an exception for `printf`. If we don't error, we generate invalid SPIR-V because the backend has no idea how to codegen vararg functions as it is not described in the spec. We get asm like this: ``` %27 = OpFunction %6 None %7 %28 = OpFunctionParameter %4 ; -- End function ``` The above asm is totally invalid, there's no `OpFunctionEnd` and it causes crashes in downstream tools like `spirv-as` and `spirv-link`. We already have many `printf` tests locking down that this doesn't break `printf`, it was already handled elsewhere at the time the error check runs. Note the SPIR-V Translator does the same thing, see [here](KhronosGroup/SPIRV-LLVM-Translator#2703). --------- Signed-off-by: Nick Sarnie <[email protected]>
1 parent b3b83ac commit 031d998

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "SPIRVUtils.h"
2222
#include "llvm/ADT/APInt.h"
2323
#include "llvm/IR/Constants.h"
24+
#include "llvm/IR/DiagnosticInfo.h"
2425
#include "llvm/IR/IntrinsicInst.h"
2526
#include "llvm/IR/Intrinsics.h"
2627
#include "llvm/IR/IntrinsicsSPIRV.h"
@@ -970,8 +971,15 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeForwardPointer(
970971
}
971972

972973
SPIRVType *SPIRVGlobalRegistry::getOpTypeFunction(
973-
SPIRVType *RetType, const SmallVectorImpl<SPIRVType *> &ArgTypes,
974+
const FunctionType *Ty, SPIRVType *RetType,
975+
const SmallVectorImpl<SPIRVType *> &ArgTypes,
974976
MachineIRBuilder &MIRBuilder) {
977+
if (Ty->isVarArg()) {
978+
Function &Fn = MIRBuilder.getMF().getFunction();
979+
Ty->getContext().diagnose(DiagnosticInfoUnsupported(
980+
Fn, "SPIR-V does not support variadic functions",
981+
MIRBuilder.getDebugLoc()));
982+
}
975983
return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
976984
auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeFunction)
977985
.addDef(createTypeVReg(MIRBuilder))
@@ -988,7 +996,8 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeFunctionWithArgs(
988996
MachineIRBuilder &MIRBuilder) {
989997
if (const MachineInstr *MI = findMI(Ty, false, &MIRBuilder.getMF()))
990998
return MI;
991-
const MachineInstr *NewMI = getOpTypeFunction(RetType, ArgTypes, MIRBuilder);
999+
const MachineInstr *NewMI =
1000+
getOpTypeFunction(cast<FunctionType>(Ty), RetType, ArgTypes, MIRBuilder);
9921001
add(Ty, false, NewMI);
9931002
return finishCreatingSPIRVType(Ty, NewMI);
9941003
}
@@ -1097,7 +1106,7 @@ SPIRVType *SPIRVGlobalRegistry::createSPIRVType(
10971106
for (const auto &ParamTy : FType->params())
10981107
ParamTypes.push_back(findSPIRVType(ParamTy, MIRBuilder, AccQual,
10991108
ExplicitLayoutRequired, EmitIR));
1100-
return getOpTypeFunction(RetTy, ParamTypes, MIRBuilder);
1109+
return getOpTypeFunction(FType, RetTy, ParamTypes, MIRBuilder);
11011110
}
11021111

11031112
unsigned AddrSpace = typeToAddressSpace(Ty);

llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ class SPIRVGlobalRegistry : public SPIRVIRMapping {
464464
SPIRVType *getOpTypeForwardPointer(SPIRV::StorageClass::StorageClass SC,
465465
MachineIRBuilder &MIRBuilder);
466466

467-
SPIRVType *getOpTypeFunction(SPIRVType *RetType,
467+
SPIRVType *getOpTypeFunction(const FunctionType *Ty, SPIRVType *RetType,
468468
const SmallVectorImpl<SPIRVType *> &ArgTypes,
469469
MachineIRBuilder &MIRBuilder);
470470

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
; RUN: not llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers < %s 2>&1 | FileCheck %s
2+
3+
define void @bar() {
4+
entry:
5+
call spir_func void (i32, ...) @_Z3fooiz(i32 5, i32 3)
6+
ret void
7+
}
8+
9+
; CHECK:error: {{.*}} in function bar void (): SPIR-V does not support variadic functions
10+
declare spir_func void @_Z3fooiz(i32, ...)

0 commit comments

Comments
 (0)