[llvm] [PlaceSafepoints] Report usage error instead of asserting on invalid gc.safepoint_poll (PR #205520)

Gustas Rove via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 24 07:37:40 PDT 2026


https://github.com/TheMixas updated https://github.com/llvm/llvm-project/pull/205520

>From 6a2ddffa6fe4e5292a26d0c71184346cacb3cff6 Mon Sep 17 00:00:00 2001
From: themixas <themixaslt at gmail.com>
Date: Wed, 24 Jun 2026 10:54:28 +0100
Subject: [PATCH] [PlaceSafepoints] Report usage error instead of asserting on
 invalid gc.safepoint_poll

When opt runs place-safepoints on valid IR that needs a safepoint poll but
does not define a valid gc.safepoint_poll, InsertSafepointPoll asserted and
crashed. Since this is reachable from user input, replace the precondition
asserts with reportFatalUsageError so the tool reports a clean error and
exits instead of crashing. These now report in all builds, not only
assertions-enabled builds.

Fixes #191975.
---
 llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp      |  3 ++-
 .../PlaceSafepoints/missing-safepoint-poll.ll       |  7 +++++++
 .../PlaceSafepoints/safepoint-poll-empty.ll         | 10 ++++++++++
 .../PlaceSafepoints/safepoint-poll-wrong-type.ll    | 13 +++++++++++++
 4 files changed, 32 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/Transforms/PlaceSafepoints/missing-safepoint-poll.ll
 create mode 100644 llvm/test/Transforms/PlaceSafepoints/safepoint-poll-empty.ll
 create mode 100644 llvm/test/Transforms/PlaceSafepoints/safepoint-poll-wrong-type.ll

diff --git a/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp b/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp
index 44600acf5b418..f9715cb5a00e0 100644
--- a/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp
+++ b/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp
@@ -629,7 +629,8 @@ InsertSafepointPoll(BasicBlock::iterator InsertBefore,
   // path call - where we need to insert a safepoint (parsepoint).
 
   auto *F = M->getFunction(GCSafepointPollName);
-  assert(F && "gc.safepoint_poll function is missing");
+  if (!F)
+    reportFatalUsageError("gc.safepoint_poll function is missing");
   assert(F->getFunctionType() ==
              FunctionType::get(Type::getVoidTy(M->getContext()), false) &&
          "gc.safepoint_poll declared with wrong type");
diff --git a/llvm/test/Transforms/PlaceSafepoints/missing-safepoint-poll.ll b/llvm/test/Transforms/PlaceSafepoints/missing-safepoint-poll.ll
new file mode 100644
index 0000000000000..5a7d5d4cc5b58
--- /dev/null
+++ b/llvm/test/Transforms/PlaceSafepoints/missing-safepoint-poll.ll
@@ -0,0 +1,7 @@
+; RUN: not opt < %s -S -passes=place-safepoints 2>&1 | FileCheck %s
+; CHECK: LLVM ERROR: gc.safepoint_poll function is missing
+
+define void @test_libcall() gc "statepoint-example" {
+entry:
+  ret void
+}
\ No newline at end of file
diff --git a/llvm/test/Transforms/PlaceSafepoints/safepoint-poll-empty.ll b/llvm/test/Transforms/PlaceSafepoints/safepoint-poll-empty.ll
new file mode 100644
index 0000000000000..47e946b5b6d74
--- /dev/null
+++ b/llvm/test/Transforms/PlaceSafepoints/safepoint-poll-empty.ll
@@ -0,0 +1,10 @@
+; REQUIRES: asserts
+; RUN: not --crash opt < %s -S -passes=place-safepoints 2>&1 | FileCheck %s
+; CHECK: gc.safepoint_poll must be a non-empty function
+
+define void @test_libcall() gc "statepoint-example" {
+entry:
+  ret void
+}
+
+declare void @gc.safepoint_poll()
\ No newline at end of file
diff --git a/llvm/test/Transforms/PlaceSafepoints/safepoint-poll-wrong-type.ll b/llvm/test/Transforms/PlaceSafepoints/safepoint-poll-wrong-type.ll
new file mode 100644
index 0000000000000..d96fcc4f5d46d
--- /dev/null
+++ b/llvm/test/Transforms/PlaceSafepoints/safepoint-poll-wrong-type.ll
@@ -0,0 +1,13 @@
+; REQUIRES: asserts
+; RUN: not --crash opt < %s -S -passes=place-safepoints 2>&1 | FileCheck %s
+; CHECK: gc.safepoint_poll declared with wrong type
+
+define void @test_libcall() gc "statepoint-example" {
+entry:
+  ret void
+}
+
+define i32 @gc.safepoint_poll() {
+entry:
+  ret i32 0
+}
\ No newline at end of file



More information about the llvm-commits mailing list