diff --git a/llvm/include/llvm/IR/CallingConv.h b/llvm/include/llvm/IR/CallingConv.h index 7897aabb6c1a..d68491eb5535 100644 --- a/llvm/include/llvm/IR/CallingConv.h +++ b/llvm/include/llvm/IR/CallingConv.h @@ -290,6 +290,27 @@ namespace CallingConv { } // end namespace CallingConv +/// \return true if the calling convention allows the function to be called +/// directly or indirectly via a call-like instruction. +constexpr bool isCallableCC(CallingConv::ID CC) { + switch (CC) { + case CallingConv::AMDGPU_CS_Chain: + case CallingConv::AMDGPU_CS_ChainPreserve: + case CallingConv::AMDGPU_CS: + case CallingConv::AMDGPU_ES: + case CallingConv::AMDGPU_GS: + case CallingConv::AMDGPU_HS: + case CallingConv::AMDGPU_KERNEL: + case CallingConv::AMDGPU_LS: + case CallingConv::AMDGPU_PS: + case CallingConv::AMDGPU_VS: + case CallingConv::SPIR_KERNEL: + return false; + default: + return true; + } +} + } // end namespace llvm #endif // LLVM_IR_CALLINGCONV_H diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 7d32bf29ae10..e3f6c1ad5a65 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -3596,14 +3596,9 @@ void Verifier::visitCallBase(CallBase &Call) { Check(Callee->getValueType() == FTy, "Intrinsic called with incompatible signature", Call); - // Disallow calls to functions with the amdgpu_cs_chain[_preserve] calling - // convention. - auto CC = Call.getCallingConv(); - Check(CC != CallingConv::AMDGPU_CS_Chain && - CC != CallingConv::AMDGPU_CS_ChainPreserve, - "Direct calls to amdgpu_cs_chain/amdgpu_cs_chain_preserve functions " - "not allowed. Please use the @llvm.amdgpu.cs.chain intrinsic instead.", - Call); + // Verify if the calling convention of the callee is callable. + Check(isCallableCC(Call.getCallingConv()), + "calling convention does not permit calls", Call); // Disallow passing/returning values with alignment higher than we can // represent. diff --git a/llvm/test/Bitcode/calling-conventions.3.2.ll b/llvm/test/Bitcode/calling-conventions.3.2.ll index 9221ef30c8dc..678886777ad4 100644 --- a/llvm/test/Bitcode/calling-conventions.3.2.ll +++ b/llvm/test/Bitcode/calling-conventions.3.2.ll @@ -80,12 +80,6 @@ define void @call_cc10 () { ret void } -define void @call_spir_kernel() { -; CHECK: call spir_kernel void @spir_kernel - call spir_kernel void @spir_kernel() - ret void -} - define void @call_spir_func() { ; CHECK: call spir_func void @spir_func call spir_func void @spir_func() diff --git a/llvm/test/Bitcode/calling-conventions.3.2.ll.bc b/llvm/test/Bitcode/calling-conventions.3.2.ll.bc index b7ac769a82b3..19cdf69be1c2 100644 Binary files a/llvm/test/Bitcode/calling-conventions.3.2.ll.bc and b/llvm/test/Bitcode/calling-conventions.3.2.ll.bc differ diff --git a/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll b/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll index fc61aa5f981d..a3d6c3b72952 100644 --- a/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll +++ b/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll @@ -849,21 +849,6 @@ define amdgpu_kernel void @calls_intrin_ascast_cc_kernel(ptr addrspace(3) %ptr) ret void } -define amdgpu_kernel void @call_calls_intrin_ascast_cc_kernel(ptr addrspace(3) %ptr) { -; GFX9-LABEL: define amdgpu_kernel void @call_calls_intrin_ascast_cc_kernel( -; GFX9-SAME: ptr addrspace(3) [[PTR:%.*]]) #[[ATTR1]] { -; GFX9-NEXT: call void @calls_intrin_ascast_cc_kernel(ptr addrspace(3) [[PTR]]) -; GFX9-NEXT: ret void -; -; GFX10-LABEL: define amdgpu_kernel void @call_calls_intrin_ascast_cc_kernel( -; GFX10-SAME: ptr addrspace(3) [[PTR:%.*]]) #[[ATTR1]] { -; GFX10-NEXT: call void @calls_intrin_ascast_cc_kernel(ptr addrspace(3) [[PTR]]) -; GFX10-NEXT: ret void -; - call void @calls_intrin_ascast_cc_kernel(ptr addrspace(3) %ptr) - ret void -} - define amdgpu_kernel void @with_inline_asm() { ; GFX9-LABEL: define amdgpu_kernel void @with_inline_asm( ; GFX9-SAME: ) #[[ATTR3]] { diff --git a/llvm/test/CodeGen/AMDGPU/call-to-kernel-undefined.ll b/llvm/test/CodeGen/AMDGPU/call-to-kernel-undefined.ll deleted file mode 100644 index da7385475088..000000000000 --- a/llvm/test/CodeGen/AMDGPU/call-to-kernel-undefined.ll +++ /dev/null @@ -1,20 +0,0 @@ -; RUN: not --crash llc -mtriple=amdgcn -mcpu=tahiti -verify-machineinstrs -o /dev/null %s 2>&1 | FileCheck %s - -; FIXME: It should be invalid IR to have a call to a kernel, but this -; is currently relied on, but should be eliminated before codegen. -define amdgpu_kernel void @callee_kernel(ptr addrspace(1) %out) #0 { -entry: - store volatile i32 0, ptr addrspace(1) %out - ret void -} - -; Make sure there's no crash when the callsite calling convention -; doesn't match. -; CHECK: LLVM ERROR: invalid call to entry function -define amdgpu_kernel void @caller_kernel(ptr addrspace(1) %out) #0 { -entry: - call void @callee_kernel(ptr addrspace(1) %out) - ret void -} - -attributes #0 = { nounwind noinline } diff --git a/llvm/test/CodeGen/AMDGPU/call-to-kernel.ll b/llvm/test/CodeGen/AMDGPU/call-to-kernel.ll deleted file mode 100644 index 1f4f6471fcdb..000000000000 --- a/llvm/test/CodeGen/AMDGPU/call-to-kernel.ll +++ /dev/null @@ -1,18 +0,0 @@ -; RUN: not --crash llc -mtriple=amdgcn -mcpu=tahiti -verify-machineinstrs -o /dev/null %s 2>&1 | FileCheck %s - -; FIXME: It should be invalid IR to have a call to a kernel, but this -; is currently relied on, but should be eliminated before codegen. -define amdgpu_kernel void @callee_kernel(ptr addrspace(1) %out) #0 { -entry: - store volatile i32 0, ptr addrspace(1) %out - ret void -} - -; CHECK: LLVM ERROR: Unsupported calling convention for call -define amdgpu_kernel void @caller_kernel(ptr addrspace(1) %out) #0 { -entry: - call amdgpu_kernel void @callee_kernel(ptr addrspace(1) %out) - ret void -} - -attributes #0 = { nounwind noinline } diff --git a/llvm/test/Other/spir_cc.ll b/llvm/test/Other/spir_cc.ll index ffc02945de4d..33cf0bbf86a1 100644 --- a/llvm/test/Other/spir_cc.ll +++ b/llvm/test/Other/spir_cc.ll @@ -8,6 +8,5 @@ define spir_func void @foo() { define spir_kernel void @bar() { call spir_func void @foo( ) - call spir_kernel void @bar( ) ret void } diff --git a/llvm/test/Verifier/amdgpu-cc.ll b/llvm/test/Verifier/amdgpu-cc.ll index ce48d1fdae3e..aec09771d2e4 100644 --- a/llvm/test/Verifier/amdgpu-cc.ll +++ b/llvm/test/Verifier/amdgpu-cc.ll @@ -217,26 +217,3 @@ define amdgpu_cs_chain_preserve void @preallocated_cc_amdgpu_cs_chain_preserve(p define amdgpu_cs_chain_preserve void @inalloca_cc_amdgpu_cs_chain_preserve(ptr inalloca(i32) %ptr) { ret void } - -declare amdgpu_cs_chain void @amdgpu_cs_chain_call_target() -declare amdgpu_cs_chain_preserve void @amdgpu_cs_chain_preserve_call_target() - -define amdgpu_cs_chain void @cant_call_amdgpu_cs_chain_functions(ptr %f) { - ; CHECK: Direct calls to amdgpu_cs_chain/amdgpu_cs_chain_preserve functions not allowed. Please use the @llvm.amdgpu.cs.chain intrinsic instead. - ; CHECK-NEXT: call amdgpu_cs_chain - call amdgpu_cs_chain void @amdgpu_cs_chain_call_target() - - ; CHECK: Direct calls to amdgpu_cs_chain/amdgpu_cs_chain_preserve functions not allowed. Please use the @llvm.amdgpu.cs.chain intrinsic instead. - ; CHECK-NEXT: call amdgpu_cs_chain_preserve - call amdgpu_cs_chain_preserve void @amdgpu_cs_chain_preserve_call_target() - - ; CHECK: Direct calls to amdgpu_cs_chain/amdgpu_cs_chain_preserve functions not allowed. Please use the @llvm.amdgpu.cs.chain intrinsic instead. - ; CHECK-NEXT: call amdgpu_cs_chain - call amdgpu_cs_chain void %f() - - ; CHECK: Direct calls to amdgpu_cs_chain/amdgpu_cs_chain_preserve functions not allowed. Please use the @llvm.amdgpu.cs.chain intrinsic instead. - ; CHECK-NEXT: call amdgpu_cs_chain - call amdgpu_cs_chain_preserve void %f() - - ret void -} diff --git a/llvm/test/Verifier/call-to-non-callable-functions.ll b/llvm/test/Verifier/call-to-non-callable-functions.ll new file mode 100644 index 000000000000..f33682c0dbe2 --- /dev/null +++ b/llvm/test/Verifier/call-to-non-callable-functions.ll @@ -0,0 +1,529 @@ +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s + +declare amdgpu_cs_chain void @callee_amdgpu_cs_chain() + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_cs_chain void @callee_amdgpu_cs_chain() +define amdgpu_cs_chain void @call_caller_amdgpu_cs_chain() { +entry: + call amdgpu_cs_chain void @callee_amdgpu_cs_chain() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_cs_chain void %func() +define amdgpu_cs_chain void @indirect_call_caller_amdgpu_cs_chain(ptr %func) { +entry: + call amdgpu_cs_chain void %func() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: invoke amdgpu_cs_chain void @callee_amdgpu_cs_chain() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_cs_chain void @invoke_caller_amdgpu_cs_chain() { +entry: + invoke amdgpu_cs_chain void @callee_amdgpu_cs_chain() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK: invoke amdgpu_cs_chain void %func() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_cs_chain void @indirect_invoke_caller_amdgpu_cs_chain(ptr %func) { +entry: + invoke amdgpu_cs_chain void %func() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +declare amdgpu_cs_chain_preserve void @callee_amdgpu_cs_chain_preserve() + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_cs_chain_preserve void @callee_amdgpu_cs_chain_preserve() +define amdgpu_cs_chain_preserve void @call_caller_amdgpu_cs_chain_preserve() { +entry: + call amdgpu_cs_chain_preserve void @callee_amdgpu_cs_chain_preserve() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_cs_chain_preserve void %func() +define amdgpu_cs_chain_preserve void @indirect_call_caller_amdgpu_cs_chain_preserve(ptr %func) { +entry: + call amdgpu_cs_chain_preserve void %func() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: invoke amdgpu_cs_chain_preserve void @callee_amdgpu_cs_chain_preserve() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_cs_chain_preserve void @invoke_caller_amdgpu_cs_chain_preserve() { +entry: + invoke amdgpu_cs_chain_preserve void @callee_amdgpu_cs_chain_preserve() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK: invoke amdgpu_cs_chain_preserve void %func() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_cs_chain_preserve void @indirect_invoke_caller_amdgpu_cs_chain_preserve(ptr %func) { +entry: + invoke amdgpu_cs_chain_preserve void %func() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +declare amdgpu_cs void @callee_amdgpu_cs() + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_cs void @callee_amdgpu_cs() +define amdgpu_cs void @call_caller_amdgpu_cs() { +entry: + call amdgpu_cs void @callee_amdgpu_cs() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_cs void %func() +define amdgpu_cs void @indirect_call_caller_amdgpu_cs(ptr %func) { +entry: + call amdgpu_cs void %func() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: invoke amdgpu_cs void @callee_amdgpu_cs() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_cs void @invoke_caller_amdgpu_cs() { +entry: + invoke amdgpu_cs void @callee_amdgpu_cs() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK: invoke amdgpu_cs void %func() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_cs void @indirect_invoke_caller_amdgpu_cs(ptr %func) { +entry: + invoke amdgpu_cs void %func() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +declare amdgpu_es void @callee_amdgpu_es() + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_es void @callee_amdgpu_es() +define amdgpu_es void @call_caller_amdgpu_es() { +entry: + call amdgpu_es void @callee_amdgpu_es() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_es void %func() +define amdgpu_es void @indirect_call_caller_amdgpu_es(ptr %func) { +entry: + call amdgpu_es void %func() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: invoke amdgpu_es void @callee_amdgpu_es() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_es void @invoke_caller_amdgpu_es() { +entry: + invoke amdgpu_es void @callee_amdgpu_es() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK: invoke amdgpu_es void %func() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_es void @indirect_invoke_caller_amdgpu_es(ptr %func) { +entry: + invoke amdgpu_es void %func() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +declare amdgpu_gs void @callee_amdgpu_gs() + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_gs void @callee_amdgpu_gs() +define amdgpu_gs void @call_caller_amdgpu_gs() { +entry: + call amdgpu_gs void @callee_amdgpu_gs() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_gs void %func() +define amdgpu_gs void @indirect_call_caller_amdgpu_gs(ptr %func) { +entry: + call amdgpu_gs void %func() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: invoke amdgpu_gs void @callee_amdgpu_gs() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_gs void @invoke_caller_amdgpu_gs() { +entry: + invoke amdgpu_gs void @callee_amdgpu_gs() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK: invoke amdgpu_gs void %func() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_gs void @indirect_invoke_caller_amdgpu_gs(ptr %func) { +entry: + invoke amdgpu_gs void %func() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +declare amdgpu_hs void @callee_amdgpu_hs() + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_hs void @callee_amdgpu_hs() +define amdgpu_hs void @call_caller_amdgpu_hs() { +entry: + call amdgpu_hs void @callee_amdgpu_hs() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_hs void %func() +define amdgpu_hs void @indirect_call_caller_amdgpu_hs(ptr %func) { +entry: + call amdgpu_hs void %func() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: invoke amdgpu_hs void @callee_amdgpu_hs() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_hs void @invoke_caller_amdgpu_hs() { +entry: + invoke amdgpu_hs void @callee_amdgpu_hs() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK: invoke amdgpu_hs void %func() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_hs void @indirect_invoke_caller_amdgpu_hs(ptr %func) { +entry: + invoke amdgpu_hs void %func() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +declare amdgpu_kernel void @callee_amdgpu_kernel() + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_kernel void @callee_amdgpu_kernel() +define amdgpu_kernel void @call_caller_amdgpu_kernel() { +entry: + call amdgpu_kernel void @callee_amdgpu_kernel() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_kernel void %func() +define amdgpu_kernel void @indirect_call_caller_amdgpu_kernel(ptr %func) { +entry: + call amdgpu_kernel void %func() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: invoke amdgpu_kernel void @callee_amdgpu_kernel() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_kernel void @invoke_caller_amdgpu_kernel() { +entry: + invoke amdgpu_kernel void @callee_amdgpu_kernel() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK: invoke amdgpu_kernel void %func() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_kernel void @indirect_invoke_caller_amdgpu_kernel(ptr %func) { +entry: + invoke amdgpu_kernel void %func() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +declare amdgpu_ls void @callee_amdgpu_ls() + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_ls void @callee_amdgpu_ls() +define amdgpu_ls void @call_caller_amdgpu_ls() { +entry: + call amdgpu_ls void @callee_amdgpu_ls() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_ls void %func() +define amdgpu_ls void @indirect_call_caller_amdgpu_ls(ptr %func) { +entry: + call amdgpu_ls void %func() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: invoke amdgpu_ls void @callee_amdgpu_ls() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_ls void @invoke_caller_amdgpu_ls() { +entry: + invoke amdgpu_ls void @callee_amdgpu_ls() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK: invoke amdgpu_ls void %func() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_ls void @indirect_invoke_caller_amdgpu_ls(ptr %func) { +entry: + invoke amdgpu_ls void %func() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +declare amdgpu_ps void @callee_amdgpu_ps() + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_ps void @callee_amdgpu_ps() +define amdgpu_ps void @call_caller_amdgpu_ps() { +entry: + call amdgpu_ps void @callee_amdgpu_ps() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_ps void %func() +define amdgpu_ps void @indirect_call_caller_amdgpu_ps(ptr %func) { +entry: + call amdgpu_ps void %func() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: invoke amdgpu_ps void @callee_amdgpu_ps() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_ps void @invoke_caller_amdgpu_ps() { +entry: + invoke amdgpu_ps void @callee_amdgpu_ps() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK: invoke amdgpu_ps void %func() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_ps void @indirect_invoke_caller_amdgpu_ps(ptr %func) { +entry: + invoke amdgpu_ps void %func() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +declare amdgpu_vs void @callee_amdgpu_vs() + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_vs void @callee_amdgpu_vs() +define amdgpu_vs void @call_caller_amdgpu_vs() { +entry: + call amdgpu_vs void @callee_amdgpu_vs() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call amdgpu_vs void %func() +define amdgpu_vs void @indirect_call_caller_amdgpu_vs(ptr %func) { +entry: + call amdgpu_vs void %func() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: invoke amdgpu_vs void @callee_amdgpu_vs() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_vs void @invoke_caller_amdgpu_vs() { +entry: + invoke amdgpu_vs void @callee_amdgpu_vs() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK: invoke amdgpu_vs void %func() +; CHECK-NEXT: to label %cont unwind label %unwind +define amdgpu_vs void @indirect_invoke_caller_amdgpu_vs(ptr %func) { +entry: + invoke amdgpu_vs void %func() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +declare spir_kernel void @callee_spir_kernel() + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call spir_kernel void @callee_spir_kernel() +define spir_kernel void @call_caller_spir_kernel() { +entry: + call spir_kernel void @callee_spir_kernel() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: call spir_kernel void %func() +define spir_kernel void @indirect_call_caller_spir_kernel(ptr %func) { +entry: + call spir_kernel void %func() + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK-NEXT: invoke spir_kernel void @callee_spir_kernel() +; CHECK-NEXT: to label %cont unwind label %unwind +define spir_kernel void @invoke_caller_spir_kernel() { +entry: + invoke spir_kernel void @callee_spir_kernel() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +} + +; CHECK: calling convention does not permit calls +; CHECK: invoke spir_kernel void %func() +; CHECK-NEXT: to label %cont unwind label %unwind +define spir_kernel void @indirect_invoke_caller_spir_kernel(ptr %func) { +entry: + invoke spir_kernel void %func() to label %cont unwind label %unwind + ret void + +cont: + ret void + +unwind: + ret void +}