Files
Nick Sarnie 6669fa5806 [SPIR-V] Don't lower builtin variadic functions (#188517)
In https://github.com/llvm/llvm-project/pull/178980 I tried to remove
the special handling for `printf`, but the fix was wrong, the pass
expects that `printf` abides by the variadic ABI (single buffer passed
in, args extracted by caller), which isn't how it works.

However the root issue is with any builtin, they are just replaced
directly with instructions, and the only place that could generate code
to honor the variadic ABI would bei in the SPIR-V backend, and it would
be pretty complicated for pretty much no benefit.

It's much simpler to teach the pass to skip certain functions, as we did
before, but this time skip all SPIR-V builtin.

---------

Signed-off-by: Nick Sarnie <nick.sarnie@intel.com>
2026-03-31 19:15:29 +00:00

41 lines
2.4 KiB
LLVM

; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
; CHECK: %[[#ExtImport:]] = OpExtInstImport "OpenCL.std"
; CHECK: %[[#Char:]] = OpTypeInt 8 0
; CHECK: %[[#CharPtr:]] = OpTypePointer UniformConstant %[[#Char]]
; CHECK: %[[#GV:]] = OpVariable %[[#]] UniformConstant %[[#]]
; CHECK: OpFunction
; CHECK: %[[#Arg1:]] = OpFunctionParameter
; CHECK: %[[#Arg2:]] = OpFunctionParameter
; CHECK: %[[#CastedGV:]] = OpBitcast %[[#CharPtr]] %[[#GV]]
; CHECK-NEXT: OpExtInst %[[#]] %[[#ExtImport]] printf %[[#CastedGV]] %[[#ArgConst:]]
; CHECK-NEXT: OpExtInst %[[#]] %[[#ExtImport]] printf %[[#CastedGV]] %[[#ArgConst]]
; CHECK-NEXT: OpExtInst %[[#]] %[[#ExtImport]] printf %[[#Arg1]] %[[#ArgConst]]
; CHECK-NEXT: OpExtInst %[[#]] %[[#ExtImport]] printf %[[#Arg1]] %[[#ArgConst]]
; CHECK-NEXT: %[[#CastedArg2:]] = OpBitcast %[[#CharPtr]] %[[#Arg2]]
; CHECK-NEXT: OpExtInst %[[#]] %[[#ExtImport]] printf %[[#CastedArg2]] %[[#ArgConst]]
; CHECK-NEXT: OpExtInst %[[#]] %[[#ExtImport]] printf %[[#CastedArg2]] %[[#ArgConst]]
; CHECK: OpFunctionEnd
%struct = type { [6 x i8] }
@FmtStr = internal addrspace(2) constant [6 x i8] c"c=%c\0A\00", align 1
define spir_kernel void @foo(ptr addrspace(2) %_arg_fmt1, ptr addrspace(2) byval(%struct) %_arg_fmt2) {
entry:
%r1 = tail call spir_func i32 (ptr addrspace(2), ...) @_Z6printfPU3AS2Kcz(ptr addrspace(2) @FmtStr, i8 signext 97)
%r2 = tail call spir_func i32 (ptr addrspace(2), ...) @_Z18__spirv_ocl_printfPU3AS2Kcz(ptr addrspace(2) @FmtStr, i8 signext 97)
%r3 = tail call spir_func i32 (ptr addrspace(2), ...) @_Z6printfPU3AS2Kcz(ptr addrspace(2) %_arg_fmt1, i8 signext 97)
%r4 = tail call spir_func i32 (ptr addrspace(2), ...) @_Z18__spirv_ocl_printfPU3AS2Kcz(ptr addrspace(2) %_arg_fmt1, i8 signext 97)
%r5 = tail call spir_func i32 (ptr addrspace(2), ...) @_Z6printfPU3AS2Kcz(ptr addrspace(2) %_arg_fmt2, i8 signext 97)
%r6 = tail call spir_func i32 (ptr addrspace(2), ...) @_Z18__spirv_ocl_printfPU3AS2Kcz(ptr addrspace(2) %_arg_fmt2, i8 signext 97)
ret void
}
declare dso_local spir_func i32 @_Z6printfPU3AS2Kcz(ptr addrspace(2), ...)
declare dso_local spir_func i32 @_Z18__spirv_ocl_printfPU3AS2Kcz(ptr addrspace(2), ...)