[flang-commits] [flang] [flang] Check x86 CPU and issue diagnostics (PR #127950)

Eugene Epshteyn via flang-commits flang-commits at lists.llvm.org
Tue Feb 25 16:34:35 PST 2025


https://github.com/eugeneepshteyn updated https://github.com/llvm/llvm-project/pull/127950

>From d9bfa81314a9f5d134d000af578150eb827dcec9 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Tue, 18 Feb 2025 21:12:38 -0500
Subject: [PATCH 01/10] WIP

---
 flang/tools/flang-driver/fc1_main.cpp | 39 +++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/flang/tools/flang-driver/fc1_main.cpp b/flang/tools/flang-driver/fc1_main.cpp
index 561a0dd5524e3..4b51852c6146e 100644
--- a/flang/tools/flang-driver/fc1_main.cpp
+++ b/flang/tools/flang-driver/fc1_main.cpp
@@ -27,18 +27,28 @@
 #include "llvm/Option/OptTable.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/X86TargetParser.h"
 
 #include <cstdio>
 
 using namespace Fortran::frontend;
 
-/// Print supported cpus of the given target.
-static int printSupportedCPUs(llvm::StringRef triple) {
+/// Instantiate llvm::Target based on triple
+static const llvm::Target* getTarget(llvm::StringRef triple) {
   std::string error;
   const llvm::Target *target =
       llvm::TargetRegistry::lookupTarget(triple, error);
   if (!target) {
     llvm::errs() << error;
+  }
+
+  return target;
+}
+
+/// Print supported cpus of the given target.
+static int printSupportedCPUs(llvm::StringRef triple) {
+  const llvm::Target *target = getTarget(triple);
+  if (!target) {
     return 1;
   }
 
@@ -50,6 +60,27 @@ static int printSupportedCPUs(llvm::StringRef triple) {
   return 0;
 }
 
+/// Check that given CPU is valid for given target.
+static bool checkSupportedCPU(llvm::StringRef str_cpu, llvm::StringRef str_triple) {
+  // If can create tareg from triple, then it's a valid triple
+  const llvm::Target *target = getTarget(str_triple);
+  if (!target) {
+    return false;
+  }
+
+  // TODO: only support check for x86_64 for now
+  llvm::Triple triple{str_triple};
+  if (triple.getArch() == llvm::Triple::x86_64) {
+    const bool only64bit{true};
+    llvm::X86::CPUKind x86cpu = llvm::X86::parseArchX86(str_cpu, only64bit);
+    return x86cpu != llvm::X86::CK_None;
+  }
+  else {
+    // TODO: only support check for x86_64 for now. Anything else passes.
+    return true;
+  }
+}
+
 int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
   // Create CompilerInstance
   std::unique_ptr<CompilerInstance> flang(new CompilerInstance());
@@ -82,6 +113,10 @@ int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
   if (flang->getFrontendOpts().printSupportedCPUs)
     return printSupportedCPUs(flang->getInvocation().getTargetOpts().triple);
 
+  // Check that requested CPU can be properly supported
+  if (!checkSupportedCPU(flang->getInvocation().getTargetOpts().cpu, flang->getInvocation().getTargetOpts().triple))
+    return 1;
+
   diagsBuffer->flushDiagnostics(flang->getDiagnostics());
 
   if (!success)

>From 79442c339ff447c6e8e1eb526fc0f0ea02824ad4 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Tue, 18 Feb 2025 23:12:26 -0500
Subject: [PATCH 02/10] Try to not enable x86 CPU check for "-x cuda". This
 implementation didn't work.

---
 flang/tools/flang-driver/fc1_main.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/flang/tools/flang-driver/fc1_main.cpp b/flang/tools/flang-driver/fc1_main.cpp
index 4b51852c6146e..0ee3e83093c7c 100644
--- a/flang/tools/flang-driver/fc1_main.cpp
+++ b/flang/tools/flang-driver/fc1_main.cpp
@@ -113,9 +113,12 @@ int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
   if (flang->getFrontendOpts().printSupportedCPUs)
     return printSupportedCPUs(flang->getInvocation().getTargetOpts().triple);
 
-  // Check that requested CPU can be properly supported
-  if (!checkSupportedCPU(flang->getInvocation().getTargetOpts().cpu, flang->getInvocation().getTargetOpts().triple))
-    return 1;
+  // Check that requested CPU can be properly supported, but only if
+  // we didn't specify CUDA support
+  if (!flang->getInvocation().getFortranOpts().features.IsEnabled(Fortran::common::LanguageFeature::CUDA)) {
+    if (!checkSupportedCPU(flang->getInvocation().getTargetOpts().cpu, flang->getInvocation().getTargetOpts().triple))
+      return 1;
+  }
 
   diagsBuffer->flushDiagnostics(flang->getDiagnostics());
 

>From 696e8085453409fcbfc435aaf75f0ea64e9ecd86 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Tue, 18 Feb 2025 23:57:01 -0500
Subject: [PATCH 03/10] New attempt, still doesn't work

---
 flang/tools/flang-driver/fc1_main.cpp | 35 +++++++++++++--------------
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/flang/tools/flang-driver/fc1_main.cpp b/flang/tools/flang-driver/fc1_main.cpp
index 0ee3e83093c7c..789b2e621456d 100644
--- a/flang/tools/flang-driver/fc1_main.cpp
+++ b/flang/tools/flang-driver/fc1_main.cpp
@@ -28,6 +28,7 @@
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/X86TargetParser.h"
+#include "llvm/ADT/StringExtras.h"
 
 #include <cstdio>
 
@@ -61,24 +62,25 @@ static int printSupportedCPUs(llvm::StringRef triple) {
 }
 
 /// Check that given CPU is valid for given target.
-static bool checkSupportedCPU(llvm::StringRef str_cpu, llvm::StringRef str_triple) {
-  // If can create tareg from triple, then it's a valid triple
-  const llvm::Target *target = getTarget(str_triple);
-  if (!target) {
-    return false;
-  }
+static bool checkSupportedCPU(clang::DiagnosticsEngine& diags, llvm::StringRef str_cpu, llvm::StringRef str_triple) {
 
-  // TODO: only support check for x86_64 for now
   llvm::Triple triple{str_triple};
   if (triple.getArch() == llvm::Triple::x86_64) {
     const bool only64bit{true};
     llvm::X86::CPUKind x86cpu = llvm::X86::parseArchX86(str_cpu, only64bit);
-    return x86cpu != llvm::X86::CK_None;
-  }
-  else {
-    // TODO: only support check for x86_64 for now. Anything else passes.
-    return true;
+    if (x86cpu == llvm::X86::CK_None) {
+      diags.Report(clang::diag::err_target_unknown_cpu) << str_cpu;
+      llvm::SmallVector<llvm::StringRef, 32> validList;
+      llvm::X86::fillValidCPUArchList(validList, only64bit);
+      if (!validList.empty())
+        diags.Report(clang::diag::note_valid_options) << llvm::join(validList, ", ");
+
+      return false;
+    }
   }
+
+  // TODO: only support check for x86_64 for now. Anything else passes.
+  return true;
 }
 
 int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
@@ -113,12 +115,9 @@ int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
   if (flang->getFrontendOpts().printSupportedCPUs)
     return printSupportedCPUs(flang->getInvocation().getTargetOpts().triple);
 
-  // Check that requested CPU can be properly supported, but only if
-  // we didn't specify CUDA support
-  if (!flang->getInvocation().getFortranOpts().features.IsEnabled(Fortran::common::LanguageFeature::CUDA)) {
-    if (!checkSupportedCPU(flang->getInvocation().getTargetOpts().cpu, flang->getInvocation().getTargetOpts().triple))
-      return 1;
-  }
+  // Check that requested CPU can be properly supported
+  if (!checkSupportedCPU(diags, flang->getInvocation().getTargetOpts().cpu, flang->getInvocation().getTargetOpts().triple))
+    return 1;
 
   diagsBuffer->flushDiagnostics(flang->getDiagnostics());
 

>From e1a112e211c880cea1916f43642697f7b2bf6526 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 19 Feb 2025 21:47:14 -0500
Subject: [PATCH 04/10] Reverted printSupportedCPUs() to original. Added debug
 code. Added work-around for empty CPU string. Works now, but has debug code.

---
 flang/tools/flang-driver/fc1_main.cpp | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/flang/tools/flang-driver/fc1_main.cpp b/flang/tools/flang-driver/fc1_main.cpp
index 789b2e621456d..e519b4f3316cf 100644
--- a/flang/tools/flang-driver/fc1_main.cpp
+++ b/flang/tools/flang-driver/fc1_main.cpp
@@ -34,8 +34,8 @@
 
 using namespace Fortran::frontend;
 
-/// Instantiate llvm::Target based on triple
-static const llvm::Target* getTarget(llvm::StringRef triple) {
+/// Print supported cpus of the given target.
+static int printSupportedCPUs(llvm::StringRef triple) {
   std::string error;
   const llvm::Target *target =
       llvm::TargetRegistry::lookupTarget(triple, error);
@@ -43,16 +43,6 @@ static const llvm::Target* getTarget(llvm::StringRef triple) {
     llvm::errs() << error;
   }
 
-  return target;
-}
-
-/// Print supported cpus of the given target.
-static int printSupportedCPUs(llvm::StringRef triple) {
-  const llvm::Target *target = getTarget(triple);
-  if (!target) {
-    return 1;
-  }
-
   // the target machine will handle the mcpu printing
   llvm::TargetOptions targetOpts;
   std::unique_ptr<llvm::TargetMachine> targetMachine(
@@ -64,8 +54,9 @@ static int printSupportedCPUs(llvm::StringRef triple) {
 /// Check that given CPU is valid for given target.
 static bool checkSupportedCPU(clang::DiagnosticsEngine& diags, llvm::StringRef str_cpu, llvm::StringRef str_triple) {
 
+  llvm::errs() << "EE str_cpu = '" << str_cpu << "', str_triple = '" << str_triple << "'\n";
   llvm::Triple triple{str_triple};
-  if (triple.getArch() == llvm::Triple::x86_64) {
+  if (triple.getArch() == llvm::Triple::x86_64 && !str_cpu.empty()) {
     const bool only64bit{true};
     llvm::X86::CPUKind x86cpu = llvm::X86::parseArchX86(str_cpu, only64bit);
     if (x86cpu == llvm::X86::CK_None) {
@@ -92,6 +83,12 @@ int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
   if (!flang->hasDiagnostics())
     return 1;
 
+  llvm::errs() << "EE args: ";
+  for (auto arg : argv) {
+    llvm::errs() << "\"" << arg << "\" ";
+  }
+  llvm::errs() << "\n";
+
   // We will buffer diagnostics from argument parsing so that we can output
   // them using a well formed diagnostic object.
   TextDiagnosticBuffer *diagsBuffer = new TextDiagnosticBuffer;
@@ -116,8 +113,8 @@ int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
     return printSupportedCPUs(flang->getInvocation().getTargetOpts().triple);
 
   // Check that requested CPU can be properly supported
-  if (!checkSupportedCPU(diags, flang->getInvocation().getTargetOpts().cpu, flang->getInvocation().getTargetOpts().triple))
-    return 1;
+  success = success &&
+    checkSupportedCPU(diags, flang->getInvocation().getTargetOpts().cpu, flang->getInvocation().getTargetOpts().triple);
 
   diagsBuffer->flushDiagnostics(flang->getDiagnostics());
 

>From d56f63b18d0ab26fe5be046ca3404b6b3853f646 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 19 Feb 2025 22:01:02 -0500
Subject: [PATCH 05/10] Removed debug code, updated comments

---
 flang/tools/flang-driver/fc1_main.cpp | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/flang/tools/flang-driver/fc1_main.cpp b/flang/tools/flang-driver/fc1_main.cpp
index e519b4f3316cf..0d51362845fce 100644
--- a/flang/tools/flang-driver/fc1_main.cpp
+++ b/flang/tools/flang-driver/fc1_main.cpp
@@ -54,10 +54,12 @@ static int printSupportedCPUs(llvm::StringRef triple) {
 /// Check that given CPU is valid for given target.
 static bool checkSupportedCPU(clang::DiagnosticsEngine& diags, llvm::StringRef str_cpu, llvm::StringRef str_triple) {
 
-  llvm::errs() << "EE str_cpu = '" << str_cpu << "', str_triple = '" << str_triple << "'\n";
   llvm::Triple triple{str_triple};
+
+  // Need to check for empty CPU string, because it can be empty for some
+  // cases, e.g., "-x cuda" compilation.
   if (triple.getArch() == llvm::Triple::x86_64 && !str_cpu.empty()) {
-    const bool only64bit{true};
+    constexpr bool only64bit{true};
     llvm::X86::CPUKind x86cpu = llvm::X86::parseArchX86(str_cpu, only64bit);
     if (x86cpu == llvm::X86::CK_None) {
       diags.Report(clang::diag::err_target_unknown_cpu) << str_cpu;
@@ -70,7 +72,8 @@ static bool checkSupportedCPU(clang::DiagnosticsEngine& diags, llvm::StringRef s
     }
   }
 
-  // TODO: only support check for x86_64 for now. Anything else passes.
+  // TODO: only support check for x86_64 for now. Anything else is considered
+  // as "supported".
   return true;
 }
 
@@ -83,12 +86,6 @@ int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
   if (!flang->hasDiagnostics())
     return 1;
 
-  llvm::errs() << "EE args: ";
-  for (auto arg : argv) {
-    llvm::errs() << "\"" << arg << "\" ";
-  }
-  llvm::errs() << "\n";
-
   // We will buffer diagnostics from argument parsing so that we can output
   // them using a well formed diagnostic object.
   TextDiagnosticBuffer *diagsBuffer = new TextDiagnosticBuffer;

>From b432279a6c587257a76c44fee2e57d66312990e2 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 19 Feb 2025 22:04:02 -0500
Subject: [PATCH 06/10] Reformatted

---
 flang/tools/flang-driver/fc1_main.cpp | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/flang/tools/flang-driver/fc1_main.cpp b/flang/tools/flang-driver/fc1_main.cpp
index 0d51362845fce..601f10f30b76a 100644
--- a/flang/tools/flang-driver/fc1_main.cpp
+++ b/flang/tools/flang-driver/fc1_main.cpp
@@ -52,7 +52,9 @@ static int printSupportedCPUs(llvm::StringRef triple) {
 }
 
 /// Check that given CPU is valid for given target.
-static bool checkSupportedCPU(clang::DiagnosticsEngine& diags, llvm::StringRef str_cpu, llvm::StringRef str_triple) {
+static bool checkSupportedCPU(
+  clang::DiagnosticsEngine& diags,
+  llvm::StringRef str_cpu, llvm::StringRef str_triple) {
 
   llvm::Triple triple{str_triple};
 
@@ -66,7 +68,8 @@ static bool checkSupportedCPU(clang::DiagnosticsEngine& diags, llvm::StringRef s
       llvm::SmallVector<llvm::StringRef, 32> validList;
       llvm::X86::fillValidCPUArchList(validList, only64bit);
       if (!validList.empty())
-        diags.Report(clang::diag::note_valid_options) << llvm::join(validList, ", ");
+        diags.Report(clang::diag::note_valid_options)
+          << llvm::join(validList, ", ");
 
       return false;
     }
@@ -111,7 +114,10 @@ int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
 
   // Check that requested CPU can be properly supported
   success = success &&
-    checkSupportedCPU(diags, flang->getInvocation().getTargetOpts().cpu, flang->getInvocation().getTargetOpts().triple);
+    checkSupportedCPU(
+      diags,
+      flang->getInvocation().getTargetOpts().cpu,
+      flang->getInvocation().getTargetOpts().triple);
 
   diagsBuffer->flushDiagnostics(flang->getDiagnostics());
 

>From 313a8972632e05cf27c6d2bed059f8833dde1325 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 19 Feb 2025 22:04:41 -0500
Subject: [PATCH 07/10] clang-format

---
 flang/tools/flang-driver/fc1_main.cpp | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/flang/tools/flang-driver/fc1_main.cpp b/flang/tools/flang-driver/fc1_main.cpp
index 601f10f30b76a..ce430ee30ca87 100644
--- a/flang/tools/flang-driver/fc1_main.cpp
+++ b/flang/tools/flang-driver/fc1_main.cpp
@@ -52,9 +52,9 @@ static int printSupportedCPUs(llvm::StringRef triple) {
 }
 
 /// Check that given CPU is valid for given target.
-static bool checkSupportedCPU(
-  clang::DiagnosticsEngine& diags,
-  llvm::StringRef str_cpu, llvm::StringRef str_triple) {
+static bool checkSupportedCPU(clang::DiagnosticsEngine &diags,
+                              llvm::StringRef str_cpu,
+                              llvm::StringRef str_triple) {
 
   llvm::Triple triple{str_triple};
 
@@ -69,7 +69,7 @@ static bool checkSupportedCPU(
       llvm::X86::fillValidCPUArchList(validList, only64bit);
       if (!validList.empty())
         diags.Report(clang::diag::note_valid_options)
-          << llvm::join(validList, ", ");
+            << llvm::join(validList, ", ");
 
       return false;
     }
@@ -114,10 +114,8 @@ int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
 
   // Check that requested CPU can be properly supported
   success = success &&
-    checkSupportedCPU(
-      diags,
-      flang->getInvocation().getTargetOpts().cpu,
-      flang->getInvocation().getTargetOpts().triple);
+            checkSupportedCPU(diags, flang->getInvocation().getTargetOpts().cpu,
+                              flang->getInvocation().getTargetOpts().triple);
 
   diagsBuffer->flushDiagnostics(flang->getDiagnostics());
 

>From 542648164c9cd217b2bb161cf871cfe6c1e737a6 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 19 Feb 2025 22:24:50 -0500
Subject: [PATCH 08/10] Fixed artifact of attempted refactoring

---
 flang/tools/flang-driver/fc1_main.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/flang/tools/flang-driver/fc1_main.cpp b/flang/tools/flang-driver/fc1_main.cpp
index ce430ee30ca87..bf7c795f137df 100644
--- a/flang/tools/flang-driver/fc1_main.cpp
+++ b/flang/tools/flang-driver/fc1_main.cpp
@@ -41,6 +41,7 @@ static int printSupportedCPUs(llvm::StringRef triple) {
       llvm::TargetRegistry::lookupTarget(triple, error);
   if (!target) {
     llvm::errs() << error;
+    return 1;
   }
 
   // the target machine will handle the mcpu printing

>From 43a54b895491afe30cd1c5ca5857d6a27336abca Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 19 Feb 2025 22:34:45 -0500
Subject: [PATCH 09/10] Formatter fix

---
 flang/tools/flang-driver/fc1_main.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/tools/flang-driver/fc1_main.cpp b/flang/tools/flang-driver/fc1_main.cpp
index bf7c795f137df..208420840d6ed 100644
--- a/flang/tools/flang-driver/fc1_main.cpp
+++ b/flang/tools/flang-driver/fc1_main.cpp
@@ -21,6 +21,7 @@
 #include "flang/Frontend/TextDiagnosticBuffer.h"
 #include "flang/FrontendTool/Utils.h"
 #include "clang/Driver/DriverDiagnostic.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
@@ -28,7 +29,6 @@
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/X86TargetParser.h"
-#include "llvm/ADT/StringExtras.h"
 
 #include <cstdio>
 

>From 8089143daf784b72037a8bb3eae4d490e24430c6 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 20 Feb 2025 10:58:53 -0500
Subject: [PATCH 10/10] LIT test

---
 flang/test/Driver/target-cpu-invalid-x86.f90 | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 flang/test/Driver/target-cpu-invalid-x86.f90

diff --git a/flang/test/Driver/target-cpu-invalid-x86.f90 b/flang/test/Driver/target-cpu-invalid-x86.f90
new file mode 100644
index 0000000000000..d62b5322e99db
--- /dev/null
+++ b/flang/test/Driver/target-cpu-invalid-x86.f90
@@ -0,0 +1,7 @@
+! Test that invalid cpu is rejected.
+
+! REQUIRES: x86-registered-target
+
+! RUN: not %flang_fc1 -triple x86_64-unknown-linux-gnu -target-cpu not_valid_cpu -o - -S %s 2>&1 | FileCheck %s
+
+! CHECK: error: unknown target CPU 'not_valid_cpu'



More information about the flang-commits mailing list