Skip to content

Commit fab4fdd

Browse files
committed
[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., #123609). Once that or similar code is merged, we can move this check accordingly.
1 parent e24c9e7 commit fab4fdd

File tree

7 files changed

+203
-84
lines changed

7 files changed

+203
-84
lines changed

llvm/include/llvm/IR/CallingConv.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,26 @@ namespace CallingConv {
290290

291291
} // end namespace CallingConv
292292

293+
/// \return true if the calling convention allows the function to be called
294+
/// directly or indirectly via a call-like instruction.
295+
constexpr bool isCallableCC(CallingConv::ID CC) {
296+
switch (CC) {
297+
case CallingConv::AMDGPU_CS_Chain:
298+
case CallingConv::AMDGPU_CS_ChainPreserve:
299+
case CallingConv::AMDGPU_CS:
300+
case CallingConv::AMDGPU_ES:
301+
case CallingConv::AMDGPU_GS:
302+
case CallingConv::AMDGPU_HS:
303+
case CallingConv::AMDGPU_KERNEL:
304+
case CallingConv::AMDGPU_LS:
305+
case CallingConv::AMDGPU_PS:
306+
case CallingConv::AMDGPU_VS:
307+
return false;
308+
default:
309+
return true;
310+
}
311+
}
312+
293313
} // end namespace llvm
294314

295315
#endif // LLVM_IR_CALLINGCONV_H

llvm/lib/IR/Verifier.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3598,14 +3598,8 @@ void Verifier::visitCallBase(CallBase &Call) {
35983598
Check(Callee->getValueType() == FTy,
35993599
"Intrinsic called with incompatible signature", Call);
36003600

3601-
// Disallow calls to functions with the amdgpu_cs_chain[_preserve] calling
3602-
// convention.
3603-
auto CC = Call.getCallingConv();
3604-
Check(CC != CallingConv::AMDGPU_CS_Chain &&
3605-
CC != CallingConv::AMDGPU_CS_ChainPreserve,
3606-
"Direct calls to amdgpu_cs_chain/amdgpu_cs_chain_preserve functions "
3607-
"not allowed. Please use the @llvm.amdgpu.cs.chain intrinsic instead.",
3608-
Call);
3601+
// Verify if the calling convention of the callee is callable.
3602+
Check(isCallableCC(Call.getCallingConv()), "Callee is not callable", Call);
36093603

36103604
// Disallow passing/returning values with alignment higher than we can
36113605
// represent.

llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -849,21 +849,6 @@ define amdgpu_kernel void @calls_intrin_ascast_cc_kernel(ptr addrspace(3) %ptr)
849849
ret void
850850
}
851851

852-
define amdgpu_kernel void @call_calls_intrin_ascast_cc_kernel(ptr addrspace(3) %ptr) {
853-
; GFX9-LABEL: define amdgpu_kernel void @call_calls_intrin_ascast_cc_kernel(
854-
; GFX9-SAME: ptr addrspace(3) [[PTR:%.*]]) #[[ATTR1]] {
855-
; GFX9-NEXT: call void @calls_intrin_ascast_cc_kernel(ptr addrspace(3) [[PTR]])
856-
; GFX9-NEXT: ret void
857-
;
858-
; GFX10-LABEL: define amdgpu_kernel void @call_calls_intrin_ascast_cc_kernel(
859-
; GFX10-SAME: ptr addrspace(3) [[PTR:%.*]]) #[[ATTR1]] {
860-
; GFX10-NEXT: call void @calls_intrin_ascast_cc_kernel(ptr addrspace(3) [[PTR]])
861-
; GFX10-NEXT: ret void
862-
;
863-
call void @calls_intrin_ascast_cc_kernel(ptr addrspace(3) %ptr)
864-
ret void
865-
}
866-
867852
define amdgpu_kernel void @with_inline_asm() {
868853
; GFX9-LABEL: define amdgpu_kernel void @with_inline_asm(
869854
; GFX9-SAME: ) #[[ATTR3]] {

llvm/test/CodeGen/AMDGPU/call-to-kernel-undefined.ll

Lines changed: 0 additions & 20 deletions
This file was deleted.

llvm/test/CodeGen/AMDGPU/call-to-kernel.ll

Lines changed: 0 additions & 18 deletions
This file was deleted.

llvm/test/Verifier/amdgpu-cc.ll

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -217,26 +217,3 @@ define amdgpu_cs_chain_preserve void @preallocated_cc_amdgpu_cs_chain_preserve(p
217217
define amdgpu_cs_chain_preserve void @inalloca_cc_amdgpu_cs_chain_preserve(ptr inalloca(i32) %ptr) {
218218
ret void
219219
}
220-
221-
declare amdgpu_cs_chain void @amdgpu_cs_chain_call_target()
222-
declare amdgpu_cs_chain_preserve void @amdgpu_cs_chain_preserve_call_target()
223-
224-
define amdgpu_cs_chain void @cant_call_amdgpu_cs_chain_functions(ptr %f) {
225-
; CHECK: Direct calls to amdgpu_cs_chain/amdgpu_cs_chain_preserve functions not allowed. Please use the @llvm.amdgpu.cs.chain intrinsic instead.
226-
; CHECK-NEXT: call amdgpu_cs_chain
227-
call amdgpu_cs_chain void @amdgpu_cs_chain_call_target()
228-
229-
; CHECK: Direct calls to amdgpu_cs_chain/amdgpu_cs_chain_preserve functions not allowed. Please use the @llvm.amdgpu.cs.chain intrinsic instead.
230-
; CHECK-NEXT: call amdgpu_cs_chain_preserve
231-
call amdgpu_cs_chain_preserve void @amdgpu_cs_chain_preserve_call_target()
232-
233-
; CHECK: Direct calls to amdgpu_cs_chain/amdgpu_cs_chain_preserve functions not allowed. Please use the @llvm.amdgpu.cs.chain intrinsic instead.
234-
; CHECK-NEXT: call amdgpu_cs_chain
235-
call amdgpu_cs_chain void %f()
236-
237-
; CHECK: Direct calls to amdgpu_cs_chain/amdgpu_cs_chain_preserve functions not allowed. Please use the @llvm.amdgpu.cs.chain intrinsic instead.
238-
; CHECK-NEXT: call amdgpu_cs_chain
239-
call amdgpu_cs_chain_preserve void %f()
240-
241-
ret void
242-
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
declare amdgpu_cs void @callee_cs()
4+
5+
declare amdgpu_cs_chain void @callee_cs_chain()
6+
7+
declare amdgpu_cs_chain_preserve void @callee_cs_chain_preserve()
8+
9+
declare amdgpu_es void @callee_es()
10+
11+
declare amdgpu_gs void @callee_gs()
12+
13+
declare amdgpu_hs void @callee_hs()
14+
15+
declare amdgpu_kernel void @callee_kernel()
16+
17+
declare amdgpu_ls void @callee_ls()
18+
19+
declare amdgpu_ps void @callee_ps()
20+
21+
declare amdgpu_vs void @callee_vs()
22+
23+
; CHECK: Callee is not callable
24+
; CHECK-NEXT: call amdgpu_cs_chain void @callee_cs_chain()
25+
define amdgpu_cs_chain void @caller_cs_chain() {
26+
entry:
27+
call amdgpu_cs_chain void @callee_cs_chain()
28+
ret void
29+
}
30+
31+
; CHECK: Callee is not callable
32+
; CHECK-NEXT: call amdgpu_cs_chain_preserve void @callee_cs_chain_preserve()
33+
define amdgpu_cs_chain_preserve void @caller_cs_chain_preserve() {
34+
entry:
35+
call amdgpu_cs_chain_preserve void @callee_cs_chain_preserve()
36+
ret void
37+
}
38+
39+
; CHECK: Callee is not callable
40+
; CHECK-NEXT: call amdgpu_kernel void @callee_kernel()
41+
define amdgpu_kernel void @caller_kernel() {
42+
entry:
43+
call amdgpu_kernel void @callee_kernel()
44+
ret void
45+
}
46+
47+
; CHECK: Callee is not callable
48+
; CHECK-NEXT: call amdgpu_vs void @callee_vs()
49+
define amdgpu_vs void @caller_vs() {
50+
entry:
51+
call amdgpu_vs void @callee_vs()
52+
ret void
53+
}
54+
55+
; CHECK: Callee is not callable
56+
; CHECK-NEXT: call amdgpu_gs void @callee_gs()
57+
define amdgpu_gs void @caller_gs() {
58+
entry:
59+
call amdgpu_gs void @callee_gs()
60+
ret void
61+
}
62+
63+
; CHECK: Callee is not callable
64+
; CHECK-NEXT: call amdgpu_ps void @callee_ps()
65+
define amdgpu_ps void @caller_ps() {
66+
entry:
67+
call amdgpu_ps void @callee_ps()
68+
ret void
69+
}
70+
71+
; CHECK: Callee is not callable
72+
; CHECK-NEXT: call amdgpu_cs void @callee_cs()
73+
define amdgpu_cs void @caller_cs() {
74+
entry:
75+
call amdgpu_cs void @callee_cs()
76+
ret void
77+
}
78+
79+
; CHECK: Callee is not callable
80+
; CHECK-NEXT: call amdgpu_es void @callee_es()
81+
define amdgpu_es void @caller_es() {
82+
entry:
83+
call amdgpu_es void @callee_es()
84+
ret void
85+
}
86+
87+
; CHECK: Callee is not callable
88+
; CHECK-NEXT: call amdgpu_hs void @callee_hs()
89+
define amdgpu_hs void @caller_hs() {
90+
entry:
91+
call amdgpu_hs void @callee_hs()
92+
ret void
93+
}
94+
95+
; CHECK: Callee is not callable
96+
; CHECK-NEXT: call amdgpu_ls void @callee_ls()
97+
define amdgpu_ls void @caller_ls() {
98+
entry:
99+
call amdgpu_ls void @callee_ls()
100+
ret void
101+
}
102+
103+
; CHECK: Callee is not callable
104+
; CHECK-NEXT: call amdgpu_cs_chain void %func()
105+
define amdgpu_cs_chain void @indirect_caller_cs_chain(ptr %func) {
106+
entry:
107+
call amdgpu_cs_chain void %func()
108+
ret void
109+
}
110+
111+
; CHECK: Callee is not callable
112+
; CHECK-NEXT: call amdgpu_cs_chain_preserve void %func()
113+
define amdgpu_cs_chain_preserve void @indirect_caller_cs_chain_preserve(ptr %func) {
114+
entry:
115+
call amdgpu_cs_chain_preserve void %func()
116+
ret void
117+
}
118+
119+
; CHECK: Callee is not callable
120+
; CHECK-NEXT: call amdgpu_kernel void %func()
121+
define void @indirect_caller_kernel(ptr %func) {
122+
entry:
123+
call amdgpu_kernel void %func()
124+
ret void
125+
}
126+
127+
; CHECK: Callee is not callable
128+
; CHECK-NEXT: call amdgpu_vs void %func()
129+
define void @indirect_caller_vs(ptr %func) {
130+
entry:
131+
call amdgpu_vs void %func()
132+
ret void
133+
}
134+
135+
; CHECK: Callee is not callable
136+
; CHECK-NEXT: call amdgpu_gs void %func()
137+
define void @indirect_caller_gs(ptr %func) {
138+
entry:
139+
call amdgpu_gs void %func()
140+
ret void
141+
}
142+
143+
; CHECK: Callee is not callable
144+
; CHECK-NEXT: call amdgpu_ps void %func()
145+
define void @indirect_caller_ps(ptr %func) {
146+
entry:
147+
call amdgpu_ps void %func()
148+
ret void
149+
}
150+
151+
; CHECK: Callee is not callable
152+
; CHECK-NEXT: call amdgpu_cs void %func()
153+
define void @indirect_caller_cs(ptr %func) {
154+
entry:
155+
call amdgpu_cs void %func()
156+
ret void
157+
}
158+
159+
; CHECK: Callee is not callable
160+
; CHECK-NEXT: call amdgpu_es void %func()
161+
define void @indirect_caller_es(ptr %func) {
162+
entry:
163+
call amdgpu_es void %func()
164+
ret void
165+
}
166+
167+
; CHECK: Callee is not callable
168+
; CHECK-NEXT: call amdgpu_hs void %func()
169+
define void @indirect_caller_hs(ptr %func) {
170+
entry:
171+
call amdgpu_hs void %func()
172+
ret void
173+
}
174+
175+
; CHECK: Callee is not callable
176+
; CHECK-NEXT: call amdgpu_ls void %func()
177+
define void @indirect_caller_ls(ptr %func) {
178+
entry:
179+
call amdgpu_ls void %func()
180+
ret void
181+
}

0 commit comments

Comments
 (0)