[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
Tue Apr 8 12:18:28 PDT 2025
https://github.com/shiltian created https://github.com/llvm/llvm-project/pull/134910
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.
>From dc71454022394320a796e47f1a3f0c9b3445e9db Mon Sep 17 00:00:00 2001
From: Shilei Tian <i at tianshilei.me>
Date: Tue, 8 Apr 2025 15:17:58 -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/lib/IR/Verifier.cpp | 21 +++-
.../AMDGPU/attributor-flatscratchinit.ll | 15 ---
.../AMDGPU/call-to-kernel-undefined.ll | 20 ----
llvm/test/CodeGen/AMDGPU/call-to-kernel.ll | 103 ++++++++++++++++--
4 files changed, 115 insertions(+), 44 deletions(-)
delete mode 100644 llvm/test/CodeGen/AMDGPU/call-to-kernel-undefined.ll
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
+}
More information about the llvm-commits
mailing list