[llvm] [AMDGPU][Verifier] Mark calls to entry functions as invalid in the IR verifier (PR #134910)
Shilei Tian via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 11 10:14:43 PDT 2025
https://github.com/shiltian updated https://github.com/llvm/llvm-project/pull/134910
>From 86407ad80265b6e5c7ba5361165ea41b468f08aa Mon Sep 17 00:00:00 2001
From: Shilei Tian <i at tianshilei.me>
Date: Fri, 11 Apr 2025 13:14:30 -0400
Subject: [PATCH] [AMDGPU][Verifier] Mark calls to entry functions as invalid
in the IR verifier
For AMDGPU, calls to entry functions are invalid. Previously, due to certain
limitations, this restriction was not enforced by the IR verifier. These
limitations have now been resolved, enabling us to enforce this check.
Adding target-dependent checks directly into the IR verifier is not ideal.
However, a cleaner solution, such as a dedicated target-dependent IR verifier,
is underway (e.g., https://github.com/llvm/llvm-project/pull/123609). Once that
or similar code is merged, we can move this check accordingly.
---
llvm/include/llvm/IR/CallingConv.h | 21 +
llvm/lib/IR/Verifier.cpp | 11 +-
llvm/test/Bitcode/calling-conventions.3.2.ll | 6 -
.../Bitcode/calling-conventions.3.2.ll.bc | Bin 2568 -> 2888 bytes
.../AMDGPU/attributor-flatscratchinit.ll | 15 -
.../AMDGPU/call-to-kernel-undefined.ll | 20 -
llvm/test/CodeGen/AMDGPU/call-to-kernel.ll | 18 -
llvm/test/Other/spir_cc.ll | 1 -
llvm/test/Verifier/amdgpu-cc.ll | 23 -
.../call-to-non-callable-functions.ll | 529 ++++++++++++++++++
10 files changed, 553 insertions(+), 91 deletions(-)
delete mode 100644 llvm/test/CodeGen/AMDGPU/call-to-kernel-undefined.ll
delete mode 100644 llvm/test/CodeGen/AMDGPU/call-to-kernel.ll
create mode 100644 llvm/test/Verifier/call-to-non-callable-functions.ll
diff --git a/llvm/include/llvm/IR/CallingConv.h b/llvm/include/llvm/IR/CallingConv.h
index 7897aabb6c1a9..d68491eb5535c 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 7d32bf29ae108..e3f6c1ad5a65b 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 9221ef30c8dc9..678886777ad4c 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 b7ac769a82b34aeabe70edab8562f53bc0601f31..19cdf69be1c26552e8208b56efc3feba41caf047 100644
GIT binary patch
delta 1749
zcmZ9NeN0<b7{*U~`^DC at d{dx>URDXtY`ruwX=yv5#o2u+A(~(&fr at 1?`6#r5u^4+x
zyOn7TCDee?#dc%BmZ+c;FhMPJTZ)v~Ik#0|j2b$aLCHw}&`lH1EnvHQ{<tUicc1gV
z&->ilv at 6w@UZ_%g7N1WAfDQn7lZ}avy#C!_<&!I~Wcx&=6bT)mYygU>0PLiq0B#_&
zr|^)eg5&5xOC9dc^VCc)b2cqgVz)n&C at 3=e05~fIAOQ;VYH5jIsyb&9%i+b*GF_(G
zk&v&xPFG3tS*$EdK?#Ejve3gEL+JFo<FjALislA~ynkjqQhq)@+w}M!-KX96mp9&@
z8yi2W|NCfV&aJA3v2Xu9-?tL!!%RnVzn=-;mHKOk?ycPU>yNR%dy&YzvVHCiNyf*@
z0V;#Sf(Eu$H8}IC1r<`Z?*U+Y9J>pxq8Pv_ymF=0MT-#(s4v$iRiH6KXgbc0>>%ox
zwlFO8JDcxLBXZeVJRE&ZpqPe%ZZ8jDU(&dfib=Jub?&mNwl#1^uz|<)m$1`uh*7P%
z&3R84ZMlVsjydTjZR*o4Kh!9w&ywu-*ICO+G3;}*h7w~92xkFRQW?qF3_UNViKcZ>
zoKB3ry{b(x(u<>U#iRB+KPcT+5Id1XlQhmJAo|^?Nsbr65ijOC;|WZDcScX#EPzPf
zJR^z|nTS_-{N?<oOhHeB8)Q$H(=>7CqMp7fBYWC-k?iSfNq77)!qd5qn5Pr~O*w+X
zvdDe_gy{&>&VJR1h^VGrzpZKc(`G?1l(B{i9-xA&s33?6R?*yA;W_!FS~-EpoEDkC
zVp6YXwx494Vlhu?Z0&km=Ijb*9pi?UI1h`t4_(|a=A|HpVP-qeR at HCQ>upAt%^0w?
z_M5FGvL&x{M6GnFW&Yx;F2N6O!BR=i;uODDWU9e9ArEH_<H9OoOpRJj at R$aTt;%J4
z2Zx78ofL)Lt8jXy0d>)&Meg_7udy{~no64kz22A-l$%p)4<Exg>q74O5 at WrL8zD+@
z!b^+?LT)I)31b(EEp2to4wfymJZr)$w<7WZwbXCPwjwfzC0XG|6jra)NkjrJ at c`J<
zJ4IKUMsPE;qrj%GX11NQwZNGRn5`B1PrTAA6#0Nf>GV?H<_A&!LWsX0<S%Q9>#8|t
zTFVc(`M%9SwNn&s1bTp$aL&%I&AI45O5qeiwan**vC8dgnH^F35INEPCj8PFaA*1z
zy(x@*6H7ZnV66}U;!UQ|rn)E;kC4Zz{+|=BH at Oe;`&2?3V*$t(Nh~Phu@*>d6|#8}
z>qkvI)~_UpL*XwZ)&*IR#6}>yOJWYl?vPkNWVcDo1=-I8GsR6Z4B;)3a00TQNX!G-
zO==5F0cHs#oWwk9QWz;1-G`?<LNwYJ at U$mL9Yup at oThcTHF#z>ZMftBp8XNc7dn6o
zF3?uZ2l3p`Xso<L0BrrlD&gPB8CWbCaX#0(%v|Z6XI<Aw3io1rv19c{ab0txPHd>F
zZ!p$to5ZEfH76Q%O-6&b%}~?)mQLKz(AKy|-`ad!S7VIch>bdfQLL&rMj!XCB;@`F
DVRpT7
delta 1411
zcmZ9MZ%7ki9LImRJ8e at jmzyoq+NDDJV&1mWZCaFPCF=S|z6cg<ZfA-AD#aHO?2;K%
z3Z~PtvQiSwLReH(FRY1KOMD?zV1cCtCZZ9&De6tXTk6jHjoqH-bKiS at -+iBl3nh6~
z`T{oiX{QPx3INLEm~`v$=M~n!j}DcTr4<r}D4^p2772h at 84WVjB(>>F+?uTISw8*w
zfUQkC8ba8j1&G04!?uuI>uRR_be{(=Up>7()rQiGmtsAx(u9OG$N&zN0LgS|{B&@P
zd$?4i8_pl7Z?63F+p4R7?a0Yn+Wq8J-IL+P{(;ZmpH<DZKbu;l)eN;qcx<^yH`AAV
z2^1 at H06Sbf)}l;Dn=2I;^exb`jFl+>PiT%>OM)?LHRB~sW%7tfSm)#nHIxuRL5Le%
zm{Igc2t>Q>Mf+l`AXzIbsavZOB3dpDPruJLUC5+X000B*y~e|`Ba)WC0 at NKz%fc^;
zB0BP*;C`$yv7;c2-2ZQoOy5sMhN(FsgJ^qEb5b!caaOGJi8SG~&OH#>0>GuRE{oCv
zK=<luaiSn3ah4RedAUE1uwUnvgW|=7zxcOH6hk=qLAhEi!rd7^&?hEB@~82*i3&X>
zcV>!!;Hh&cpAhvAn;MT2Osy7rD$72$I>mwDsiRHmX=x%+EJ9DkHMhjX4(T~^m3lpZ
zcMQ27zeYKq@^bcJJGoiLu(KcO)Vbc2AH<e%N6Nfo|GN*PCJ&hx7|otyEfcK8%US}g
zWs=<ugBk#(e>j@;pI*1qO_lcuZ5&zvVG|Om5idamwHnINgHs6)A-At`67T=lPa?l9
zb7*nzR at qFthPowTQ^;<vVQzw$N7%gv5=0lRp>9YRkGks;=0$c*!UD*;B+Q5Gs)ThR
zyW*C>9)z6|b{AQPggr&(m#`qRcG($BL5V3C;uE%cl&$1;!ptXLA&W-Lyt<b><*@J@
z?~`64kKgo|yxXhG<2Sz`Lwoc2)Hme(Y(BsBEh%r>#naP5lHodmFTGYAZ6G_${vC>M
z(N)~pTCUo!jG5f8XLR_fZ>-h2j7EdgXyA;D+2u0kR_Mz)B<7qQW|Pz8%yn_)PN&J`
eWOTOb>c$#d16SW*E2wO6*10&FKQneK9>{;hLKcqz
diff --git a/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll b/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll
index fc61aa5f981dd..a3d6c3b729523 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 da7385475088b..0000000000000
--- 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 1f4f6471fcdba..0000000000000
--- 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 ffc02945de4d2..33cf0bbf86a1f 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 ce48d1fdae3e5..aec09771d2e4f 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 0000000000000..f33682c0dbe23
--- /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
+}
More information about the llvm-commits
mailing list