aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
Diffstat (limited to 'flang')
-rw-r--r--flang/include/flang/Frontend/TargetOptions.h16
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp8
-rw-r--r--flang/lib/Frontend/FrontendActions.cpp9
-rw-r--r--flang/test/Driver/driver-help.f902
-rw-r--r--flang/test/Driver/target-cpu-features.f9056
5 files changed, 80 insertions, 11 deletions
diff --git a/flang/include/flang/Frontend/TargetOptions.h b/flang/include/flang/Frontend/TargetOptions.h
index 84371be..170509f 100644
--- a/flang/include/flang/Frontend/TargetOptions.h
+++ b/flang/include/flang/Frontend/TargetOptions.h
@@ -22,18 +22,18 @@
namespace Fortran::frontend {
-/// Options for controlling the target. Currently this is just a placeholder.
-/// In the future, we will use this to specify various target options that
-/// will affect the generated code e.g.:
-/// * CPU to tune the code for
-/// * available CPU/hardware extensions
-/// * target specific features to enable/disable
-/// * options for accelerators (e.g. GPUs)
-/// * (...)
+/// Options for controlling the target.
class TargetOptions {
public:
/// The name of the target triple to compile for.
std::string triple;
+
+ /// If given, the name of the target CPU to generate code for.
+ std::string cpu;
+
+ /// The list of target specific features to enable or disable, as written on
+ /// the command line.
+ std::vector<std::string> featuresAsWritten;
};
} // end namespace Fortran::frontend
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index b8f4ad7..e24d816 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -171,6 +171,14 @@ static void parseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) {
if (const llvm::opt::Arg *a =
args.getLastArg(clang::driver::options::OPT_triple))
opts.triple = a->getValue();
+
+ if (const llvm::opt::Arg *a =
+ args.getLastArg(clang::driver::options::OPT_target_cpu))
+ opts.cpu = a->getValue();
+
+ for (const llvm::opt::Arg *currentArg :
+ args.filtered(clang::driver::options::OPT_target_feature))
+ opts.featuresAsWritten.emplace_back(currentArg->getValue());
}
// Tweak the frontend configuration based on the frontend action
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 990cb76..82d472dd8 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -591,7 +591,8 @@ getCGOptLevel(const Fortran::frontend::CodeGenOptions &opts) {
void CodeGenAction::setUpTargetMachine() {
CompilerInstance &ci = this->getInstance();
- const std::string &theTriple = ci.getInvocation().getTargetOpts().triple;
+ const TargetOptions &targetOpts = ci.getInvocation().getTargetOpts();
+ const std::string &theTriple = targetOpts.triple;
// Create `Target`
std::string error;
@@ -602,9 +603,11 @@ void CodeGenAction::setUpTargetMachine() {
// Create `TargetMachine`
const auto &CGOpts = ci.getInvocation().getCodeGenOpts();
llvm::CodeGenOpt::Level OptLevel = getCGOptLevel(CGOpts);
+ std::string featuresStr = llvm::join(targetOpts.featuresAsWritten.begin(),
+ targetOpts.featuresAsWritten.end(), ",");
tm.reset(theTarget->createTargetMachine(
- theTriple, /*CPU=*/"",
- /*Features=*/"", llvm::TargetOptions(),
+ theTriple, /*CPU=*/targetOpts.cpu,
+ /*Features=*/featuresStr, llvm::TargetOptions(),
/*Reloc::Model=*/CGOpts.getRelocationModel(),
/*CodeModel::Model=*/llvm::None, OptLevel));
assert(tm && "Failed to create TargetMachine");
diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90
index 4f04b85..d54ed7b 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -156,6 +156,8 @@
! HELP-FC1-NEXT: -P Disable linemarker output in -E mode
! HELP-FC1-NEXT: -std=<value> Language standard to compile for
! HELP-FC1-NEXT: -S Only run preprocess and compilation steps
+! HELP-FC1-NEXT: -target-cpu <value> Target a specific cpu type
+! HELP-FC1-NEXT: -target-feature <value> Target specific attributes
! HELP-FC1-NEXT: -test-io Run the InputOuputTest action. Use for development and testing only.
! HELP-FC1-NEXT: -triple <value> Specify target triple (e.g. i686-apple-darwin9)
! HELP-FC1-NEXT: -U <macro> Undefine macro <macro>
diff --git a/flang/test/Driver/target-cpu-features.f90 b/flang/test/Driver/target-cpu-features.f90
new file mode 100644
index 0000000..985a13d
--- /dev/null
+++ b/flang/test/Driver/target-cpu-features.f90
@@ -0,0 +1,56 @@
+! REQUIRES: aarch64-registered-target, x86-registered-target
+
+! Test that -mcpu/march are used and that the -target-cpu and -target-features
+! are also added to the fc1 command.
+
+! RUN: %flang --target=aarch64-linux-gnu -mcpu=cortex-a57 -c %s -### 2>&1 \
+! RUN: | FileCheck %s -check-prefix=CHECK-A57
+
+! RUN: %flang --target=aarch64-linux-gnu -mcpu=cortex-a76 -c %s -### 2>&1 \
+! RUN: | FileCheck %s -check-prefix=CHECK-A76
+
+! RUN: %flang --target=aarch64-linux-gnu -march=armv9 -c %s -### 2>&1 \
+! RUN: | FileCheck %s -check-prefix=CHECK-ARMV9
+
+! Negative test. ARM cpu with x86 target.
+! RUN: %flang --target=x86_64-linux-gnu -mcpu=cortex-a57 -c %s -### 2>&1 \
+! RUN: | FileCheck %s -check-prefix=CHECK-NO-A57
+
+! RUN: %flang --target=x86_64-linux-gnu -march=skylake -c %s -### 2>&1 \
+! RUN: | FileCheck %s -check-prefix=CHECK-SKYLAKE
+
+! RUN: %flang --target=x86_64h-linux-gnu -c %s -### 2>&1 \
+! RUN: | FileCheck %s -check-prefix=CHECK-X86_64H
+
+
+! Test that invalid cpu and features are ignored.
+
+! RUN: %flang_fc1 -triple aarch64-linux-gnu -target-cpu supercpu \
+! RUN: -o /dev/null -S %s 2>&1 | FileCheck %s -check-prefix=CHECK-INVALID-CPU
+
+! RUN: %flang_fc1 -triple aarch64-linux-gnu -target-feature +superspeed \
+! RUN: -o /dev/null -S %s 2>&1 | FileCheck %s -check-prefix=CHECK-INVALID-FEATURE
+
+
+! CHECK-A57: "-fc1" "-triple" "aarch64-unknown-linux-gnu"
+! CHECK-A57-SAME: "-target-cpu" "cortex-a57" "-target-feature" "+v8a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+sha2" "-target-feature" "+aes"
+
+! CHECK-A76: "-fc1" "-triple" "aarch64-unknown-linux-gnu"
+! CHECK-A76-SAME: "-target-cpu" "cortex-a76" "-target-feature" "+v8.2a" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+fullfp16" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+ssbs" "-target-feature" "+sha2" "-target-feature" "+aes"
+
+! CHECK-ARMV9: "-fc1" "-triple" "aarch64-unknown-linux-gnu"
+! CHECK-ARMV9-SAME: "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9a" "-target-feature" "+sve" "-target-feature" "+sve2"
+
+! CHECK-NO-A57: "-fc1" "-triple" "x86_64-unknown-linux-gnu"
+! CHECK-NO-A57-NOT: cortex-a57
+! CHECK-NO-A57-SAME: "-target-cpu" "x86-64"
+! CHECK-NO-A57-NOT: cortex-a57
+
+! CHECK-SKYLAKE: "-fc1" "-triple" "x86_64-unknown-linux-gnu"
+! CHECK-SKYLAKE-SAME: "-target-cpu" "skylake"
+
+! CHECK-X86_64H: "-fc1" "-triple" "x86_64h-unknown-linux-gnu"
+! CHECK-X86_64H-SAME: "-target-cpu" "x86-64" "-target-feature" "-rdrnd" "-target-feature" "-aes" "-target-feature" "-pclmul" "-target-feature" "-rtm" "-target-feature" "-fsgsbase"
+
+! CHECK-INVALID-CPU: 'supercpu' is not a recognized processor for this target (ignoring processor)
+! CHECK-INVALID-FEATURE: '+superspeed' is not a recognized feature for this target (ignoring feature)