diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -19,11 +19,13 @@ #include "clang/Driver/Options.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Triple.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" +#include "llvm/Support/Host.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" @@ -93,7 +95,9 @@ /// \param [in] opts The target options instance to update /// \param [in] args The list of input arguments (from the compiler invocation) static void ParseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) { - opts.triple = args.getLastArgValue(clang::driver::options::OPT_triple); + if (const llvm::opt::Arg *a = + args.getLastArg(clang::driver::options::OPT_triple)) + opts.triple = a->getValue(); } // Tweak the frontend configuration based on the frontend action @@ -559,6 +563,15 @@ bool success = true; + // Set the default triple for this CompilerInvocation. This might be + // overridden by users with `-triple` (see the call to `ParseTargetArgs` + // below). + // NOTE: Like in Clang, it would be nice to use option marshalling + // for this so that the entire logic for setting-up the triple is in one + // place. + res.targetOpts().triple = + llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()); + // Parse the arguments const llvm::opt::OptTable &opts = clang::driver::getDriverOptTable(); const unsigned includedFlagsBitmask = clang::driver::options::FC1Option; diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -30,6 +30,7 @@ #include "mlir/IR/Dialect.h" #include "mlir/Pass/PassManager.h" #include "mlir/Target/LLVMIR/ModuleTranslation.h" +#include "clang/Basic/DiagnosticFrontend.h" #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" @@ -481,9 +482,15 @@ if (!llvmModule) GenerateLLVMIR(); - // Create and configure `Target` + // Set the triple based on the CompilerInvocation set-up + const std::string &theTriple = ci.invocation().targetOpts().triple; + if (llvmModule->getTargetTriple() != theTriple) { + ci.diagnostics().Report(clang::diag::warn_fe_override_module) << theTriple; + llvmModule->setTargetTriple(theTriple); + } + + // Create `Target` std::string error; - std::string theTriple = llvmModule->getTargetTriple(); const llvm::Target *theTarget = llvm::TargetRegistry::lookupTarget(theTriple, error); assert(theTarget && "Failed to create Target"); @@ -546,13 +553,17 @@ if (!llvmModule) GenerateLLVMIR(); + // Set the triple based on the CompilerInvocation set-up + const std::string &theTriple = ci.invocation().targetOpts().triple; + if (llvmModule->getTargetTriple() != theTriple) { + ci.diagnostics().Report(clang::diag::warn_fe_override_module) << theTriple; + llvmModule->setTargetTriple(theTriple); + } + // Create `Target` std::string error; - const std::string &theTriple = llvmModule->getTargetTriple(); const llvm::Target *theTarget = llvm::TargetRegistry::lookupTarget(theTriple, error); - // TODO: Make this a diagnostic once `flang-new` can consume LLVM IR files - // (in which users could use unsupported triples) assert(theTarget && "Failed to create Target"); // Create `TargetMachine` diff --git a/flang/unittests/Frontend/FrontendActionTest.cpp b/flang/unittests/Frontend/FrontendActionTest.cpp --- a/flang/unittests/Frontend/FrontendActionTest.cpp +++ b/flang/unittests/Frontend/FrontendActionTest.cpp @@ -10,7 +10,9 @@ #include "flang/Frontend/CompilerInvocation.h" #include "flang/Frontend/FrontendOptions.h" #include "flang/FrontendTool/Utils.h" +#include "llvm/ADT/Triple.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Host.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" @@ -170,7 +172,10 @@ // Set-up the action kind. compInst_.invocation().frontendOpts().programAction = EmitLLVM; - compInst_.invocation().preprocessorOpts().noReformat = true; + + // Set-up default target triple. + compInst_.invocation().targetOpts().triple = + llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()); // Set-up the output stream. We are using output buffer wrapped as an output // stream, as opposed to an actual file (or a file descriptor). @@ -197,7 +202,10 @@ // Set-up the action kind. compInst_.invocation().frontendOpts().programAction = EmitAssembly; - compInst_.invocation().preprocessorOpts().noReformat = true; + + // Set-up default target triple. + compInst_.invocation().targetOpts().triple = + llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()); // Initialise LLVM backend llvm::InitializeAllTargets();