[clang] [llvm] [mlir] [ErrorHandling] Add reportFatalInternalError + reportFatalUsageError (NFC) (PR #138251)

Nikita Popov via cfe-commits cfe-commits at lists.llvm.org
Fri May 2 13:04:06 PDT 2025


https://github.com/nikic updated https://github.com/llvm/llvm-project/pull/138251

>From 114ba17da2f522c5fd5045f5030a44fe13b3af27 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 2 May 2025 12:46:48 +0200
Subject: [PATCH 1/6] [ErrorHandling] Add reportFatalInternalError +
 reportFatalUsageError (NFC)

This implements the result of the discussion at:
https://discourse.llvm.org/t/rfc-report-fatal-error-and-the-default-value-of-gencrashdialog/73587

There are two different use cases for report_fatal_error, so
replace it with two functions reportFatalInternalError() and
reportFatalUsageError(). The former indicates a bug in LLVM and
generates a crash dialog. The latter does not. The names have been
suggested by rnk and people seemed to like them.

This replaces a lot of the usages that passed an explicit value
for GenCrashDiag. I did not bulk replace remaining report_fatal_error
usage.
---
 clang/lib/AST/ExternalASTSource.cpp           |  2 +-
 .../ClangLinkerWrapper.cpp                    |  2 +-
 .../llvm/CodeGen/CodeGenTargetMachineImpl.h   |  4 +-
 llvm/include/llvm/Passes/CodeGenPassBuilder.h |  2 +-
 llvm/include/llvm/Support/Error.h             | 11 +++++-
 llvm/include/llvm/Support/ErrorHandling.h     | 37 ++++++++++++++-----
 llvm/lib/LTO/LTOBackend.cpp                   |  2 +-
 llvm/lib/Support/Error.cpp                    |  7 ++++
 llvm/lib/Support/ErrorHandling.cpp            | 19 ++++++++++
 llvm/lib/Support/raw_ostream.cpp              |  5 +--
 llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp   |  5 +--
 .../Target/DirectX/DXILIntrinsicExpansion.cpp | 14 +++----
 llvm/lib/Target/DirectX/DXILOpBuilder.cpp     |  5 +--
 .../lib/Target/DirectX/DXILResourceAccess.cpp |  3 +-
 .../LoongArch/LoongArchISelLowering.cpp       |  5 +--
 .../RISCV/MCTargetDesc/RISCVBaseInfo.cpp      |  5 ++-
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   | 10 ++---
 llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp |  2 +-
 llvm/lib/Transforms/IPO/BlockExtractor.cpp    | 13 +++----
 llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp  |  8 ++--
 .../InstCombine/InstructionCombining.cpp      | 11 +++---
 .../Instrumentation/GCOVProfiling.cpp         |  4 +-
 llvm/lib/Transforms/Scalar/LICM.cpp           |  6 +--
 .../lib/Transforms/Scalar/LoopPassManager.cpp |  5 +--
 llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp |  4 +-
 llvm/tools/opt/optdriver.cpp                  |  2 +-
 mlir/lib/TableGen/AttrOrTypeDef.cpp           |  5 +--
 27 files changed, 116 insertions(+), 82 deletions(-)

diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp
index 3e865cb7679b5..e8c1004089713 100644
--- a/clang/lib/AST/ExternalASTSource.cpp
+++ b/clang/lib/AST/ExternalASTSource.cpp
@@ -129,7 +129,7 @@ uint32_t ExternalASTSource::incrementGeneration(ASTContext &C) {
     // FIXME: Only bump the generation counter if the current generation number
     // has been observed?
     if (!++CurrentGeneration)
-      llvm::report_fatal_error("generation counter overflowed", false);
+      llvm::reportFatalUsageError("generation counter overflowed");
   }
 
   return OldGeneration;
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index bdeaa2031d184..105b656c9dfad 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -1404,7 +1404,7 @@ int main(int Argc, char **Argv) {
   PassPlugins.setCallback([&](const std::string &PluginPath) {
     auto Plugin = PassPlugin::Load(PluginPath);
     if (!Plugin)
-      report_fatal_error(Plugin.takeError(), /*gen_crash_diag=*/false);
+      reportFatalUsageError(Plugin.takeError());
     PluginList.emplace_back(Plugin.get());
   });
   cl::ParseCommandLineOptions(NewArgv.size(), &NewArgv[0]);
diff --git a/llvm/include/llvm/CodeGen/CodeGenTargetMachineImpl.h b/llvm/include/llvm/CodeGen/CodeGenTargetMachineImpl.h
index 7bb4420e555fb..ad399cd0b2f10 100644
--- a/llvm/include/llvm/CodeGen/CodeGenTargetMachineImpl.h
+++ b/llvm/include/llvm/CodeGen/CodeGenTargetMachineImpl.h
@@ -82,9 +82,9 @@ getEffectiveCodeModel(std::optional<CodeModel::Model> CM,
   if (CM) {
     // By default, targets do not support the tiny and kernel models.
     if (*CM == CodeModel::Tiny)
-      report_fatal_error("Target does not support the tiny CodeModel", false);
+      reportFatalUsageError("Target does not support the tiny CodeModel");
     if (*CM == CodeModel::Kernel)
-      report_fatal_error("Target does not support the kernel CodeModel", false);
+      reportFatalUsageError("Target does not support the kernel CodeModel");
     return *CM;
   }
   return Default;
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 80b74785473f7..6ed9ac47405d3 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -1117,7 +1117,7 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
       addPass(RAGreedyPass());
       break;
     default:
-      report_fatal_error("register allocator not supported yet", false);
+      reportFatalUsageError("register allocator not supported yet");
     }
     return;
   }
diff --git a/llvm/include/llvm/Support/Error.h b/llvm/include/llvm/Support/Error.h
index f0580bdd50ee6..43deccb825347 100644
--- a/llvm/include/llvm/Support/Error.h
+++ b/llvm/include/llvm/Support/Error.h
@@ -735,10 +735,17 @@ template <class T> class [[nodiscard]] Expected {
 #endif
 };
 
-/// Report a serious error, calling any installed error handler. See
-/// ErrorHandling.h.
+/// @deprecated Use reportFatalInternalError() or reportFatalUsageError()
+/// instead.
 [[noreturn]] void report_fatal_error(Error Err, bool gen_crash_diag = true);
 
+/// Report a fatal error that indicates a bug in LLVM.
+/// See ErrorHandling.h for details.
+[[noreturn]] void reportFatalInternalError(Error Err);
+/// Report a fatal error that does not indicate a bug in LLVM.
+/// See ErrorHandling.h for details.
+[[noreturn]] void reportFatalUsageError(Error Err);
+
 /// Report a fatal error if Err is a failure value.
 ///
 /// This function can be used to wrap calls to fallible functions ONLY when it
diff --git a/llvm/include/llvm/Support/ErrorHandling.h b/llvm/include/llvm/Support/ErrorHandling.h
index 9c8e3448f3a03..16a5fc8ad4092 100644
--- a/llvm/include/llvm/Support/ErrorHandling.h
+++ b/llvm/include/llvm/Support/ErrorHandling.h
@@ -59,15 +59,8 @@ namespace llvm {
     ~ScopedFatalErrorHandler() { remove_fatal_error_handler(); }
   };
 
-/// Reports a serious error, calling any installed error handler. These
-/// functions are intended to be used for error conditions which are outside
-/// the control of the compiler (I/O errors, invalid user input, etc.)
-///
-/// If no error handler is installed the default is to print the message to
-/// standard error, followed by a newline.
-/// After the error handler is called this function will call abort(), it
-/// does not return.
-/// NOTE: The std::string variant was removed to avoid a <string> dependency.
+/// @deprecated Use reportFatalInternalError() or reportFatalUsageError()
+/// instead.
 [[noreturn]] void report_fatal_error(const char *reason,
                                      bool gen_crash_diag = true);
 [[noreturn]] void report_fatal_error(StringRef reason,
@@ -75,6 +68,32 @@ namespace llvm {
 [[noreturn]] void report_fatal_error(const Twine &reason,
                                      bool gen_crash_diag = true);
 
+/// Report a fatal error that likely indicates a bug in LLVM. It serves a
+/// similar purpose as an assertion, but is always enabled, regardless of the
+/// value of NDEBUG.
+///
+/// This will call installed error handlers (or print the message by default)
+/// and then abort. This will produce a crash trace and *will* ask users to
+/// report an LLVM bug.
+[[noreturn]] void reportFatalInternalError(const char *reason);
+[[noreturn]] void reportFatalInternalError(StringRef reason);
+[[noreturn]] void reportFatalInternalError(const Twine &reason);
+
+/// Report a fatal error that does not indicate a bug in LLVM, in contexts
+/// where a more sophisticated error reporting mechanism (such as Error/Expected
+/// or DiagnosticInfo) is not supported.
+///
+/// Examples where this function should be used include invalid inputs or
+/// options, but also environment error conditions outside LLVM's control.
+/// It should also be used for known unsupported/unimplemented functionality.
+///
+/// This will call installed error handlers (or print the message by default)
+/// and then exit with code 1. It will not produce a crash trace and will
+/// *not* ask users to report an LLVM bug.
+[[noreturn]] void reportFatalUsageError(const char *reason);
+[[noreturn]] void reportFatalUsageError(StringRef reason);
+[[noreturn]] void reportFatalUsageError(const Twine &reason);
+
 /// Installs a new bad alloc error handler that should be used whenever a
 /// bad alloc error, e.g. failing malloc/calloc, is encountered by LLVM.
 ///
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index dd9197efa7718..8a85ac835000a 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -195,7 +195,7 @@ static void RegisterPassPlugins(ArrayRef<std::string> PassPlugins,
   for (auto &PluginFN : PassPlugins) {
     auto PassPlugin = PassPlugin::Load(PluginFN);
     if (!PassPlugin)
-      report_fatal_error(PassPlugin.takeError(), /*gen_crash_diag=*/false);
+      reportFatalUsageError(PassPlugin.takeError());
     PassPlugin->registerPassBuilderCallbacks(PB);
   }
 }
diff --git a/llvm/lib/Support/Error.cpp b/llvm/lib/Support/Error.cpp
index baa3c322e9dae..d168b462a6eb2 100644
--- a/llvm/lib/Support/Error.cpp
+++ b/llvm/lib/Support/Error.cpp
@@ -174,6 +174,13 @@ void report_fatal_error(Error Err, bool GenCrashDiag) {
   report_fatal_error(Twine(ErrMsg), GenCrashDiag);
 }
 
+void reportFatalInternalError(Error Err) {
+  report_fatal_error(std::move(Err), /*GenCrashDiag=*/true);
+}
+void reportFatalUsageError(Error Err) {
+  report_fatal_error(std::move(Err), /*GenCrashDiag=*/false);
+}
+
 } // end namespace llvm
 
 LLVMErrorTypeId LLVMGetErrorTypeId(LLVMErrorRef Err) {
diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
index afe3b37cc3431..cc16f2037ea58 100644
--- a/llvm/lib/Support/ErrorHandling.cpp
+++ b/llvm/lib/Support/ErrorHandling.cpp
@@ -126,6 +126,25 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
     exit(1);
 }
 
+void llvm::reportFatalInternalError(const char *reason) {
+  report_fatal_error(reason, /*GenCrashDiag=*/true);
+}
+void llvm::reportFatalInternalError(StringRef reason) {
+  report_fatal_error(reason, /*GenCrashDiag=*/true);
+}
+void llvm::reportFatalInternalError(const Twine &reason) {
+  report_fatal_error(reason, /*GenCrashDiag=*/true);
+}
+void llvm::reportFatalUsageError(const char *reason) {
+  report_fatal_error(reason, /*GenCrashDiag=*/false);
+}
+void llvm::reportFatalUsageError(StringRef reason) {
+  report_fatal_error(reason, /*GenCrashDiag=*/false);
+}
+void llvm::reportFatalUsageError(const Twine &reason) {
+  report_fatal_error(reason, /*GenCrashDiag=*/false);
+}
+
 void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler,
                                            void *user_data) {
 #if LLVM_ENABLE_THREADS == 1
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index e75ddc66b7d16..16631a63d1921 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -678,9 +678,8 @@ raw_fd_ostream::~raw_fd_ostream() {
   // has_error() and clear the error flag with clear_error() before
   // destructing raw_ostream objects which may have errors.
   if (has_error())
-    report_fatal_error(Twine("IO failure on output stream: ") +
-                           error().message(),
-                       /*gen_crash_diag=*/false);
+    reportFatalUsageError(Twine("IO failure on output stream: ") +
+                          error().message());
 }
 
 #if defined(_WIN32)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index 800e2b9c0e657..5e684a7c46568 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -163,9 +163,8 @@ void AMDGPUAsmPrinter::emitFunctionBodyStart() {
 
   // TODO: We're checking this late, would be nice to check it earlier.
   if (STM.requiresCodeObjectV6() && CodeObjectVersion < AMDGPU::AMDHSA_COV6) {
-    report_fatal_error(
-        STM.getCPU() + " is only available on code object version 6 or better",
-        /*gen_crash_diag*/ false);
+    reportFatalUsageError(
+        STM.getCPU() + " is only available on code object version 6 or better");
   }
 
   // TODO: Which one is called first, emitStartOfAsmFile or
diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
index 8ec5ed0e22974..6e8dc64643778 100644
--- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
+++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
@@ -138,8 +138,7 @@ static Value *expandCrossIntrinsic(CallInst *Orig) {
 
   VectorType *VT = cast<VectorType>(Orig->getType());
   if (cast<FixedVectorType>(VT)->getNumElements() != 3)
-    report_fatal_error(Twine("return vector must have exactly 3 elements"),
-                       /* gen_crash_diag=*/false);
+    reportFatalUsageError("return vector must have exactly 3 elements");
 
   Value *op0 = Orig->getOperand(0);
   Value *op1 = Orig->getOperand(1);
@@ -197,9 +196,8 @@ static Value *expandFloatDotIntrinsic(CallInst *Orig, Value *A, Value *B) {
     DotIntrinsic = Intrinsic::dx_dot4;
     break;
   default:
-    report_fatal_error(
-        Twine("Invalid dot product input vector: length is outside 2-4"),
-        /* gen_crash_diag=*/false);
+    reportFatalUsageError(
+        "Invalid dot product input vector: length is outside 2-4");
     return nullptr;
   }
 
@@ -359,8 +357,7 @@ static Value *expandNormalizeIntrinsic(CallInst *Orig) {
     if (auto *constantFP = dyn_cast<ConstantFP>(X)) {
       const APFloat &fpVal = constantFP->getValueAPF();
       if (fpVal.isZero())
-        report_fatal_error(Twine("Invalid input scalar: length is zero"),
-                           /* gen_crash_diag=*/false);
+        reportFatalUsageError"Invalid input scalar: length is zero");
     }
     return Builder.CreateFDiv(X, X);
   }
@@ -372,8 +369,7 @@ static Value *expandNormalizeIntrinsic(CallInst *Orig) {
   if (auto *constantFP = dyn_cast<ConstantFP>(DotProduct)) {
     const APFloat &fpVal = constantFP->getValueAPF();
     if (fpVal.isZero())
-      report_fatal_error(Twine("Invalid input vector: length is zero"),
-                         /* gen_crash_diag=*/false);
+      reportFatalUsageError("Invalid input vector: length is zero");
   }
 
   Value *Multiplicand = Builder.CreateIntrinsic(EltTy, Intrinsic::dx_rsqrt,
diff --git a/llvm/lib/Target/DirectX/DXILOpBuilder.cpp b/llvm/lib/Target/DirectX/DXILOpBuilder.cpp
index c92475fee2141..1aed8f9867231 100644
--- a/llvm/lib/Target/DirectX/DXILOpBuilder.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpBuilder.cpp
@@ -478,10 +478,9 @@ DXILOpBuilder::DXILOpBuilder(Module &M) : M(M), IRB(M.getContext()) {
   ShaderStage = TT.getEnvironment();
   // Ensure Environment type is known
   if (ShaderStage == Triple::UnknownEnvironment) {
-    report_fatal_error(
+    reportFatalUsageError(
         Twine(DXILVersion.getAsString()) +
-            ": Unknown Compilation Target Shader Stage specified ",
-        /*gen_crash_diag*/ false);
+        ": Unknown Compilation Target Shader Stage specified ");
   }
 }
 
diff --git a/llvm/lib/Target/DirectX/DXILResourceAccess.cpp b/llvm/lib/Target/DirectX/DXILResourceAccess.cpp
index 16337f1237e00..566f3a98457a4 100644
--- a/llvm/lib/Target/DirectX/DXILResourceAccess.cpp
+++ b/llvm/lib/Target/DirectX/DXILResourceAccess.cpp
@@ -115,8 +115,7 @@ static void createStoreIntrinsic(IntrinsicInst *II, StoreInst *SI,
   case dxil::ResourceKind::TextureCubeArray:
   case dxil::ResourceKind::FeedbackTexture2D:
   case dxil::ResourceKind::FeedbackTexture2DArray:
-    report_fatal_error("DXIL Load not implemented yet",
-                       /*gen_crash_diag=*/false);
+    reportFatalUsageError("DXIL Load not implemented yet");
     return;
   case dxil::ResourceKind::CBuffer:
   case dxil::ResourceKind::Sampler:
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 1383302059910..1e2d752a02607 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -2486,8 +2486,7 @@ LoongArchTargetLowering::lowerGlobalTLSAddress(SDValue Op,
   assert(N->getOffset() == 0 && "unexpected offset in global node");
 
   if (DAG.getTarget().useEmulatedTLS())
-    report_fatal_error("the emulated TLS is prohibited",
-                       /*GenCrashDiag=*/false);
+    reportFatalUsageError("the emulated TLS is prohibited");
 
   bool IsDesc = DAG.getTarget().useTLSDESC();
 
@@ -7122,4 +7121,4 @@ LoongArchTargetLowering::getPreferredVectorAction(MVT VT) const {
     return TypeWidenVector;
 
   return TargetLoweringBase::getPreferredVectorAction(VT);
-}
\ No newline at end of file
+}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
index 6d2659aa1236e..d407beffcd7d1 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
@@ -52,11 +52,12 @@ namespace RISCV {
 } // namespace RISCV
 
 // Report an error but don't ask the user to report a bug.
+// TODO: Remove these wrappers.
 [[noreturn]] static void reportError(const char *Reason) {
-  report_fatal_error(Reason, /*gen_crash_diag=*/false);
+  reportFatalUsageError(Reason);
 }
 [[noreturn]] static void reportError(Error Err) {
-  report_fatal_error(std::move(Err), /*gen_crash_diag=*/false);
+  reportFatalUsageError(std::move(Err));
 }
 
 namespace RISCVABI {
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 0d3003b59eeba..86f8873c135ef 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21465,15 +21465,13 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
       report_fatal_error("'qci-*' interrupt kinds require Xqciint extension");
 
     if (Kind.starts_with("SiFive-CLIC-") && !Subtarget.hasVendorXSfmclic())
-      report_fatal_error(
-          "'SiFive-CLIC-*' interrupt kinds require XSfmclic extension",
-          /*gen_crash_diag=*/false);
+      reportFatalUsageError(
+          "'SiFive-CLIC-*' interrupt kinds require XSfmclic extension");
 
     const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
     if (Kind.starts_with("SiFive-CLIC-preemptible") && TFI->hasFP(MF))
-      report_fatal_error("'SiFive-CLIC-preemptible' interrupt kinds cannot "
-                         "have a frame pointer",
-                         /*gen_crash_diag=*/false);
+      reportFatalUsageError("'SiFive-CLIC-preemptible' interrupt kinds cannot "
+                            "have a frame pointer");
   }
 
   EVT PtrVT = getPointerTy(DAG.getDataLayout());
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 31b8ffe4099a7..88b1e44d15af0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -52,7 +52,7 @@ static unsigned typeToAddressSpace(const Type *Ty) {
   if (auto *ExtTy = dyn_cast<TargetExtType>(Ty);
       ExtTy && isTypedPointerWrapper(ExtTy))
     return ExtTy->getIntParameter(0);
-  report_fatal_error("Unable to convert LLVM type to SPIRVType", true);
+  reportFatalInternalError("Unable to convert LLVM type to SPIRVType");
 }
 
 #ifndef NDEBUG
diff --git a/llvm/lib/Transforms/IPO/BlockExtractor.cpp b/llvm/lib/Transforms/IPO/BlockExtractor.cpp
index ec1be35a33164..44913533030e3 100644
--- a/llvm/lib/Transforms/IPO/BlockExtractor.cpp
+++ b/llvm/lib/Transforms/IPO/BlockExtractor.cpp
@@ -80,8 +80,8 @@ void BlockExtractor::loadFile() {
     if (LineSplit.empty())
       continue;
     if (LineSplit.size()!=2)
-      report_fatal_error("Invalid line format, expecting lines like: 'funcname bb1[;bb2..]'",
-                         /*GenCrashDiag=*/false);
+      reportFatalUsageError(
+          "Invalid line format, expecting lines like: 'funcname bb1[;bb2..]'");
     SmallVector<StringRef, 4> BBNames;
     LineSplit[1].split(BBNames, ';', /*MaxSplit=*/-1,
                        /*KeepEmpty=*/false);
@@ -139,14 +139,13 @@ bool BlockExtractor::runOnModule(Module &M) {
   for (const auto &BInfo : BlocksByName) {
     Function *F = M.getFunction(BInfo.first);
     if (!F)
-      report_fatal_error("Invalid function name specified in the input file",
-                         /*GenCrashDiag=*/false);
+      reportFatalUsageError(
+          "Invalid function name specified in the input file");
     for (const auto &BBInfo : BInfo.second) {
       auto Res = llvm::find_if(
           *F, [&](const BasicBlock &BB) { return BB.getName() == BBInfo; });
       if (Res == F->end())
-        report_fatal_error("Invalid block name specified in the input file",
-                           /*GenCrashDiag=*/false);
+        reportFatalUsageError("Invalid block name specified in the input file");
       GroupsOfBlocks[NextGroupIdx].push_back(&*Res);
     }
     ++NextGroupIdx;
@@ -158,7 +157,7 @@ bool BlockExtractor::runOnModule(Module &M) {
     for (BasicBlock *BB : BBs) {
       // Check if the module contains BB.
       if (BB->getParent()->getParent() != &M)
-        report_fatal_error("Invalid basic block", /*GenCrashDiag=*/false);
+        reportFatalUsageError("Invalid basic block");
       LLVM_DEBUG(dbgs() << "BlockExtractor: Extracting "
                         << BB->getParent()->getName() << ":" << BB->getName()
                         << "\n");
diff --git a/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp b/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp
index 5950573173d74..73f567734a91b 100644
--- a/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp
+++ b/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp
@@ -24,14 +24,12 @@ using namespace llvm;
 
 PreservedAnalyses EmbedBitcodePass::run(Module &M, ModuleAnalysisManager &AM) {
   if (M.getGlobalVariable("llvm.embedded.module", /*AllowInternal=*/true))
-    report_fatal_error("Can only embed the module once",
-                       /*gen_crash_diag=*/false);
+    reportFatalUsageError("Can only embed the module once");
 
   Triple T(M.getTargetTriple());
   if (T.getObjectFormat() != Triple::ELF)
-    report_fatal_error(
-        "EmbedBitcode pass currently only supports ELF object format",
-        /*gen_crash_diag=*/false);
+    reportFatalUsageError(
+        "EmbedBitcode pass currently only supports ELF object format");
 
   std::string Data;
   raw_string_ostream OS(Data);
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index f807f5f4519fc..9b70e8e75d585 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -5647,13 +5647,12 @@ static bool combineInstructionsOverFunction(
 
     MadeIRChange = true;
     if (Iteration > Opts.MaxIterations) {
-      report_fatal_error(
+      reportFatalUsageError(
           "Instruction Combining on " + Twine(F.getName()) +
-              " did not reach a fixpoint after " + Twine(Opts.MaxIterations) +
-              " iterations. " +
-              "Use 'instcombine<no-verify-fixpoint>' or function attribute "
-              "'instcombine-no-verify-fixpoint' to suppress this error.",
-          /*GenCrashDiag=*/false);
+          " did not reach a fixpoint after " + Twine(Opts.MaxIterations) +
+          " iterations. " +
+          "Use 'instcombine<no-verify-fixpoint>' or function attribute "
+          "'instcombine-no-verify-fixpoint' to suppress this error.");
     }
   }
 
diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index 86c263f5b2154..9351a42581ba0 100644
--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -81,8 +81,8 @@ GCOVOptions GCOVOptions::getDefault() {
   Options.Atomic = AtomicCounter;
 
   if (DefaultGCOVVersion.size() != 4) {
-    llvm::report_fatal_error(Twine("Invalid -default-gcov-version: ") +
-                             DefaultGCOVVersion, /*GenCrashDiag=*/false);
+    reportFatalUsageError(Twine("Invalid -default-gcov-version: ") +
+                          DefaultGCOVVersion);
   }
   memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4);
   return Options;
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 889b43a843bef..42bccc858cdaa 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -296,8 +296,7 @@ struct LegacyLICMPass : public LoopPass {
 PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM,
                                 LoopStandardAnalysisResults &AR, LPMUpdater &) {
   if (!AR.MSSA)
-    report_fatal_error("LICM requires MemorySSA (loop-mssa)",
-                       /*GenCrashDiag*/false);
+    reportFatalUsageError("LICM requires MemorySSA (loop-mssa)");
 
   // For the new PM, we also can't use OptimizationRemarkEmitter as an analysis
   // pass.  Function analyses need to be preserved across loop transformations
@@ -330,8 +329,7 @@ PreservedAnalyses LNICMPass::run(LoopNest &LN, LoopAnalysisManager &AM,
                                  LoopStandardAnalysisResults &AR,
                                  LPMUpdater &) {
   if (!AR.MSSA)
-    report_fatal_error("LNICM requires MemorySSA (loop-mssa)",
-                       /*GenCrashDiag*/false);
+    reportFatalUsageError("LNICM requires MemorySSA (loop-mssa)");
 
   // For the new PM, we also can't use OptimizationRemarkEmitter as an analysis
   // pass.  Function analyses need to be preserved across loop transformations
diff --git a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
index 9f4270f5d62f5..e390fdfb81e7b 100644
--- a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
@@ -308,9 +308,8 @@ PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
       PI.runAfterPass<Loop>(*Pass, *L, PassPA);
 
     if (LAR.MSSA && !PassPA.getChecker<MemorySSAAnalysis>().preserved())
-      report_fatal_error("Loop pass manager using MemorySSA contains a pass "
-                         "that does not preserve MemorySSA",
-                         /*gen_crash_diag*/ false);
+      reportFatalUsageError("Loop pass manager using MemorySSA contains a pass "
+                            "that does not preserve MemorySSA");
 
 #ifndef NDEBUG
     // LoopAnalysisResults should always be valid.
diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
index d7080d6d76794..d84b74dd0eecc 100644
--- a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
@@ -946,8 +946,8 @@ bool llvm::computeUnrollCount(
   // case it's not permitted to also specify an explicit unroll count.
   if (PP.PeelCount) {
     if (UnrollCount.getNumOccurrences() > 0) {
-      report_fatal_error("Cannot specify both explicit peel count and "
-                         "explicit unroll count", /*GenCrashDiag=*/false);
+      reportFatalUsageError("Cannot specify both explicit peel count and "
+                            "explicit unroll count");
     }
     UP.Count = 1;
     UP.Runtime = false;
diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp
index 5ca4d883697f0..de46efa13025d 100644
--- a/llvm/tools/opt/optdriver.cpp
+++ b/llvm/tools/opt/optdriver.cpp
@@ -450,7 +450,7 @@ extern "C" int optMain(
   PassPlugins.setCallback([&](const std::string &PluginPath) {
     auto Plugin = PassPlugin::Load(PluginPath);
     if (!Plugin)
-      report_fatal_error(Plugin.takeError(), /*gen_crash_diag=*/false);
+      reportFatalUsageError(Plugin.takeError());
     PluginList.emplace_back(Plugin.get());
   });
 
diff --git a/mlir/lib/TableGen/AttrOrTypeDef.cpp b/mlir/lib/TableGen/AttrOrTypeDef.cpp
index ccb0a6c6c261e..596c96afc78d3 100644
--- a/mlir/lib/TableGen/AttrOrTypeDef.cpp
+++ b/mlir/lib/TableGen/AttrOrTypeDef.cpp
@@ -297,10 +297,9 @@ StringRef AttrOrTypeParameter::getCppType() const {
         init->getDef()->getLoc(),
         Twine("Missing `cppType` field in Attribute/Type parameter: ") +
             init->getAsString());
-  llvm::report_fatal_error(
+  llvm::reportFatalUsageError(
       Twine("Missing `cppType` field in Attribute/Type parameter: ") +
-          getDef()->getAsString(),
-      /*gen_crash_diag=*/false);
+      getDef()->getAsString());
 }
 
 StringRef AttrOrTypeParameter::getCppAccessorType() const {

>From d82279e198c20930aaf578828dd68fc0fb7edc69 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 2 May 2025 14:46:12 +0200
Subject: [PATCH 2/6] fix typo

---
 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
index 6e8dc64643778..b9ac09d8ed166 100644
--- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
+++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
@@ -357,7 +357,7 @@ static Value *expandNormalizeIntrinsic(CallInst *Orig) {
     if (auto *constantFP = dyn_cast<ConstantFP>(X)) {
       const APFloat &fpVal = constantFP->getValueAPF();
       if (fpVal.isZero())
-        reportFatalUsageError"Invalid input scalar: length is zero");
+        reportFatalUsageError("Invalid input scalar: length is zero");
     }
     return Builder.CreateFDiv(X, X);
   }

>From 88b9ef9c48bb69083cdfbb9ff0eaa8be1bd058a1 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 2 May 2025 14:50:05 +0200
Subject: [PATCH 3/6] Clarify that the "should" here is relative to
 reportFatalInternalError

---
 llvm/include/llvm/Support/ErrorHandling.h | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/Support/ErrorHandling.h b/llvm/include/llvm/Support/ErrorHandling.h
index 16a5fc8ad4092..6a6374c23497a 100644
--- a/llvm/include/llvm/Support/ErrorHandling.h
+++ b/llvm/include/llvm/Support/ErrorHandling.h
@@ -83,9 +83,10 @@ namespace llvm {
 /// where a more sophisticated error reporting mechanism (such as Error/Expected
 /// or DiagnosticInfo) is not supported.
 ///
-/// Examples where this function should be used include invalid inputs or
-/// options, but also environment error conditions outside LLVM's control.
-/// It should also be used for known unsupported/unimplemented functionality.
+/// Examples where this function should be used instead of
+/// reportFatalInternalError() include invalid inputs or options, but also
+/// environment error conditions outside LLVM's control. It should also be used
+/// for known unsupported/unimplemented functionality.
 ///
 /// This will call installed error handlers (or print the message by default)
 /// and then exit with code 1. It will not produce a crash trace and will

>From 0e9b468eb37c8554ba7923418f2676ca6406098f Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 2 May 2025 16:33:06 +0200
Subject: [PATCH 4/6] Further tweak wording

---
 llvm/include/llvm/Support/ErrorHandling.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/Support/ErrorHandling.h b/llvm/include/llvm/Support/ErrorHandling.h
index 6a6374c23497a..556f876648ce6 100644
--- a/llvm/include/llvm/Support/ErrorHandling.h
+++ b/llvm/include/llvm/Support/ErrorHandling.h
@@ -81,7 +81,8 @@ namespace llvm {
 
 /// Report a fatal error that does not indicate a bug in LLVM, in contexts
 /// where a more sophisticated error reporting mechanism (such as Error/Expected
-/// or DiagnosticInfo) is not supported.
+/// or DiagnosticInfo) is currently not supported, and would be too involved to
+/// introduce at the moment.
 ///
 /// Examples where this function should be used instead of
 /// reportFatalInternalError() include invalid inputs or options, but also

>From 032ca473aba0d07af05b7f317ec5b2ec3ba834fe Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 2 May 2025 16:47:19 +0200
Subject: [PATCH 5/6] more sophisticated -> proper

---
 llvm/include/llvm/Support/ErrorHandling.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/Support/ErrorHandling.h b/llvm/include/llvm/Support/ErrorHandling.h
index 556f876648ce6..b38171c5256f7 100644
--- a/llvm/include/llvm/Support/ErrorHandling.h
+++ b/llvm/include/llvm/Support/ErrorHandling.h
@@ -80,8 +80,8 @@ namespace llvm {
 [[noreturn]] void reportFatalInternalError(const Twine &reason);
 
 /// Report a fatal error that does not indicate a bug in LLVM, in contexts
-/// where a more sophisticated error reporting mechanism (such as Error/Expected
-/// or DiagnosticInfo) is currently not supported, and would be too involved to
+/// where a proper error reporting mechanism (such as Error/Expected or
+/// DiagnosticInfo) is currently not supported, and would be too involved to
 /// introduce at the moment.
 ///
 /// Examples where this function should be used instead of

>From b5798c7908f1dd17f1f45c65c5f605cea351f41c Mon Sep 17 00:00:00 2001
From: Nikita Popov <nikita.ppv at gmail.com>
Date: Fri, 2 May 2025 22:03:22 +0200
Subject: [PATCH 6/6] Break out a paragraph

---
 llvm/include/llvm/Support/ErrorHandling.h | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/Support/ErrorHandling.h b/llvm/include/llvm/Support/ErrorHandling.h
index b38171c5256f7..85daaee10458c 100644
--- a/llvm/include/llvm/Support/ErrorHandling.h
+++ b/llvm/include/llvm/Support/ErrorHandling.h
@@ -79,10 +79,11 @@ namespace llvm {
 [[noreturn]] void reportFatalInternalError(StringRef reason);
 [[noreturn]] void reportFatalInternalError(const Twine &reason);
 
-/// Report a fatal error that does not indicate a bug in LLVM, in contexts
-/// where a proper error reporting mechanism (such as Error/Expected or
-/// DiagnosticInfo) is currently not supported, and would be too involved to
-/// introduce at the moment.
+/// Report a fatal error that does not indicate a bug in LLVM.
+///
+/// This can be used in contexts where a proper error reporting mechanism
+/// (such as Error/Expected or DiagnosticInfo) is currently not supported, and
+/// would be too involved to introduce at the moment.
 ///
 /// Examples where this function should be used instead of
 /// reportFatalInternalError() include invalid inputs or options, but also



More information about the cfe-commits mailing list