1*0ce6255aSAlex Voicu; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=hipstdpar-select-accelerator-code \ 2*0ce6255aSAlex Voicu; RUN: %s | FileCheck %s 3*0ce6255aSAlex Voicu 4*0ce6255aSAlex Voicu$_ZNK8CallableclEPi = comdat any 5*0ce6255aSAlex Voicu$_ZNK8CallableclEPf = comdat any 6*0ce6255aSAlex Voicu$_ZNK8Callable6mem_fnEPKi = comdat any 7*0ce6255aSAlex Voicu$_ZN8Callable13static_mem_fnEPKi = comdat any 8*0ce6255aSAlex Voicu; CHECK-NOT: $_ZNK8Callable37another_mem_fn_which_will_get_removedEPKf 9*0ce6255aSAlex Voicu$_ZNK8Callable37another_mem_fn_which_will_get_removedEPKf = comdat any 10*0ce6255aSAlex Voicu; CHECK-NOT: $_ZN8Callable44another_static_mem_fn_which_will_get_removedEPKf 11*0ce6255aSAlex Voicu$_ZN8Callable44another_static_mem_fn_which_will_get_removedEPKf = comdat any 12*0ce6255aSAlex Voicu 13*0ce6255aSAlex Voicu%struct.Callable = type { [64 x i8] } 14*0ce6255aSAlex Voicu 15*0ce6255aSAlex Voicu; CHECK-NOT: @should_be_removed 16*0ce6255aSAlex Voicu@llvm.compiler.used = appending addrspace(1) global [1 x ptr] [ptr @should_be_removed], section "llvm.metadata" 17*0ce6255aSAlex Voicu 18*0ce6255aSAlex Voicudefine void @should_be_removed(ptr %p) { 19*0ce6255aSAlex Voicu ret void 20*0ce6255aSAlex Voicu} 21*0ce6255aSAlex Voicu 22*0ce6255aSAlex Voicudeclare void @llvm.trap() 23*0ce6255aSAlex Voicu 24*0ce6255aSAlex Voicu; CHECK: define {{.*}} @called_via_chain 25*0ce6255aSAlex Voicudefine void @called_via_chain(ptr %p) { 26*0ce6255aSAlex Voicu entry: 27*0ce6255aSAlex Voicu %tobool.not = icmp eq ptr %p, null 28*0ce6255aSAlex Voicu br i1 %tobool.not, label %if.then, label %if.end 29*0ce6255aSAlex Voicu 30*0ce6255aSAlex Voicu if.then: 31*0ce6255aSAlex Voicu tail call void @llvm.trap() 32*0ce6255aSAlex Voicu unreachable 33*0ce6255aSAlex Voicu 34*0ce6255aSAlex Voicu if.end: 35*0ce6255aSAlex Voicu ret void 36*0ce6255aSAlex Voicu} 37*0ce6255aSAlex Voicu 38*0ce6255aSAlex Voicu; CHECK: define {{.*}} @directly_called 39*0ce6255aSAlex Voicudefine void @directly_called(ptr %p) { 40*0ce6255aSAlex Voicu tail call void @called_via_chain(ptr %p) 41*0ce6255aSAlex Voicu ret void 42*0ce6255aSAlex Voicu} 43*0ce6255aSAlex Voicu 44*0ce6255aSAlex Voicu; CHECK: define {{.*}} amdgpu_kernel {{.*}} @accelerator_execution_root 45*0ce6255aSAlex Voicudefine hidden amdgpu_kernel void @accelerator_execution_root(ptr %p) { 46*0ce6255aSAlex Voicu tail call void @directly_called(ptr %p) 47*0ce6255aSAlex Voicu ret void 48*0ce6255aSAlex Voicu} 49*0ce6255aSAlex Voicu 50*0ce6255aSAlex Voicu; CHECK-NOT: @defined_elsewhere_should_be_removed 51*0ce6255aSAlex Voicudeclare void @defined_elsewhere_should_be_removed(ptr) 52*0ce6255aSAlex Voicu 53*0ce6255aSAlex Voicu; CHECK: declare {{.*}} @defined_elsewhere_directly_called 54*0ce6255aSAlex Voicudeclare void @defined_elsewhere_directly_called(ptr) 55*0ce6255aSAlex Voicu 56*0ce6255aSAlex Voicu; CHECK: define {{.*}} amdgpu_kernel {{.*}} @another_accelerator_execution_root 57*0ce6255aSAlex Voicudefine hidden amdgpu_kernel void @another_accelerator_execution_root(ptr %p) { 58*0ce6255aSAlex Voicu tail call void @defined_elsewhere_directly_called(ptr %p) 59*0ce6255aSAlex Voicu ret void 60*0ce6255aSAlex Voicu} 61*0ce6255aSAlex Voicu 62*0ce6255aSAlex Voicu; Also test passing a callable object (functor / lambda) to a kernel, which is 63*0ce6255aSAlex Voicu; the common pattern for customising algorithms. 64*0ce6255aSAlex Voicu 65*0ce6255aSAlex Voicu; CHECK: define {{.*}} amdgpu_kernel {{.*}} @_Z22accelerator_execution_root_taking_callablePi8Callable 66*0ce6255aSAlex Voicudefine hidden amdgpu_kernel void @_Z22accelerator_execution_root_taking_callablePi8Callable(ptr noundef %p, ptr addrspace(4) nocapture readonly byref(%struct.Callable) align 8 %callable) { 67*0ce6255aSAlex Voicu %callable_in_generic = addrspacecast ptr addrspace(4) %callable to ptr 68*0ce6255aSAlex Voicu call void @_ZNK8CallableclEPi(ptr noundef nonnull align 1 dereferenceable(64) %callable_in_generic, ptr noundef %p) 69*0ce6255aSAlex Voicu 70*0ce6255aSAlex Voicu ret void 71*0ce6255aSAlex Voicu} 72*0ce6255aSAlex Voicu 73*0ce6255aSAlex Voicu; CHECK: define {{.*}} @_ZNK8CallableclEPi 74*0ce6255aSAlex Voicudefine linkonce_odr dso_local void @_ZNK8CallableclEPi(ptr noundef nonnull align 1 dereferenceable(64) %this, ptr noundef %p) { 75*0ce6255aSAlex Voicu call void @_ZNK8Callable6mem_fnEPKi(ptr noundef nonnull align 1 dereferenceable(1) %this, ptr noundef %p) 76*0ce6255aSAlex Voicu 77*0ce6255aSAlex Voicu ret void 78*0ce6255aSAlex Voicu} 79*0ce6255aSAlex Voicu 80*0ce6255aSAlex Voicu; CHECK: define {{.*}} @_ZNK8Callable6mem_fnEPKi 81*0ce6255aSAlex Voicudefine linkonce_odr dso_local void @_ZNK8Callable6mem_fnEPKi(ptr noundef nonnull align 1 dereferenceable(1) %this, ptr noundef %p) { 82*0ce6255aSAlex Voicu call void @_ZN8Callable13static_mem_fnEPKi(ptr noundef %p) 83*0ce6255aSAlex Voicu 84*0ce6255aSAlex Voicu ret void 85*0ce6255aSAlex Voicu} 86*0ce6255aSAlex Voicu 87*0ce6255aSAlex Voicu; CHECK: define {{.*}} @_ZN8Callable13static_mem_fnEPKi 88*0ce6255aSAlex Voicudefine linkonce_odr dso_local void @_ZN8Callable13static_mem_fnEPKi(ptr noundef %p) { 89*0ce6255aSAlex Voicu ret void 90*0ce6255aSAlex Voicu} 91*0ce6255aSAlex Voicu 92*0ce6255aSAlex Voicu; CHECK-NOT: define {{.*}} @_Z26non_kernel_taking_callablePf8Callable 93*0ce6255aSAlex Voicudefine dso_local void @_Z26non_kernel_taking_callablePf8Callable(ptr noundef %p, ptr noundef byval(%struct.Callable) align 8 %callable) { 94*0ce6255aSAlex Voicu call void @_ZNK8CallableclEPf(ptr noundef nonnull align 1 dereferenceable(64) %callable, ptr noundef %p) 95*0ce6255aSAlex Voicu 96*0ce6255aSAlex Voicu ret void 97*0ce6255aSAlex Voicu} 98*0ce6255aSAlex Voicu 99*0ce6255aSAlex Voicu; CHECK-NOT: define {{.*}} @_ZNK8CallableclEPf 100*0ce6255aSAlex Voicudefine linkonce_odr dso_local void @_ZNK8CallableclEPf(ptr noundef nonnull align 1 dereferenceable(64) %this, ptr noundef %p) { 101*0ce6255aSAlex Voicu call void @_ZNK8Callable37another_mem_fn_which_will_get_removedEPKf(ptr noundef nonnull align 1 dereferenceable(64) %this, ptr noundef %p) 102*0ce6255aSAlex Voicu 103*0ce6255aSAlex Voicu ret void 104*0ce6255aSAlex Voicu} 105*0ce6255aSAlex Voicu 106*0ce6255aSAlex Voicu; CHECK-NOT: @_ZNK8Callable37another_mem_fn_which_will_get_removedEPKf 107*0ce6255aSAlex Voicudefine linkonce_odr dso_local void @_ZNK8Callable37another_mem_fn_which_will_get_removedEPKf(ptr noundef nonnull align 1 dereferenceable(64) %this, ptr noundef %p) { 108*0ce6255aSAlex Voicu call void @_ZN8Callable44another_static_mem_fn_which_will_get_removedEPKf(ptr noundef %p) 109*0ce6255aSAlex Voicu 110*0ce6255aSAlex Voicu ret void 111*0ce6255aSAlex Voicu} 112*0ce6255aSAlex Voicu 113*0ce6255aSAlex Voicu; CHECK-NOT: @_ZN8Callable44another_static_mem_fn_which_will_get_removedEPKf 114*0ce6255aSAlex Voicudefine linkonce_odr dso_local void @_ZN8Callable44another_static_mem_fn_which_will_get_removedEPKf(ptr noundef %p) { 115*0ce6255aSAlex Voicu ret void 116*0ce6255aSAlex Voicu}