https://github.com/kkwli updated https://github.com/llvm/llvm-project/pull/169860
>From dce9682ebe8fbd85121afe2aae1c95a37ec71fa3 Mon Sep 17 00:00:00 2001 From: Kelvin Li <[email protected]> Date: Mon, 20 Oct 2025 09:19:40 -0400 Subject: [PATCH 1/3] [flang] Emit target features for PPC --- clang/lib/Driver/ToolChains/Flang.cpp | 1 + flang/include/flang/Frontend/TargetOptions.h | 3 + flang/lib/Frontend/CompilerInstance.cpp | 72 ++++++++++++++++++- flang/lib/Lower/Bridge.cpp | 2 +- .../Driver/target-cpu-features-invalid.f90 | 17 +++-- flang/test/Lower/target-features-ppc.f90 | 15 ++++ 6 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 flang/test/Lower/target-features-ppc.f90 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..0b7b517944d2d 100644 --- a/flang/test/Driver/target-cpu-features-invalid.f90 +++ b/flang/test/Driver/target-cpu-features-invalid.f90 @@ -1,16 +1,19 @@ -! REQUIRES: aarch64-registered-target, amdgpu-registered-target +! : aarch64-registered-target, amdgpu-registered-target, powerpc-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: %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 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: 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 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: %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: ]> >From 848ce41939eda4a158a14b245eef41dad2471d3d Mon Sep 17 00:00:00 2001 From: Kelvin Li <[email protected]> Date: Thu, 27 Nov 2025 18:11:52 -0500 Subject: [PATCH 2/3] remove comment lines --- flang/test/Driver/target-cpu-features-invalid.f90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/flang/test/Driver/target-cpu-features-invalid.f90 b/flang/test/Driver/target-cpu-features-invalid.f90 index 0b7b517944d2d..664c183ff692b 100644 --- a/flang/test/Driver/target-cpu-features-invalid.f90 +++ b/flang/test/Driver/target-cpu-features-invalid.f90 @@ -1,5 +1,3 @@ -! : aarch64-registered-target, amdgpu-registered-target, powerpc-registered-target - ! Test that invalid cpu and features are ignored. ! RUN: %if aarch64-registered-target %{ %flang_fc1 -triple aarch64-linux-gnu -target-cpu supercpu \ >From 000dc93ea29e07e33b8d19f7cb5ae0221f0fe12d Mon Sep 17 00:00:00 2001 From: Kelvin Li <[email protected]> Date: Thu, 27 Nov 2025 18:26:46 -0500 Subject: [PATCH 3/3] fix format --- flang/lib/Frontend/CompilerInstance.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flang/lib/Frontend/CompilerInstance.cpp b/flang/lib/Frontend/CompilerInstance.cpp index f9f6417aaf815..8174ae0cfaade 100644 --- a/flang/lib/Frontend/CompilerInstance.cpp +++ b/flang/lib/Frontend/CompilerInstance.cpp @@ -319,7 +319,7 @@ getExplicitAndImplicitNVPTXTargetFeatures(clang::DiagnosticsEngine &diags, return llvm::join(featuresVec, ","); } -enum ppcCPU {prePwr8, prePwr10}; +enum ppcCPU { prePwr8, prePwr10 }; static std::optional<ppcCPU> ppcType(std::string &cpu) { return llvm::StringSwitch<std::optional<ppcCPU>>(cpu) .Case("future", std::nullopt) @@ -395,8 +395,8 @@ std::string CompilerInstance::getTargetFeatures() { return getExplicitAndImplicitNVPTXTargetFeatures(getDiagnostics(), targetOpts, triple); } else if (triple.isPPC()) { - return getExplicitAndImplicitPPCTargetFeatures(getDiagnostics(), - targetOpts, triple); + return getExplicitAndImplicitPPCTargetFeatures(getDiagnostics(), targetOpts, + triple); } return llvm::join(targetOpts.featuresAsWritten.begin(), targetOpts.featuresAsWritten.end(), ","); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
