diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index 48046f308c..803bf8aeac 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -814,6 +814,18 @@ SPIRVType *LLVMToSPIRVBase::transSPIRVOpaqueType(StringRef STName, SPIRVType *LLVMToSPIRVBase::transScavengedType(Value *V) { if (auto *F = dyn_cast(V)) { FunctionType *FnTy = Scavenger->getFunctionType(F); + // VarArg functions other than printf are not supported in SPIR-V. None of + // printf variants can actually reach this point because they're skipped in + // 'LLVMToSPIRVBase::translate()'. Specifically, + // 'isBuiltinTransToExtInst(&F)' returns true for printf and its variants, + // and so they are never added to 'Decls' and 'Defs'. Therefore, it's safe + // to only check here if we're dealing with a variadic function to report an + // error. To be on the safe side, an assertion is added to check printf + // never reaches this point. + assert(F->getName() != "printf"); + BM->getErrorLog().checkError(!FnTy->isVarArg(), + SPIRVEC_UnsupportedVarArgFunction); + SPIRVType *RT = transType(FnTy->getReturnType()); std::vector PT; for (Argument &Arg : F->args()) { diff --git a/lib/SPIRV/libSPIRV/SPIRVErrorEnum.h b/lib/SPIRV/libSPIRV/SPIRVErrorEnum.h index 6953d74751..9273f01c61 100644 --- a/lib/SPIRV/libSPIRV/SPIRVErrorEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVErrorEnum.h @@ -29,6 +29,8 @@ _SPIRV_OP(InvalidVersionNumber, "Invalid Version Number.") _SPIRV_OP(UnspecifiedMemoryModel, "Unspecified Memory Model.") _SPIRV_OP(RepeatedMemoryModel, "Expects a single OpMemoryModel instruction.") +_SPIRV_OP(UnsupportedVarArgFunction, + "Variadic functions other than 'printf' are not supported in SPIR-V.") /* This is the last error code to have a maximum valid value to compare to */ _SPIRV_OP(InternalMaxErrorCode, "Unknown error code") diff --git a/test/DebugInfo/Generic/2009-11-10-CurrentFn.ll b/test/DebugInfo/Generic/2009-11-10-CurrentFn.ll index 57c5b89a47..07f7eb71bb 100644 --- a/test/DebugInfo/Generic/2009-11-10-CurrentFn.ll +++ b/test/DebugInfo/Generic/2009-11-10-CurrentFn.ll @@ -9,11 +9,11 @@ target triple = "spir64-unknown-unknown" define void @bar(i32 %i) nounwind uwtable ssp !dbg !5 { entry: - tail call void (...) @foo() nounwind, !dbg !14 + tail call void @foo() nounwind, !dbg !14 ret void, !dbg !16 } -declare void @foo(...) +declare void @foo() declare void @llvm.dbg.value(metadata, metadata, metadata) nounwind readnone diff --git a/test/DebugInfo/Generic/multiline.ll b/test/DebugInfo/Generic/multiline.ll index 0a4ac8980d..4bfe97a606 100644 --- a/test/DebugInfo/Generic/multiline.ll +++ b/test/DebugInfo/Generic/multiline.ll @@ -49,16 +49,16 @@ target triple = "spir64-unknown-unknown" ; Function Attrs: nounwind uwtable define void @f2() #0 !dbg !4 { entry: - call void (...) @f1(), !dbg !11 - call void (...) @f1(), !dbg !12 - call void (...) @f1(), !dbg !13 - call void (...) @f1(), !dbg !14 - call void (...) @f1(), !dbg !15 - call void (...) @f1(), !dbg !16 + call void @f1(), !dbg !11 + call void @f1(), !dbg !12 + call void @f1(), !dbg !13 + call void @f1(), !dbg !14 + call void @f1(), !dbg !15 + call void @f1(), !dbg !16 ret void, !dbg !17 } -declare void @f1(...) #1 +declare void @f1() #1 attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/test/DebugInfo/Generic/varargs.ll b/test/DebugInfo/Generic/varargs.ll deleted file mode 100644 index 2da3a7d3b8..0000000000 --- a/test/DebugInfo/Generic/varargs.ll +++ /dev/null @@ -1,94 +0,0 @@ -; REQUIRES: object-emission -; -; RUN: llvm-as < %s -o %t.bc -; RUN: llvm-spirv %t.bc -o %t.spv -; RUN: llvm-spirv -r %t.spv -o - | llvm-dis -o %t.ll - -; RUN: llc -mtriple=%triple -O0 -filetype=obj %t.ll -o - | llvm-dwarfdump -v -debug-info - | FileCheck %s - -; Test debug info for variadic function arguments. -; Created from tools/clang/tests/CodeGenCXX/debug-info-varargs.cpp with the -; function pointer removed. -; -; The ... parameter of variadic should be emitted as -; DW_TAG_unspecified_parameters. -; -; Normal variadic function. -; void b(int c, ...); -; -; CHECK: DW_TAG_subprogram -; CHECK-NOT: DW_TAG -; CHECK: DW_AT_name {{.*}} "b" -; CHECK-NOT: DW_TAG -; CHECK: DW_TAG_formal_parameter -; CHECK-NOT: DW_TAG -; CHECK: DW_TAG_variable -; CHECK-NOT: DW_TAG -; CHECK: DW_TAG_unspecified_parameters -; -; CHECK: DW_TAG_subprogram -; CHECK-NOT: DW_TAG -; CHECK: DW_AT_name {{.*}} "a" -; CHECK-NOT: DW_TAG -; CHECK: DW_TAG_formal_parameter -; CHECK-NOT: DW_TAG -; CHECK: DW_TAG_formal_parameter -; CHECK-NOT: DW_TAG -; CHECK: DW_TAG_unspecified_parameters -; -; Variadic C++ member function. -; struct A { void a(int c, ...); } -; -; ModuleID = 'debug-info-varargs.cpp' -source_filename = "debug-info-varargs.cpp" -target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024" -target triple = "spir64-unknown-unknown" - -%struct.A = type { i8 } - -; Function Attrs: noinline nounwind optnone -define spir_func void @_Z1biz(i32 %c, ...) #0 !dbg !6 { -entry: - %c.addr = alloca i32, align 4 - %a = alloca %struct.A, align 1 - store i32 %c, ptr %c.addr, align 4 - call void @llvm.dbg.declare(metadata ptr %c.addr, metadata !11, metadata !DIExpression()), !dbg !12 - call void @llvm.dbg.declare(metadata ptr %a, metadata !13, metadata !DIExpression()), !dbg !20 - ret void, !dbg !21 -} - -; Function Attrs: nounwind readnone speculatable -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - -attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -attributes #1 = { nounwind readnone speculatable } - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!3, !4} -!opencl.used.extensions = !{!2} -!opencl.used.optional.core.features = !{!2} -!opencl.compiler.options = !{!2} -!llvm.ident = !{!5} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 8.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) -!1 = !DIFile(filename: "", directory: "/tmp") -!2 = !{} -!3 = !{i32 2, !"Debug Info Version", i32 3} -!4 = !{i32 1, !"wchar_size", i32 4} -!5 = !{!"clang version 8.0.0 "} -!6 = distinct !DISubprogram(name: "b", linkageName: "_Z1biz", scope: !7, file: !7, line: 11, type: !8, isLocal: false, isDefinition: true, scopeLine: 11, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2) -!7 = !DIFile(filename: "debug-info-varargs.cpp", directory: "/tmp") -!8 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !9) -!9 = !{null, !10, null} -!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!11 = !DILocalVariable(name: "c", arg: 1, scope: !6, file: !7, line: 11, type: !10) -!12 = !DILocation(line: 11, scope: !6) -!13 = !DILocalVariable(name: "a", scope: !6, file: !7, line: 23, type: !14) -!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !7, line: 3, size: 8, flags: DIFlagTypePassByValue, elements: !15, identifier: "_ZTS1A") -!15 = !{!16} -!16 = !DISubprogram(name: "a", linkageName: "_ZN1A1aEiz", scope: !14, file: !7, line: 5, type: !17, isLocal: false, isDefinition: false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false) -!17 = !DISubroutineType(types: !18) -!18 = !{null, !19, !10, null} -!19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) -!20 = !DILocation(line: 23, scope: !6) -!21 = !DILocation(line: 29, scope: !6) diff --git a/test/DebugInfo/X86/abstract_origin.ll b/test/DebugInfo/X86/abstract_origin.ll index 48e08bf471..446c1687dd 100644 --- a/test/DebugInfo/X86/abstract_origin.ll +++ b/test/DebugInfo/X86/abstract_origin.ll @@ -30,16 +30,16 @@ target triple = "spir64-unknown-unknown" ; Function Attrs: alwaysinline nounwind ssp uwtable define void @g() #0 !dbg !7 { entry: - tail call void (...) @f() #3, !dbg !10 + tail call void @f() #3, !dbg !10 ret void, !dbg !11 } -declare void @f(...) +declare void @f() ; Function Attrs: nounwind ssp uwtable define void @h() #2 !dbg !12 { entry: - tail call void (...) @f() #3, !dbg !13 + tail call void @f() #3, !dbg !13 ret void, !dbg !15 } diff --git a/test/DebugInfo/X86/dbg-value-const-byref.ll b/test/DebugInfo/X86/dbg-value-const-byref.ll index be0efb138c..1bd9dec935 100644 --- a/test/DebugInfo/X86/dbg-value-const-byref.ll +++ b/test/DebugInfo/X86/dbg-value-const-byref.ll @@ -51,7 +51,7 @@ entry: call void @llvm.dbg.value(metadata i32 3, metadata !10, metadata !DIExpression()), !dbg !15 %call = call i32 @f3(i32 3) #3, !dbg !16 call void @llvm.dbg.value(metadata i32 7, metadata !10, metadata !DIExpression()), !dbg !18 - %call1 = call i32 (...) @f1() #3, !dbg !19 + %call1 = call i32 @f1() #3, !dbg !19 call void @llvm.dbg.value(metadata i32 %call1, metadata !10, metadata !DIExpression()), !dbg !19 store i32 %call1, ptr %i, align 4, !dbg !19, !tbaa !20 call void @llvm.dbg.value(metadata ptr %i, metadata !10, metadata !DIExpression(DW_OP_deref)), !dbg !24 @@ -61,7 +61,7 @@ entry: declare i32 @f3(i32) -declare i32 @f1(...) +declare i32 @f1() declare void @f2(ptr) diff --git a/test/DebugInfo/X86/single-dbg_value.ll b/test/DebugInfo/X86/single-dbg_value.ll index 2f96f5a5b6..b44103d1ac 100644 --- a/test/DebugInfo/X86/single-dbg_value.ll +++ b/test/DebugInfo/X86/single-dbg_value.ll @@ -46,7 +46,7 @@ target triple = "spir64-unknown-unknown" define void @f() #0 !dbg !4 { entry: tail call void @h(i32 0) #2, !dbg !14 - %call = tail call i32 (...) @g() #2, !dbg !15 + %call = tail call i32 @g() #2, !dbg !15 tail call void @llvm.dbg.value(metadata i32 %call, metadata !8, metadata !16), !dbg !17 tail call void @h(i32 %call) #2, !dbg !18 ret void, !dbg !19 @@ -54,7 +54,7 @@ entry: declare void @h(i32) -declare i32 @g(...) +declare i32 @g() ; Function Attrs: nounwind readnone declare void @llvm.dbg.value(metadata, metadata, metadata) #1 diff --git a/test/negative/unsup_invoke_instr.ll b/test/negative/unsup_invoke_instr.ll index 45d44d4708..a08f8f3147 100644 --- a/test/negative/unsup_invoke_instr.ll +++ b/test/negative/unsup_invoke_instr.ll @@ -37,7 +37,7 @@ lpad: ret i32 0 } -declare dso_local i32 @__gxx_personality_v0(...) +declare dso_local i32 @__gxx_personality_v0() attributes #0 = { norecurse "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-module-id"="/localdisk2/icl/fadeeval/sycl_workspace/reproducer2/test.cpp" "uniform-work-group-size"="true" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/test/negative/unsupported_vararg_func.ll b/test/negative/unsupported_vararg_func.ll new file mode 100644 index 0000000000..783fe4d00c --- /dev/null +++ b/test/negative/unsupported_vararg_func.ll @@ -0,0 +1,17 @@ +; Check whether the translator reports an error for a +; function other than printf with variadic arguments. + +; RUN: llvm-as < %s -o %t.bc +; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1" +target triple = "spir64-unknown-unknown" + +; CHECK: UnsupportedVarArgFunction: Variadic functions other than 'printf' are not supported in SPIR-V. +; Function Attrs: convergent +declare spir_func void @for__issue_diagnostic(i32 noundef, i32 noundef, ...) local_unnamed_addr + +define i32 @foo() nounwind { + call spir_func void (i32, i32, ...) @for__issue_diagnostic(i32 noundef 41, i32 noundef 0) + ret i32 0 +}