blob: 0b89b940286b16dedc24797b37479ff10b628cea [file]
; RUN: opt --mtriple=amdgcn-amd-amdhsa -S -passes=openmp-opt < %s | FileCheck %s
; When OpenMPOpt transforms a generic-mode kernel to SPMD mode, its generic-mode
; worker state machine is gone, so the parallel data-sharing wrapper (argument
; index 6 of __kmpc_parallel_60) is dead. OpenMPOpt nulls that argument so the
; otherwise-dead wrapper -- and any LDS it references -- can be eliminated instead
; of lingering as a non-kernel function that uses LDS (which the AMDGPU backend
; warns about). A kernel that stays in generic mode still needs its wrapper for
; the worker state machine, so it must be left untouched.
%struct.ident_t = type { i32, i32, i32, i32, ptr }
%struct.KernelEnvironmentTy = type { %struct.ConfigurationEnvironmentTy, ptr, ptr }
%struct.ConfigurationEnvironmentTy = type { i8, i8, i8, i32, i32, i32, i32, i32, i32 }
@0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
@1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, ptr @0 }, align 8
; The SPMD-amenable kernel is promoted: ExecMode 1 (GENERIC) -> 3 (GENERIC_SPMD).
; CHECK: @spmd_kernel_environment = {{.*}}ConfigurationEnvironmentTy { i8 0, i8 0, i8 3
@spmd_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 1, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr @1, ptr null }
; The kernel with an unguardable side effect stays generic: ExecMode remains 1.
; CHECK: @generic_kernel_environment = {{.*}}ConfigurationEnvironmentTy { i8 1, i8 0, i8 1
@generic_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 1, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr @1, ptr null }
define weak amdgpu_kernel void @spmd_kernel() "kernel" {
%init = call i32 @__kmpc_target_init(ptr @spmd_kernel_environment, ptr null)
call void @spmd_outlined(ptr null, ptr null)
call void @__kmpc_target_deinit()
ret void
}
define weak amdgpu_kernel void @generic_kernel() "kernel" {
%init = call i32 @__kmpc_target_init(ptr @generic_kernel_environment, ptr null)
call void @generic_outlined(ptr null, ptr null)
call void @__kmpc_target_deinit()
ret void
}
; SPMD kernel: the wrapper (arg 6) is nulled.
; CHECK-LABEL: define internal void @spmd_outlined(
; CHECK: call void @__kmpc_parallel_60(ptr @1, i32 0, i32 1, i32 -1, i32 -1, ptr @spmd_body, ptr null, ptr null, i64 0, i32 0)
define internal void @spmd_outlined(ptr %.global_tid., ptr %.bound_tid.) {
call void @__kmpc_parallel_60(ptr @1, i32 0, i32 1, i32 -1, i32 -1, ptr @spmd_body, ptr @spmd_body_wrapper, ptr null, i64 0, i32 0)
ret void
}
; Generic kernel: the wrapper (arg 6) is preserved.
; CHECK-LABEL: define internal void @generic_outlined(
; CHECK: call void @__kmpc_parallel_60(ptr @1, i32 0, i32 1, i32 -1, i32 -1, ptr @generic_body, ptr @generic_body_wrapper, ptr null, i64 0, i32 0)
define internal void @generic_outlined(ptr %.global_tid., ptr %.bound_tid.) {
call void @unknown()
call void @__kmpc_parallel_60(ptr @1, i32 0, i32 1, i32 -1, i32 -1, ptr @generic_body, ptr @generic_body_wrapper, ptr null, i64 0, i32 0)
ret void
}
define internal void @spmd_body(ptr %.global_tid., ptr %.bound_tid.) {
ret void
}
define internal void @spmd_body_wrapper(i16 zeroext %0, i32 %1) {
call void @spmd_body(ptr null, ptr null)
ret void
}
define internal void @generic_body(ptr %.global_tid., ptr %.bound_tid.) {
ret void
}
define internal void @generic_body_wrapper(i16 zeroext %0, i32 %1) {
call void @generic_body(ptr null, ptr null)
ret void
}
declare void @unknown()
declare i32 @__kmpc_target_init(ptr, ptr)
declare void @__kmpc_target_deinit()
declare void @__kmpc_parallel_60(ptr, i32, i32, i32, i32, ptr, ptr, ptr, i64, i32)
declare fastcc i32 @__kmpc_get_hardware_thread_id_in_block()
declare void @__kmpc_barrier_simple_spmd(ptr, i32)
!llvm.module.flags = !{!0, !1}
!0 = !{i32 7, !"openmp", i32 51}
!1 = !{i32 7, !"openmp-device", i32 51}