[llvm] [AMDGPU][Verifier] Mark calls to entry functions as invalid in the IR verifier (PR #134910)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 8 12:19:01 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: Shilei Tian (shiltian)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/134910.diff
4 Files Affected:
- (modified) llvm/lib/IR/Verifier.cpp (+20-1)
- (modified) llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll (-15)
- (removed) llvm/test/CodeGen/AMDGPU/call-to-kernel-undefined.ll (-20)
- (modified) llvm/test/CodeGen/AMDGPU/call-to-kernel.ll (+95-8)
``````````diff
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 7423e746dfa9a..a8d2f817efe06 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3765,9 +3765,28 @@ void Verifier::visitCallBase(CallBase &Call) {
"Return type cannot be x86_amx for indirect call!");
}
- if (Function *F = Call.getCalledFunction())
+ if (Function *F = Call.getCalledFunction()) {
if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
visitIntrinsicCall(ID, Call);
+ // TODO: Move this to target dependent IR verifier once we have it.
+ auto IsAMDGPUEntryFunctionCC = [](CallingConv::ID CC) -> bool {
+ switch (CC) {
+ case CallingConv::AMDGPU_KERNEL:
+ case CallingConv::AMDGPU_VS:
+ case CallingConv::AMDGPU_GS:
+ case CallingConv::AMDGPU_PS:
+ case CallingConv::AMDGPU_CS:
+ case CallingConv::AMDGPU_ES:
+ case CallingConv::AMDGPU_HS:
+ case CallingConv::AMDGPU_LS:
+ return true;
+ default:
+ return false;
+ }
+ };
+ Check(!IsAMDGPUEntryFunctionCC(F->getCallingConv()),
+ "Call to amdgpu entry function is not allowed");
+ }
// Verify that a callsite has at most one "deopt", at most one "funclet", at
// most one "gc-transition", at most one "cfguardtarget", at most one
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
index 1f4f6471fcdba..7463d23a81af7 100644
--- a/llvm/test/CodeGen/AMDGPU/call-to-kernel.ll
+++ b/llvm/test/CodeGen/AMDGPU/call-to-kernel.ll
@@ -1,18 +1,105 @@
-; RUN: not --crash llc -mtriple=amdgcn -mcpu=tahiti -verify-machineinstrs -o /dev/null %s 2>&1 | FileCheck %s
+; RUN: not llvm-as %s -o /dev/null 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 {
+; CHECK: Call to amdgpu entry function is not allowed
+define amdgpu_kernel void @callee_kernel(ptr addrspace(1) %out) {
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 {
+define amdgpu_kernel void @caller_kernel(ptr addrspace(1) %out) {
entry:
- call amdgpu_kernel void @callee_kernel(ptr addrspace(1) %out)
+ call void @callee_kernel(ptr addrspace(1) %out)
ret void
}
-attributes #0 = { nounwind noinline }
+; CHECK: Call to amdgpu entry function is not allowed
+define amdgpu_vs void @callee_vs(ptr addrspace(1) inreg %out) {
+entry:
+ store volatile i32 0, ptr addrspace(1) %out
+ ret void
+}
+
+define amdgpu_vs void @caller_vs(ptr addrspace(1) inreg %out) {
+entry:
+ call void @callee_vs(ptr addrspace(1) %out)
+ ret void
+}
+
+; CHECK: Call to amdgpu entry function is not allowed
+define amdgpu_gs void @callee_gs(ptr addrspace(1) %out) {
+entry:
+ store volatile i32 0, ptr addrspace(1) %out
+ ret void
+}
+
+define amdgpu_gs void @caller_gs(ptr addrspace(1) %out) {
+entry:
+ call void @callee_gs(ptr addrspace(1) %out)
+ ret void
+}
+
+; CHECK: Call to amdgpu entry function is not allowed
+define amdgpu_ps void @callee_ps(ptr addrspace(1) %out) {
+entry:
+ store volatile i32 0, ptr addrspace(1) %out
+ ret void
+}
+
+define amdgpu_ps void @caller_ps(ptr addrspace(1) %out) {
+entry:
+ call void @callee_ps(ptr addrspace(1) %out)
+ ret void
+}
+
+; CHECK: Call to amdgpu entry function is not allowed
+define amdgpu_cs void @callee_cs(ptr addrspace(1) %out) {
+entry:
+ store volatile i32 0, ptr addrspace(1) %out
+ ret void
+}
+
+define amdgpu_cs void @caller_cs(ptr addrspace(1) %out) {
+entry:
+ call void @callee_cs(ptr addrspace(1) %out)
+ ret void
+}
+
+; CHECK: Call to amdgpu entry function is not allowed
+define amdgpu_es void @callee_es(ptr addrspace(1) %out) {
+entry:
+ store volatile i32 0, ptr addrspace(1) %out
+ ret void
+}
+
+define amdgpu_es void @caller_es(ptr addrspace(1) %out) {
+entry:
+ call void @callee_es(ptr addrspace(1) %out)
+ ret void
+}
+
+; CHECK: Call to amdgpu entry function is not allowed
+define amdgpu_hs void @callee_hs(ptr addrspace(1) %out) {
+entry:
+ store volatile i32 0, ptr addrspace(1) %out
+ ret void
+}
+
+define amdgpu_hs void @caller_hs(ptr addrspace(1) %out) {
+entry:
+ call void @callee_hs(ptr addrspace(1) %out)
+ ret void
+}
+
+; CHECK: Call to amdgpu entry function is not allowed
+define amdgpu_ls void @callee_ls(ptr addrspace(1) %out) {
+entry:
+ store volatile i32 0, ptr addrspace(1) %out
+ ret void
+}
+
+define amdgpu_ls void @caller_ls(ptr addrspace(1) %out) {
+entry:
+ call void @callee_ls(ptr addrspace(1) %out)
+ ret void
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/134910
More information about the llvm-commits
mailing list