blob: c9be77a405243f53932c5a7f1568d08d290a8fc1 [file] [edit]
; RUN: opt -mtriple=spirv64-unknown-unknown -S --passes=expand-variadics --expand-variadics-override=lowering %s | FileCheck %s
;
; An unmangled C `printf` declaration demangles to bare "printf" (no argument
; list). On SPIR-V it must be left as a variadic call so the backend can lower
; it to the OpenCL.std printf ExtInst with inline operands, instead of having
; its arguments packed into a vararg buffer here. A user-defined variadic
; function with a body is still expanded as usual.
@.str = private unnamed_addr addrspace(2) constant [4 x i8] c"%d\0A\00"
declare spir_func i32 @printf(ptr addrspace(2), ...)
; printf is left untouched: the call stays variadic and nothing is packed
; (CHECK-NEXT pins that ret immediately follows the call).
; CHECK-LABEL: define spir_kernel void @uses_printf(
; CHECK-NEXT: {{%.*}} = call spir_func i32 (ptr addrspace(2), ...) @printf(ptr addrspace(2) @.str, i32 42)
; CHECK-NEXT: ret void
define spir_kernel void @uses_printf() {
%r = call spir_func i32 (ptr addrspace(2), ...) @printf(ptr addrspace(2) @.str, i32 42)
ret void
}
; Control: an ordinary variadic function with a body is still expanded, i.e.
; its caller packs the arguments into a vararg buffer.
define spir_func i32 @my_variadic(...) {
ret i32 0
}
; CHECK-LABEL: define spir_kernel void @uses_my_variadic(
; CHECK: %vararg_buffer = alloca %uses_my_variadic.vararg
; CHECK: call spir_func i32 @my_variadic(ptr %vararg_buffer)
define spir_kernel void @uses_my_variadic() {
%r = call spir_func i32 (...) @my_variadic(i32 7)
ret void
}