[llvm] [NVPTX] Add more clear error message for using invalid syncscope (PR #165737)

Stefan Mada via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 31 11:49:27 PDT 2025


https://github.com/smada3 updated https://github.com/llvm/llvm-project/pull/165737

>From 30b99de5b4b829669c20647b381fb5bb28bb879d Mon Sep 17 00:00:00 2001
From: Stefan Mada <smada at nvidia.com>
Date: Thu, 30 Oct 2025 16:30:07 +0000
Subject: [PATCH 1/2] [NVPTX] Add more clear error message for using invalid
 syncscope

---
 llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp   | 25 ++++++++++++++-----
 llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h     |  1 +
 .../cmpxchg-unsupported-syncscope.err.ll      | 11 ++++++++
 3 files changed, 31 insertions(+), 6 deletions(-)
 create mode 100644 llvm/test/CodeGen/NVPTX/cmpxchg-unsupported-syncscope.err.ll

diff --git a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
index 7e7ee754c250d..0bcb9c89b3e8b 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
@@ -1836,7 +1836,7 @@ bool NVPTXDAGToDAGISel::tryFence(SDNode *N) {
   return true;
 }
 
-NVPTXScopes::NVPTXScopes(LLVMContext &C) {
+NVPTXScopes::NVPTXScopes(LLVMContext &C) : Context(&C) {
   Scopes[C.getOrInsertSyncScopeID("singlethread")] = NVPTX::Scope::Thread;
   Scopes[C.getOrInsertSyncScopeID("")] = NVPTX::Scope::System;
   Scopes[C.getOrInsertSyncScopeID("block")] = NVPTX::Scope::Block;
@@ -1851,11 +1851,24 @@ NVPTX::Scope NVPTXScopes::operator[](SyncScope::ID ID) const {
 
   auto S = Scopes.find(ID);
   if (S == Scopes.end()) {
-    // TODO:
-    // - Add API to LLVMContext to get the name of a single scope.
-    // - Use that API here to print an error containing the name
-    //   of this Unknown ID.
-    report_fatal_error(formatv("Could not find scope ID={}.", int(ID)));
+    // Get the actual scope name from LLVMContext for a better error message
+    std::string scopeName = "<unknown>";
+    if (auto name = Context->getSyncScopeName(ID))
+      scopeName = name->str();
+
+    // Build list of supported syncscopes programmatically
+    std::string supportedScopes;
+    for (const auto &Entry : Scopes) {
+      if (!supportedScopes.empty())
+        supportedScopes += ", ";
+      if (auto name = Context->getSyncScopeName(Entry.first))
+        supportedScopes += name->empty() ? "<empty string>" : name->str();
+    }
+
+    reportFatalUsageError(
+        formatv("NVPTX backend does not support syncscope \"{0}\" (ID={1}).\n"
+                "Supported syncscopes are: {2}.",
+                scopeName, int(ID), supportedScopes));
   }
   return S->second;
 }
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h
index c912e709d0aa0..5fb1267224bd5 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h
+++ b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h
@@ -35,6 +35,7 @@ struct NVPTXScopes {
 
 private:
   SmallMapVector<SyncScope::ID, NVPTX::Scope, 8> Scopes{};
+  LLVMContext *Context = nullptr;
 };
 
 class LLVM_LIBRARY_VISIBILITY NVPTXDAGToDAGISel : public SelectionDAGISel {
diff --git a/llvm/test/CodeGen/NVPTX/cmpxchg-unsupported-syncscope.err.ll b/llvm/test/CodeGen/NVPTX/cmpxchg-unsupported-syncscope.err.ll
new file mode 100644
index 0000000000000..d3853e2fdaa88
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/cmpxchg-unsupported-syncscope.err.ll
@@ -0,0 +1,11 @@
+; RUN: not llc -mcpu=sm_100a -mtriple=nvptx64 -mattr=+ptx86 %s 2>&1 | FileCheck %s
+
+; Test that we get a clear error message when using an unsupported syncscope.
+
+; CHECK: NVPTX backend does not support syncscope "agent"
+; CHECK: Supported syncscopes are: singlethread, <empty string>, block, cluster, device
+define i32 @cmpxchg_unsupported_syncscope_agent(ptr %addr, i32 %cmp, i32 %new) {
+  %result = cmpxchg ptr %addr, i32 %cmp, i32 %new syncscope("agent") monotonic monotonic
+  %value = extractvalue { i32, i1 } %result, 0
+  ret i32 %value
+}

>From 24ffd3e452e6c93a76bedf69e70c85fcfa7bed3e Mon Sep 17 00:00:00 2001
From: Stefan Mada <smada at nvidia.com>
Date: Fri, 31 Oct 2025 18:49:08 +0000
Subject: [PATCH 2/2] Fixed printing code to be cleaner

---
 llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
index 0bcb9c89b3e8b..a899ead0f38c6 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
@@ -1857,18 +1857,16 @@ NVPTX::Scope NVPTXScopes::operator[](SyncScope::ID ID) const {
       scopeName = name->str();
 
     // Build list of supported syncscopes programmatically
-    std::string supportedScopes;
+    SmallVector<StringRef> supportedScopes;
     for (const auto &Entry : Scopes) {
-      if (!supportedScopes.empty())
-        supportedScopes += ", ";
       if (auto name = Context->getSyncScopeName(Entry.first))
-        supportedScopes += name->empty() ? "<empty string>" : name->str();
+        supportedScopes.push_back(name->empty() ? "<empty string>" : *name);
     }
 
     reportFatalUsageError(
         formatv("NVPTX backend does not support syncscope \"{0}\" (ID={1}).\n"
                 "Supported syncscopes are: {2}.",
-                scopeName, int(ID), supportedScopes));
+                scopeName, int(ID), llvm::join(supportedScopes, ", ")));
   }
   return S->second;
 }



More information about the llvm-commits mailing list