[Flang] Exit gracefully with a useful message when we fail to lookup a target
authorNadeem, Usman <mnadeem@quicinc.com>
Mon, 20 Mar 2023 19:05:18 +0000 (12:05 -0700)
committerNadeem, Usman <mnadeem@quicinc.com>
Mon, 20 Mar 2023 19:08:34 +0000 (12:08 -0700)
Without this patch we were asserting with a generic message `Failed to
create Target`, but we already have a detailed error message stored in
the variable `error` after calling `lookupTarget()` but this error was not
getting used/printed.

With this patch we will emit a message with more details instead of a
stack dump with a generic message.

Differential Revision: https://reviews.llvm.org/D146333

Change-Id: I7ddee917cf921a2133ca3e6b35791b2142f770a2

flang/include/flang/Frontend/FrontendActions.h
flang/lib/Frontend/FrontendActions.cpp
flang/test/Driver/target-machine-error.f90 [new file with mode: 0644]

index 7a5042b..2b96125 100644 (file)
@@ -204,7 +204,7 @@ class CodeGenAction : public FrontendAction {
   /// Runs prescan, parsing, sema and lowers to MLIR.
   bool beginSourceFileAction() override;
   /// Sets up LLVM's TargetMachine.
-  void setUpTargetMachine();
+  bool setUpTargetMachine();
   /// Runs the optimization (aka middle-end) pipeline on the LLVM module
   /// associated with this action.
   void runOptimizationPipeline(llvm::raw_pwrite_stream &os);
index 64cabd8..b723fe8 100644 (file)
@@ -143,7 +143,8 @@ bool CodeGenAction::beginSourceFileAction() {
     }
 
     mlirModule = std::make_unique<mlir::ModuleOp>(module.release());
-    setUpTargetMachine();
+    if (!setUpTargetMachine())
+      return false;
     const llvm::DataLayout &dl = tm->createDataLayout();
     setMLIRDataLayout(*mlirModule, dl);
     return true;
@@ -184,7 +185,8 @@ bool CodeGenAction::beginSourceFileAction() {
         *mlirModule, ci.getInvocation().getLangOpts().OpenMPIsDevice);
   }
 
-  setUpTargetMachine();
+  if (!setUpTargetMachine())
+    return false;
   const llvm::DataLayout &dl = tm->createDataLayout();
   setMLIRDataLayout(*mlirModule, dl);
 
@@ -585,7 +587,7 @@ void CodeGenAction::generateLLVMIR() {
 
 }
 
-void CodeGenAction::setUpTargetMachine() {
+bool CodeGenAction::setUpTargetMachine() {
   CompilerInstance &ci = this->getInstance();
 
   const TargetOptions &targetOpts = ci.getInvocation().getTargetOpts();
@@ -595,7 +597,11 @@ void CodeGenAction::setUpTargetMachine() {
   std::string error;
   const llvm::Target *theTarget =
       llvm::TargetRegistry::lookupTarget(theTriple, error);
-  assert(theTarget && "Failed to create Target");
+  if (!theTarget) {
+    ci.getDiagnostics().Report(clang::diag::err_fe_unable_to_create_target)
+        << error;
+    return false;
+  }
 
   // Create `TargetMachine`
   const auto &CGOpts = ci.getInvocation().getCodeGenOpts();
@@ -611,6 +617,7 @@ void CodeGenAction::setUpTargetMachine() {
       /*Reloc::Model=*/CGOpts.getRelocationModel(),
       /*CodeModel::Model=*/std::nullopt, OptLevel));
   assert(tm && "Failed to create TargetMachine");
+  return true;
 }
 
 static std::unique_ptr<llvm::raw_pwrite_stream>
@@ -799,7 +806,8 @@ void CodeGenAction::executeAction() {
   // Set the triple based on the targetmachine (this comes compiler invocation
   // and the command-line target option if specified, or the default if not
   // given on the command-line).
-  setUpTargetMachine();
+  if (!setUpTargetMachine())
+    return;
   const std::string &theTriple = tm->getTargetTriple().str();
 
   if (llvmModule->getTargetTriple() != theTriple) {
diff --git a/flang/test/Driver/target-machine-error.f90 b/flang/test/Driver/target-machine-error.f90
new file mode 100644 (file)
index 0000000..8f6522d
--- /dev/null
@@ -0,0 +1,6 @@
+! RUN: not %flang  --target=some-invalid-triple -S  %s -o \
+! RUN:   /dev/null 2>&1 | FileCheck %s
+! RUN: not %flang_fc1 -triple some-invalid-triple -S %s -o \
+! RUN:   /dev/null 2>&1 | FileCheck %s
+
+! CHECK: error: unable to create target: 'No available targets are compatible with triple "some-invalid-triple"'