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