[flang-commits] [clang] [flang] [flang] Emit target features for PPC (PR #169860)
via flang-commits
flang-commits at lists.llvm.org
Thu Nov 27 15:15:54 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-driver
Author: Kelvin Li (kkwli)
<details>
<summary>Changes</summary>
This patch is to emit target features for PPC. The feature list is expected to be the same as what is emitted by clang.
---
Full diff: https://github.com/llvm/llvm-project/pull/169860.diff
6 Files Affected:
- (modified) clang/lib/Driver/ToolChains/Flang.cpp (+1)
- (modified) flang/include/flang/Frontend/TargetOptions.h (+3)
- (modified) flang/lib/Frontend/CompilerInstance.cpp (+70-2)
- (modified) flang/lib/Lower/Bridge.cpp (+1-1)
- (modified) flang/test/Driver/target-cpu-features-invalid.f90 (+9-8)
- (added) flang/test/Lower/target-features-ppc.f90 (+15)
``````````diff
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 438de23be0103..4bb7612999d40 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -544,6 +544,7 @@ void Flang::addTargetOptions(const ArgList &Args,
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
case llvm::Triple::ppc64le:
+ getTargetFeatures(D, Triple, Args, CmdArgs, /*ForAs*/ false);
AddPPCTargetArgs(Args, CmdArgs);
break;
case llvm::Triple::loongarch64:
diff --git a/flang/include/flang/Frontend/TargetOptions.h b/flang/include/flang/Frontend/TargetOptions.h
index f6e5634d5a995..96b94c5f98965 100644
--- a/flang/include/flang/Frontend/TargetOptions.h
+++ b/flang/include/flang/Frontend/TargetOptions.h
@@ -42,6 +42,9 @@ class TargetOptions {
/// the command line.
std::vector<std::string> featuresAsWritten;
+ /// The default target features.
+ std::string targetFeatureStr;
+
/// The real KINDs disabled for this target
std::vector<int> disabledRealKinds;
diff --git a/flang/lib/Frontend/CompilerInstance.cpp b/flang/lib/Frontend/CompilerInstance.cpp
index 5920ed82114f8..f9f6417aaf815 100644
--- a/flang/lib/Frontend/CompilerInstance.cpp
+++ b/flang/lib/Frontend/CompilerInstance.cpp
@@ -28,6 +28,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/PPCTargetParser.h"
#include "llvm/TargetParser/TargetParser.h"
#include "llvm/TargetParser/Triple.h"
@@ -318,8 +319,67 @@ getExplicitAndImplicitNVPTXTargetFeatures(clang::DiagnosticsEngine &diags,
return llvm::join(featuresVec, ",");
}
+enum ppcCPU {prePwr8, prePwr10};
+static std::optional<ppcCPU> ppcType(std::string &cpu) {
+ return llvm::StringSwitch<std::optional<ppcCPU>>(cpu)
+ .Case("future", std::nullopt)
+ .Case("pwr11", std::nullopt)
+ .Case("pwr10", std::nullopt)
+ .Case("pwr9", prePwr10)
+ .Case("pwr8", prePwr10)
+ .Default(prePwr8);
+}
+
+static std::string
+getExplicitAndImplicitPPCTargetFeatures(clang::DiagnosticsEngine &diags,
+ TargetOptions &targetOpts,
+ const llvm::Triple triple) {
+ std::vector<std::string> featuresVec;
+ std::optional<llvm::StringMap<bool>> FeaturesOpt =
+ llvm::PPC::getPPCDefaultTargetFeatures(triple, targetOpts.cpu);
+ if (FeaturesOpt) {
+ for (auto &I : FeaturesOpt.value()) {
+ featuresVec.push_back(
+ (llvm::Twine(I.second ? "+" : "-") + I.first().str()).str());
+ }
+ }
+ // Check if the feature already exists.
+ for (auto v : targetOpts.featuresAsWritten) {
+ if (std::find(featuresVec.begin(), featuresVec.end(), v) ==
+ featuresVec.end()) {
+ featuresVec.push_back(v);
+ }
+ }
+
+ // Some features are not supported in earlier CPUs.
+ std::map<std::string_view, std::vector<ppcCPU>> unsupportedFeatures{
+ {"+mma", {prePwr8, prePwr10}},
+ {"+paired-vector-memops", {prePwr8, prePwr10}},
+ {"+pcrelative-memops", {prePwr8, prePwr10}},
+ {"+prefix-instrs", {prePwr8, prePwr10}},
+ {"+privileged", {prePwr8}},
+ {"+rop-protect", {prePwr8}}};
+ // Check if there are any unsupported features specified.
+ if (auto cpuType = ppcType(targetOpts.cpu)) {
+ for (auto f : unsupportedFeatures) {
+ for (auto g : f.second) {
+ if (cpuType.value() == g) {
+ if (llvm::is_contained(featuresVec, f.first)) {
+ diags.Report(clang::diag::err_opt_not_valid_on_target) << f.first;
+ return std::string();
+ }
+ }
+ }
+ }
+ }
+
+ llvm::sort(featuresVec);
+ targetOpts.targetFeatureStr = llvm::join(featuresVec, ",");
+ return targetOpts.targetFeatureStr;
+}
+
std::string CompilerInstance::getTargetFeatures() {
- const TargetOptions &targetOpts = getInvocation().getTargetOpts();
+ TargetOptions &targetOpts = getInvocation().getTargetOpts();
const llvm::Triple triple(targetOpts.triple);
// Clang does not append all target features to the clang -cc1 invocation.
@@ -334,13 +394,16 @@ std::string CompilerInstance::getTargetFeatures() {
} else if (triple.isNVPTX()) {
return getExplicitAndImplicitNVPTXTargetFeatures(getDiagnostics(),
targetOpts, triple);
+ } else if (triple.isPPC()) {
+ return getExplicitAndImplicitPPCTargetFeatures(getDiagnostics(),
+ targetOpts, triple);
}
return llvm::join(targetOpts.featuresAsWritten.begin(),
targetOpts.featuresAsWritten.end(), ",");
}
bool CompilerInstance::setUpTargetMachine() {
- const TargetOptions &targetOpts = getInvocation().getTargetOpts();
+ TargetOptions &targetOpts = getInvocation().getTargetOpts();
const std::string &theTriple = targetOpts.triple;
// Create `Target`
@@ -371,6 +434,11 @@ bool CompilerInstance::setUpTargetMachine() {
/*Reloc::Model=*/CGOpts.getRelocationModel(),
/*CodeModel::Model=*/cm, OptLevel));
assert(targetMachine && "Failed to create TargetMachine");
+
+ if (!triple.isPPC()) {
+ targetOpts.targetFeatureStr = targetMachine->getTargetFeatureString();
+ }
+
if (cm.has_value()) {
if ((cm == llvm::CodeModel::Medium || cm == llvm::CodeModel::Large) &&
triple.getArch() == llvm::Triple::x86_64) {
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 6f9dc32297272..cdeff1240cfd8 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -7159,7 +7159,7 @@ Fortran::lower::LoweringBridge::LoweringBridge(
targetOpts.atomicIgnoreDenormalMode);
fir::setAtomicFineGrainedMemory(*module, targetOpts.atomicFineGrainedMemory);
fir::setAtomicRemoteMemory(*module, targetOpts.atomicRemoteMemory);
- fir::setTargetFeatures(*module, targetMachine.getTargetFeatureString());
+ fir::setTargetFeatures(*module, targetOpts.targetFeatureStr);
fir::support::setMLIRDataLayout(*module, targetMachine.createDataLayout());
fir::setIdent(*module, Fortran::common::getFlangFullVersion());
if (cgOpts.RecordCommandLine)
diff --git a/flang/test/Driver/target-cpu-features-invalid.f90 b/flang/test/Driver/target-cpu-features-invalid.f90
index 288da8d57e81d..664c183ff692b 100644
--- a/flang/test/Driver/target-cpu-features-invalid.f90
+++ b/flang/test/Driver/target-cpu-features-invalid.f90
@@ -1,16 +1,17 @@
-! REQUIRES: aarch64-registered-target, amdgpu-registered-target
-
! 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: %if aarch64-registered-target %{ %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: %if aarch64-registered-target %{ %flang_fc1 -triple aarch64-linux-gnu -target-feature +superspeed \
+! RUN: -o /dev/null -S %s 2>&1 | FileCheck %s -check-prefix=CHECK-INVALID-FEATURE %}
-! 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
+! RUN: %if amdgpu-registered-target %{ not %flang_fc1 -triple amdgcn-amd-amdhsa -target-feature +wavefrontsize32 \
+! RUN: -target-feature +wavefrontsize64 -o /dev/null -S %s 2>&1 | FileCheck %s -check-prefix=CHECK-INVALID-WAVEFRONT %}
-! RUN: not %flang_fc1 -triple amdgcn-amd-amdhsa -target-feature +wavefrontsize32 \
-! RUN: -target-feature +wavefrontsize64 -o /dev/null -S %s 2>&1 | FileCheck %s -check-prefix=CHECK-INVALID-WAVEFRONT
+! RUN: %if powerpc-registered-target %{ not %flang_fc1 -triple powerpc64le-linux-gnu -target-feature +mma -target-cpu pwr9 -o /dev/null -S %s 2>&1 | FileCheck %s -check-prefix=CHECK-INVALID-PPC-FEATURE %}
! 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)
! CHECK-INVALID-WAVEFRONT: 'wavefrontsize32' and 'wavefrontsize64' are mutually exclusive
+! CHECK-INVALID-PPC-FEATURE: option '+mma' cannot be specified on this target
diff --git a/flang/test/Lower/target-features-ppc.f90 b/flang/test/Lower/target-features-ppc.f90
new file mode 100644
index 0000000000000..1c3429e6936a0
--- /dev/null
+++ b/flang/test/Lower/target-features-ppc.f90
@@ -0,0 +1,15 @@
+! REQUIRES: target=powerpc{{.*}}
+! RUN: %flang_fc1 -emit-fir -target-cpu pwr10 %s -o - | FileCheck %s --check-prefixes=ALL,FEATURE
+! RUN: %flang_fc1 -emit-fir -target-cpu pwr10 -target-feature +privileged %s -o - | FileCheck %s --check-prefixes=ALL,BOTH
+
+! ALL: module attributes {
+
+! ALL: fir.target_cpu = "pwr10"
+
+! FEATURE: fir.target_features = #llvm.target_features<[
+! FEATURE: "+64bit-support", "+allow-unaligned-fp-access", "+altivec", "+bpermd", "+cmpb", "+crbits", "+crypto", "+direct-move", "+extdiv", "+fast-MFLR", "+fcpsgn", "+fpcvt", "+fprnd", "+fpu", "+fre", "+fres", "+frsqrte", "+frsqrtes", "+fsqrt", "+fuse-add-logical", "+fuse-arith-add", "+fuse-logical", "+fuse-logical-add", "+fuse-sha3", "+fuse-store", "+fusion", "+hard-float", "+icbt", "+isa-v206-instructions", "+isa-v207-instructions", "+isa-v30-instructions", "+isa-v31-instructions", "+isel", "+ldbrx", "+lfiwax", "+mfocrf", "+mma", "+paired-vector-memops", "+partword-atomics", "+pcrelative-memops", "+popcntd", "+power10-vector", "+power8-altivec", "+power8-vector", "+power9-altivec", "+power9-vector", "+ppc-postra-sched", "+ppc-prera-sched", "+predictable-select-expensive", "+prefix-instrs", "+quadword-atomics", "+recipprec", "+stfiwx", "+two-const-nr", "+vsx"
+! FEATURE: ]>
+
+! BOTH: fir.target_features = #llvm.target_features<[
+! BOTH: "+64bit-support", "+allow-unaligned-fp-access", "+altivec", "+bpermd", "+cmpb", "+crbits", "+crypto", "+direct-move", "+extdiv", "+fast-MFLR", "+fcpsgn", "+fpcvt", "+fprnd", "+fpu", "+fre", "+fres", "+frsqrte", "+frsqrtes", "+fsqrt", "+fuse-add-logical", "+fuse-arith-add", "+fuse-logical", "+fuse-logical-add", "+fuse-sha3", "+fuse-store", "+fusion", "+hard-float", "+icbt", "+isa-v206-instructions", "+isa-v207-instructions", "+isa-v30-instructions", "+isa-v31-instructions", "+isel", "+ldbrx", "+lfiwax", "+mfocrf", "+mma", "+paired-vector-memops", "+partword-atomics", "+pcrelative-memops", "+popcntd", "+power10-vector", "+power8-altivec", "+power8-vector", "+power9-altivec", "+power9-vector", "+ppc-postra-sched", "+ppc-prera-sched", "+predictable-select-expensive", "+prefix-instrs", "+privileged", "+quadword-atomics", "+recipprec", "+stfiwx", "+two-const-nr", "+vsx"
+! BOTH: ]>
``````````
</details>
https://github.com/llvm/llvm-project/pull/169860
More information about the flang-commits
mailing list