Skip to content

[Reland] [PowerPC] frontend get target feature from backend with cpu name #144594

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 7 additions & 141 deletions clang/lib/Basic/Targets/PPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "clang/Basic/MacroBuilder.h"
#include "clang/Basic/TargetBuiltins.h"
#include "llvm/TargetParser/PPCTargetParser.h"
#include <optional>

using namespace clang;
using namespace clang::targets;
Expand Down Expand Up @@ -516,129 +517,14 @@ static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
bool PPCTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeaturesVec) const {
Features["altivec"] = llvm::StringSwitch<bool>(CPU)
.Case("7400", true)
.Case("g4", true)
.Case("7450", true)
.Case("g4+", true)
.Case("970", true)
.Case("g5", true)
.Case("pwr6", true)
.Case("pwr7", true)
.Case("pwr8", true)
.Case("pwr9", true)
.Case("ppc64", true)
.Case("ppc64le", true)
.Default(false);

Features["power9-vector"] = (CPU == "pwr9");
Features["crypto"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
.Case("pwr8", true)
.Default(false);
Features["power8-vector"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
.Case("pwr8", true)
.Default(false);
Features["bpermd"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
.Case("pwr8", true)
.Case("pwr7", true)
.Default(false);
Features["extdiv"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
.Case("pwr8", true)
.Case("pwr7", true)
.Default(false);
Features["direct-move"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
.Case("pwr8", true)
.Default(false);
Features["crbits"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
.Case("pwr8", true)
.Default(false);
Features["vsx"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
.Case("pwr8", true)
.Case("pwr7", true)
.Default(false);
Features["htm"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
.Case("pwr8", true)
.Default(false);

// ROP Protect is off by default.
Features["rop-protect"] = false;
// Privileged instructions are off by default.
Features["privileged"] = false;

if (getTriple().isOSAIX()) {
// The code generated by the -maix-small-local-[exec|dynamic]-tls option is
// turned off by default.
Features["aix-small-local-exec-tls"] = false;
Features["aix-small-local-dynamic-tls"] = false;

// Turn off TLS model opt by default.
Features["aix-shared-lib-tls-model-opt"] = false;
}

Features["spe"] = llvm::StringSwitch<bool>(CPU)
.Case("8548", true)
.Case("e500", true)
.Default(false);

Features["isa-v206-instructions"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
.Case("pwr8", true)
.Case("pwr7", true)
.Case("a2", true)
.Default(false);

Features["isa-v207-instructions"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
.Case("pwr8", true)
.Default(false);

Features["isa-v30-instructions"] =
llvm::StringSwitch<bool>(CPU).Case("pwr9", true).Default(false);

Features["quadword-atomics"] =
getTriple().isArch64Bit() && llvm::StringSwitch<bool>(CPU)
.Case("pwr9", true)
.Case("pwr8", true)
.Default(false);

// Power10 includes all the same features as Power9 plus any features specific
// to the Power10 core.
if (CPU == "pwr10" || CPU == "power10") {
initFeatureMap(Features, Diags, "pwr9", FeaturesVec);
addP10SpecificFeatures(Features);
}

// Power11 includes all the same features as Power10 plus any features
// specific to the Power11 core.
if (CPU == "pwr11" || CPU == "power11") {
initFeatureMap(Features, Diags, "pwr10", FeaturesVec);
addP11SpecificFeatures(Features);
}
const llvm::Triple &TheTriple = getTriple();

// Future CPU should include all of the features of Power 11 as well as any
// additional features (yet to be determined) specific to it.
if (CPU == "future") {
initFeatureMap(Features, Diags, "pwr11", FeaturesVec);
addFutureSpecificFeatures(Features);
}
std::optional<llvm::StringMap<bool>> FeaturesOpt =
llvm::PPC::getPPCDefaultTargetFeatures(TheTriple,
llvm::PPC::normalizeCPUName(CPU));
if (FeaturesOpt)
Features = FeaturesOpt.value();

if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
return false;
Expand Down Expand Up @@ -700,26 +586,6 @@ bool PPCTargetInfo::initFeatureMap(
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
}

// Add any Power10 specific features.
void PPCTargetInfo::addP10SpecificFeatures(
llvm::StringMap<bool> &Features) const {
Features["htm"] = false; // HTM was removed for P10.
Features["paired-vector-memops"] = true;
Features["mma"] = true;
Features["power10-vector"] = true;
Features["pcrelative-memops"] = true;
Features["prefix-instrs"] = true;
Features["isa-v31-instructions"] = true;
}

// Add any Power11 specific features.
void PPCTargetInfo::addP11SpecificFeatures(
llvm::StringMap<bool> &Features) const {}

// Add features specific to the "Future" CPU.
void PPCTargetInfo::addFutureSpecificFeatures(
llvm::StringMap<bool> &Features) const {}

bool PPCTargetInfo::hasFeature(StringRef Feature) const {
return llvm::StringSwitch<bool>(Feature)
.Case("powerpc", true)
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ int &g() { return r; }
// DARWIN-LABEL: define internal cxx_fast_tlscc void @__tls_init()
// CHECK: call void @[[R_INIT]]()

// LINUX_AIX: attributes [[ATTR0]] = { {{.*}}"target-features"{{.*}} }
// LINUX_AIX: attributes [[ATTR0]] = { {{.*}} }
// DARWIN: attributes [[ATTR1]] = { {{.*}}nounwind{{.*}}"target-features"{{.*}} }
7 changes: 3 additions & 4 deletions clang/test/Driver/aix-shared-lib-tls-model-opt.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %clang -target powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK-AIX,CHECK-AIX-OFF %s
// RUN: %clang -target powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK-AIX,CHECK-AIX-OFF %s
// RUN: %clang -target powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX %s
// RUN: %clang -target powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX %s
// RUN: %clang -target powerpc64le-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s
// RUN: %clang -target powerpc64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s

Expand All @@ -19,9 +19,8 @@ int test(void) {

// CHECK-AIX: test() #0 {
// CHECK-AIX: attributes #0 = {
// CHECK-AIX-OFF-SAME: -aix-shared-lib-tls-model-opt
// CHECK-AIX-ON-SAME: +aix-shared-lib-tls-model-opt

// CHECK-LINUX-NOT: {{[-+]aix-shared-lib-tls-model-opt}}
// CHECK-LINUX-NOT: {{[+]aix-shared-lib-tls-model-opt}}

// CHECK-UNSUPPORTED-TARGET: option '-maix-shared-lib-tls-model-opt' cannot be specified on this target
39 changes: 19 additions & 20 deletions clang/test/Driver/aix-small-local-exec-dynamic-tls.c
Original file line number Diff line number Diff line change
@@ -1,48 +1,47 @@
// RUN: %clang -target powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX-DEFAULT %s
// RUN: %clang -target powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX-DEFAULT %s
// RUN: %clang -target powerpc64le-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s
// RUN: %clang -target powerpc64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s
// RUN: %clang --target=powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s
// RUN: %clang --target=powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s
// RUN: %clang --target=powerpc64le-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s
// RUN: %clang --target=powerpc64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s

// RUN: %clang -target powerpc64-unknown-aix -maix-small-local-exec-tls -S -emit-llvm \
// RUN: %clang --target=powerpc64-unknown-aix -maix-small-local-exec-tls -S -emit-llvm \
// RUN: %s -o - | FileCheck %s --check-prefix=CHECK-AIX_SMALL_LOCALEXEC_TLS

// RUN: %clang -target powerpc64-unknown-aix -maix-small-local-dynamic-tls -S -emit-llvm \
// RUN: %clang --target=powerpc64-unknown-aix -maix-small-local-dynamic-tls -S -emit-llvm \
// RUN: %s -o - | FileCheck %s --check-prefix=CHECK-AIX_SMALL_LOCALDYNAMIC_TLS

// RUN: not %clang -target powerpc-unknown-aix -maix-small-local-exec-tls \
// RUN: not %clang --target=powerpc-unknown-aix -maix-small-local-exec-tls \
// RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-AIX32 %s
// RUN: not %clang -target powerpc64le-unknown-linux-gnu -maix-small-local-exec-tls \
// RUN: not %clang --target=powerpc64le-unknown-linux-gnu -maix-small-local-exec-tls \
// RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-LINUX %s
// RUN: not %clang -target powerpc64-unknown-linux-gnu -maix-small-local-exec-tls \
// RUN: not %clang --target=powerpc64-unknown-linux-gnu -maix-small-local-exec-tls \
// RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-LINUX %s
// RUN: not %clang -target powerpc64-unknown-aix -maix-small-local-exec-tls \
// RUN: not %clang --target=powerpc64-unknown-aix -maix-small-local-exec-tls \
// RUN: -fsyntax-only -fno-data-sections %s 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-UNSUPPORTED-NO-DATASEC %s
// RUN: not %clang -target powerpc64-unknown-linux-gnu -maix-small-local-exec-tls \
// RUN: not %clang --target=powerpc64-unknown-linux-gnu -maix-small-local-exec-tls \
// RUN: -fsyntax-only -fno-data-sections %s 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-UNSUPPORTED-NO-DATASEC %s

// RUN: not %clang -target powerpc-unknown-aix -maix-small-local-dynamic-tls \
// RUN: not %clang --target=powerpc-unknown-aix -maix-small-local-dynamic-tls \
// RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-AIX32 %s
// RUN: not %clang -target powerpc64le-unknown-linux-gnu -maix-small-local-dynamic-tls \
// RUN: not %clang --target=powerpc64le-unknown-linux-gnu -maix-small-local-dynamic-tls \
// RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-LINUX %s
// RUN: not %clang -target powerpc64-unknown-linux-gnu -maix-small-local-dynamic-tls \
// RUN: not %clang --target=powerpc64-unknown-linux-gnu -maix-small-local-dynamic-tls \
// RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-LINUX %s
// RUN: not %clang -target powerpc64-unknown-aix -maix-small-local-dynamic-tls \
// RUN: not %clang --target=powerpc64-unknown-aix -maix-small-local-dynamic-tls \
// RUN: -fsyntax-only -fno-data-sections %s 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-UNSUPPORTED-NO-DATASEC %s
// RUN: not %clang -target powerpc64-unknown-linux-gnu -maix-small-local-dynamic-tls \
// RUN: not %clang --target=powerpc64-unknown-linux-gnu -maix-small-local-dynamic-tls \
// RUN: -fsyntax-only -fno-data-sections %s 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-UNSUPPORTED-NO-DATASEC %s

int test(void) {
return 0;
}

// CHECK-AIX-DEFAULT: test() #0 {
// CHECK-AIX-DEFAULT: attributes #0 = {
// CHECK-AIX-DEFAULT-SAME: {{-aix-small-local-exec-tls,.*-aix-small-local-dynamic-tls|-aix-small-local-dynamic-tls,.*-aix-small-local-exec-tls}}
// CHECK-LINUX-NOT: {{[-+]aix-small-local-exec-tls,.*[-+]aix-small-local-dynamic-tls|[-+]aix-small-local-dynamic-tls,.*[-+]aix-small-local-exec-tls}}
// CHECK-DEFAULT: test() #0 {
// CHECK-DEFAULT: attributes #0 = {
// CHECK-DEFAULT-NOT: {{[-+]aix-small-local-exec-tls,.*[-+]aix-small-local-dynamic-tls|[-+]aix-small-local-dynamic-tls,.*[-+]aix-small-local-exec-tls}}

// CHECK-UNSUPPORTED-AIX32: option '-maix-small-local-[exec|dynamic]-tls' cannot be specified on this target
// CHECK-UNSUPPORTED-LINUX: option '-maix-small-local-[exec|dynamic]-tls' cannot be specified on this target
Expand Down
4 changes: 0 additions & 4 deletions clang/test/Driver/ppc-crbits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@
// RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr8 -mno-crbits \
// RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS

// RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr7 -emit-llvm \
// RUN: -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS
// RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr7 -mcrbits \
// RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-CRBITS
// RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr7 -mno-crbits \
Expand All @@ -92,8 +90,6 @@
// RUN: %clang -target powerpc-ibm-aix -mcpu=pwr8 -mno-crbits \
// RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS

// RUN: %clang -target powerpc-ibm-aix -mcpu=pwr7 -emit-llvm \
// RUN: -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS
// RUN: %clang -target powerpc-ibm-aix -mcpu=pwr7 -mcrbits \
// RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-CRBITS
// RUN: %clang -target powerpc-ibm-aix -mcpu=pwr7 -mno-crbits \
Expand Down
22 changes: 11 additions & 11 deletions clang/test/Driver/ppc-isa-features.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
// RUN: %clang -target powerpc64-unknown-aix -mcpu=pwr9 -S -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-PWR9
// RUN: %clang -target powerpc-unknown-aix -mcpu=pwr10 -S -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-PWR10

// CHECK-PWR6: -isa-v206-instructions
// CHECK-PWR6: -isa-v207-instructions
// CHECK-PWR6: -isa-v30-instructions
// CHECK-PWR6-NOT: isa-v206-instructions
// CHECK-PWR6-NOT: isa-v207-instructions
// CHECK-PWR6-NOT: isa-v30-instructions

// CHECK-A2: +isa-v206-instructions
// CHECK-A2: -isa-v207-instructions
// CHECK-A2: -isa-v30-instructions
// CHECK-A2: +isa-v206-instructions
// CHECK-A2-NOT: isa-v207-instructions
// CHECK-A2-NOT: isa-v30-instructions

// CHECK-PWR7: +isa-v206-instructions
// CHECK-PWR7: -isa-v207-instructions
// CHECK-PWR7: -isa-v30-instructions
// CHECK-PWR7: +isa-v206-instructions
// CHECK-PWR7-NOT: isa-v207-instructions
// CHECK-PWR7-NOT: isa-v30-instructions

// CHECK-PWR8: +isa-v207-instructions
// CHECK-PWR8: -isa-v30-instructions
// CHECK-PWR8: +isa-v207-instructions
// CHECK-PWR8-NOT: isa-v30-instructions

// CHECK-PWR9: +isa-v207-instructions
// CHECK-PWR9: +isa-v30-instructions
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/TargetParser/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ tablegen(LLVM AArch64TargetParserDef.inc -gen-arm-target-def -I ${PROJECT_SOURCE
set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/RISCV/RISCV.td)
tablegen(LLVM RISCVTargetParserDef.inc -gen-riscv-target-def -I ${PROJECT_SOURCE_DIR}/lib/Target/RISCV/)

set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/PowerPC/PPC.td)
tablegen(LLVM PPCGenTargetFeatures.inc -gen-target-features -I${PROJECT_SOURCE_DIR}/lib/Target/PowerPC)

# This covers all of the tablegen calls above.
add_public_tablegen_target(target_parser_gen)
6 changes: 6 additions & 0 deletions llvm/include/llvm/TargetParser/PPCTargetParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#ifndef LLVM_TARGETPARSER_PPCTARGETPARSER_H
#define LLVM_TARGETPARSER_PPCTARGETPARSER_H

#include "TargetParser.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/TargetParser/Triple.h"
Expand All @@ -37,6 +39,10 @@ LLVM_ABI StringRef getNormalizedPPCTuneCPU(const Triple &T,
// For PPC, there are some cpu names for same CPU, like pwr10 and power10,
// normalize them.
LLVM_ABI StringRef normalizeCPUName(StringRef CPUName);

LLVM_ABI std::optional<llvm::StringMap<bool>>
getPPCDefaultTargetFeatures(const Triple &T, StringRef CPUName);

} // namespace PPC
} // namespace llvm

Expand Down
27 changes: 27 additions & 0 deletions llvm/include/llvm/TargetParser/TargetParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#ifndef LLVM_TARGETPARSER_TARGETPARSER_H
#define LLVM_TARGETPARSER_TARGETPARSER_H

#include "SubtargetFeature.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
Expand Down Expand Up @@ -190,6 +192,31 @@ insertWaveSizeFeature(StringRef GPU, const Triple &T,
StringMap<bool> &Features);

} // namespace AMDGPU

struct BasicSubtargetFeatureKV {
const char *Key; ///< K-V key string
unsigned Value; ///< K-V integer value
FeatureBitArray Implies; ///< K-V bit mask
};

/// Used to provide key value pairs for feature and CPU bit flags.
struct BasicSubtargetSubTypeKV {
const char *Key; ///< K-V key string
FeatureBitArray Implies; ///< K-V bit mask

/// Compare routine for std::lower_bound
bool operator<(StringRef S) const { return StringRef(Key) < S; }

/// Compare routine for std::is_sorted.
bool operator<(const BasicSubtargetSubTypeKV &Other) const {
return StringRef(Key) < StringRef(Other.Key);
}
};
Comment on lines +196 to +214
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to move SubtargetFeatureKV and SubtargetSubTypeKV from MCSubtargetInfo.h into llvm/include/llvm/TargetParser/SubtargetFeature.h (better than duplicating the definitions so closely).

Copy link
Contributor Author

@diggerlin diggerlin Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. However, the patch is already quite large. I think it would be better to handle this in a separate NFC patch later. That said, if you strongly recommend it, I can include it in the current patch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this is a reland, sure, I'm happy for you to do this refactor later.


std::optional<llvm::StringMap<bool>>
getCPUDefaultTargetFeatures(StringRef CPU,
ArrayRef<BasicSubtargetSubTypeKV> ProcDesc,
ArrayRef<BasicSubtargetFeatureKV> ProcFeatures);
} // namespace llvm

#endif
Loading