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' diff --git a/flang/tools/flang-driver/fc1_main.cpp b/flang/tools/flang-driver/fc1_main.cpp index 561a0dd5524e3..208420840d6ed 100644 --- a/flang/tools/flang-driver/fc1_main.cpp +++ b/flang/tools/flang-driver/fc1_main.cpp @@ -21,12 +21,14 @@ #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" #include "llvm/Option/OptTable.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/X86TargetParser.h" #include @@ -50,6 +52,35 @@ static int printSupportedCPUs(llvm::StringRef triple) { return 0; } +/// Check that given CPU is valid for given target. +static bool checkSupportedCPU(clang::DiagnosticsEngine &diags, + llvm::StringRef str_cpu, + llvm::StringRef str_triple) { + + 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()) { + 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; + llvm::SmallVector 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 is considered + // as "supported". + return true; +} + int fc1_main(llvm::ArrayRef argv, const char *argv0) { // Create CompilerInstance std::unique_ptr flang(new CompilerInstance()); @@ -82,6 +113,11 @@ int fc1_main(llvm::ArrayRef argv, const char *argv0) { if (flang->getFrontendOpts().printSupportedCPUs) return printSupportedCPUs(flang->getInvocation().getTargetOpts().triple); + // Check that requested CPU can be properly supported + success = success && + checkSupportedCPU(diags, flang->getInvocation().getTargetOpts().cpu, + flang->getInvocation().getTargetOpts().triple); + diagsBuffer->flushDiagnostics(flang->getDiagnostics()); if (!success)