Variadic function lowering for SPIR-V was initially added in https://github.com/llvm/llvm-project/pull/175076. However, I tried a full OpenMP offloading example that includes a vararg call and hit a few issues: 1) The OpenMP Deivce library function `ompx::printf` was incorrectly being considered a builtin `printf` function that would be handled specifically by the SPIR-V backend. The fix here is to remove the `printf` special handling. 2) We were getting an assert in ModuleVerifier saying the LLVM lifetime intrinsics were being called with an argument that was neither an `alloca` ptr or `poison`. The problem is the `alloca` was replaced with a SPIR-V intrinsic `alloca` in `SPIRVPrepareFunctions`, but the lifetime intrinsic added in `ExpandVariadics` was not lowered to the SPIR-V lifetime intrinsic since `ExpandVariadics` is run after `SPIRVPrepareFunctions`, The fix here is to just run `ExpandVariadics` first. 3) There were `va` intrinsics taking in a `addrspace(4)` pointer that were not being expanded. The fix here is to extend `ExpandVariadics` to support expanding `va` intrinsics with target-specific address spaces. --------- Signed-off-by: Nick Sarnie <nick.sarnie@intel.com> Co-authored-by: Joseph Huber <huberjn@outlook.com>
42 lines
2.0 KiB
LLVM
42 lines
2.0 KiB
LLVM
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers < %s 2>&1 | FileCheck %s
|
|
|
|
; CHECK: OpName [[MAIN:%.*]] "main"
|
|
; CHECK: [[MAIN]] = OpFunction
|
|
; CHECK-NOT: OPFunctionEnd
|
|
; CHECK: OpLifetimeStart
|
|
; CHECK-NOT: OPFunctionEnd
|
|
; CHECK: OpLifetimeStop
|
|
; CHECK: OpFunctionEnd
|
|
|
|
@.str = private unnamed_addr addrspace(1) constant [3 x i8] c"%s\00", align 1
|
|
@.str.1 = private unnamed_addr addrspace(1) constant [4 x i8] c"hey\00", align 1
|
|
|
|
declare spir_func noundef i32 @_Z7vprintfPKcz(ptr addrspace(4) noundef %0, ...) addrspace(9)
|
|
|
|
define spir_func noundef i32 @_ZN4ompx6printfEPKcz(ptr addrspace(4) noundef %Format, ...) addrspace(9) {
|
|
entry:
|
|
%retval = alloca i32, align 4
|
|
%Format.addr = alloca ptr addrspace(4), align 8
|
|
%vlist = alloca ptr addrspace(4), align 8
|
|
%retval.ascast = addrspacecast ptr %retval to ptr addrspace(4)
|
|
%Format.addr.ascast = addrspacecast ptr %Format.addr to ptr addrspace(4)
|
|
%vlist.ascast = addrspacecast ptr %vlist to ptr addrspace(4)
|
|
store ptr addrspace(4) %Format, ptr addrspace(4) %Format.addr.ascast, align 8
|
|
call addrspace(9) void @llvm.va_start.p4(ptr addrspace(4) %vlist.ascast)
|
|
%0 = load ptr addrspace(4), ptr addrspace(4) %Format.addr.ascast, align 8
|
|
%1 = load ptr addrspace(4), ptr addrspace(4) %vlist.ascast, align 8
|
|
%call = call spir_func noundef addrspace(9) i32 (ptr addrspace(4), ...) @_Z7vprintfPKcz(ptr addrspace(4) noundef %0, ptr addrspace(4) noundef %1)
|
|
ret i32 %call
|
|
}
|
|
|
|
declare void @llvm.va_start.p4(ptr addrspace(4)) addrspace(9)
|
|
|
|
define noundef i32 @main() addrspace(9) {
|
|
entry:
|
|
%retval = alloca i32, align 4
|
|
%retval.ascast = addrspacecast ptr %retval to ptr addrspace(4)
|
|
store i32 0, ptr addrspace(4) %retval.ascast, align 4
|
|
%call = call spir_func noundef addrspace(9) i32 (ptr addrspace(4), ...) @_ZN4ompx6printfEPKcz(ptr addrspace(4) noundef addrspacecast (ptr addrspace(1) @.str to ptr addrspace(4)), ptr addrspace(4) noundef addrspacecast (ptr addrspace(1) @.str.1 to ptr addrspace(4))) #5
|
|
ret i32 0
|
|
}
|