| ; 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 |
| } |