Skip to content

[PowerPC] add TargetParser for PPC target #97541

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

Merged
merged 1 commit into from
Jul 25, 2024

Conversation

chenzheng1030
Copy link
Collaborator

For now only focus on the CPU type, will work on the CPU features part later.

With the CPU handling in TargetParser, clang and llc/opt are able to query common interfaces.

So we can set same default CPU and CPU features with same interfaces.

@chenzheng1030 chenzheng1030 requested a review from diggerlin July 3, 2024 08:45
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:PowerPC clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jul 3, 2024
@chenzheng1030 chenzheng1030 requested a review from mandlebug July 3, 2024 08:46
@llvmbot
Copy link
Member

llvmbot commented Jul 3, 2024

@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-backend-powerpc

Author: Chen Zheng (chenzheng1030)

Changes

For now only focus on the CPU type, will work on the CPU features part later.

With the CPU handling in TargetParser, clang and llc/opt are able to query common interfaces.

So we can set same default CPU and CPU features with same interfaces.


Patch is 24.14 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/97541.diff

12 Files Affected:

  • (modified) clang/lib/Basic/Targets/PPC.cpp (+3-15)
  • (modified) clang/lib/Driver/ToolChains/Arch/PPC.cpp (-72)
  • (modified) clang/lib/Driver/ToolChains/Arch/PPC.h (-4)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+6-2)
  • (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+4-1)
  • (modified) clang/test/CodeGen/aix-builtin-cpu-is.c (+25-17)
  • (modified) clang/test/Misc/target-invalid-cpu-note.c (+1-1)
  • (modified) llvm/include/llvm/TargetParser/PPCTargetParser.def (+52-1)
  • (added) llvm/include/llvm/TargetParser/PPCTargetParser.h (+37)
  • (modified) llvm/lib/TargetParser/CMakeLists.txt (+1)
  • (added) llvm/lib/TargetParser/PPCTargetParser.cpp (+121)
  • (modified) llvm/utils/gn/secondary/llvm/lib/TargetParser/BUILD.gn (+1)
diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 89c5566f7ad09..5543f4a100c46 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -14,6 +14,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/MacroBuilder.h"
 #include "clang/Basic/TargetBuiltins.h"
+#include "llvm/TargetParser/PPCTargetParser.h"
 
 using namespace clang;
 using namespace clang::targets;
@@ -866,25 +867,12 @@ ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const {
   return llvm::ArrayRef(GCCAddlRegNames);
 }
 
-static constexpr llvm::StringLiteral ValidCPUNames[] = {
-    {"generic"},     {"440"},     {"450"},    {"601"},       {"602"},
-    {"603"},         {"603e"},    {"603ev"},  {"604"},       {"604e"},
-    {"620"},         {"630"},     {"g3"},     {"7400"},      {"g4"},
-    {"7450"},        {"g4+"},     {"750"},    {"8548"},      {"970"},
-    {"g5"},          {"a2"},      {"e500"},   {"e500mc"},    {"e5500"},
-    {"power3"},      {"pwr3"},    {"power4"}, {"pwr4"},      {"power5"},
-    {"pwr5"},        {"power5x"}, {"pwr5x"},  {"power6"},    {"pwr6"},
-    {"power6x"},     {"pwr6x"},   {"power7"}, {"pwr7"},      {"power8"},
-    {"pwr8"},        {"power9"},  {"pwr9"},   {"power10"},   {"pwr10"},
-    {"powerpc"},     {"ppc"},     {"ppc32"},  {"powerpc64"}, {"ppc64"},
-    {"powerpc64le"}, {"ppc64le"}, {"future"}};
-
 bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
-  return llvm::is_contained(ValidCPUNames, Name);
+  return llvm::PPC::isValidCPU(Name);
 }
 
 void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
-  Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
+  llvm::PPC::fillValidCPUList(Values);
 }
 
 void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
diff --git a/clang/lib/Driver/ToolChains/Arch/PPC.cpp b/clang/lib/Driver/ToolChains/Arch/PPC.cpp
index 634c096523319..b63e16c22370d 100644
--- a/clang/lib/Driver/ToolChains/Arch/PPC.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/PPC.cpp
@@ -20,78 +20,6 @@ using namespace clang::driver::tools;
 using namespace clang;
 using namespace llvm::opt;
 
-static std::string getPPCGenericTargetCPU(const llvm::Triple &T) {
-  // LLVM may default to generating code for the native CPU,
-  // but, like gcc, we default to a more generic option for
-  // each architecture. (except on AIX)
-  if (T.isOSAIX())
-    return "pwr7";
-  else if (T.getArch() == llvm::Triple::ppc64le)
-    return "ppc64le";
-  else if (T.getArch() == llvm::Triple::ppc64)
-    return "ppc64";
-  else
-    return "ppc";
-}
-
-static std::string normalizeCPUName(StringRef CPUName, const llvm::Triple &T) {
-  // Clang/LLVM does not actually support code generation
-  // for the 405 CPU. However, there are uses of this CPU ID
-  // in projects that previously used GCC and rely on Clang
-  // accepting it. Clang has always ignored it and passed the
-  // generic CPU ID to the back end.
-  if (CPUName == "generic" || CPUName == "405")
-    return getPPCGenericTargetCPU(T);
-
-  if (CPUName == "native") {
-    std::string CPU = std::string(llvm::sys::getHostCPUName());
-    if (!CPU.empty() && CPU != "generic")
-      return CPU;
-    else
-      return getPPCGenericTargetCPU(T);
-  }
-
-  return llvm::StringSwitch<const char *>(CPUName)
-      .Case("common", "generic")
-      .Case("440fp", "440")
-      .Case("630", "pwr3")
-      .Case("G3", "g3")
-      .Case("G4", "g4")
-      .Case("G4+", "g4+")
-      .Case("8548", "e500")
-      .Case("G5", "g5")
-      .Case("power3", "pwr3")
-      .Case("power4", "pwr4")
-      .Case("power5", "pwr5")
-      .Case("power5x", "pwr5x")
-      .Case("power6", "pwr6")
-      .Case("power6x", "pwr6x")
-      .Case("power7", "pwr7")
-      .Case("power8", "pwr8")
-      .Case("power9", "pwr9")
-      .Case("power10", "pwr10")
-      .Case("future", "future")
-      .Case("powerpc", "ppc")
-      .Case("powerpc64", "ppc64")
-      .Case("powerpc64le", "ppc64le")
-      .Default(CPUName.data());
-}
-
-/// Get the (LLVM) name of the PowerPC cpu we are tuning for.
-std::string ppc::getPPCTuneCPU(const ArgList &Args, const llvm::Triple &T) {
-  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))
-    return normalizeCPUName(A->getValue(), T);
-  return getPPCGenericTargetCPU(T);
-}
-
-/// Get the (LLVM) name of the PowerPC cpu we are targeting.
-std::string ppc::getPPCTargetCPU(const Driver &D, const ArgList &Args,
-                                 const llvm::Triple &T) {
-  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
-    return normalizeCPUName(A->getValue(), T);
-  return getPPCGenericTargetCPU(T);
-}
-
 const char *ppc::getPPCAsmModeForCPU(StringRef Name) {
   return llvm::StringSwitch<const char *>(Name)
       .Case("pwr7", "-mpower7")
diff --git a/clang/lib/Driver/ToolChains/Arch/PPC.h b/clang/lib/Driver/ToolChains/Arch/PPC.h
index ec5b3c8140b66..89b9af92e8ddb 100644
--- a/clang/lib/Driver/ToolChains/Arch/PPC.h
+++ b/clang/lib/Driver/ToolChains/Arch/PPC.h
@@ -35,10 +35,6 @@ enum class ReadGOTPtrMode {
 
 FloatABI getPPCFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
 
-std::string getPPCTargetCPU(const Driver &D, const llvm::opt::ArgList &Args,
-                            const llvm::Triple &T);
-std::string getPPCTuneCPU(const llvm::opt::ArgList &Args,
-                          const llvm::Triple &T);
 const char *getPPCAsmModeForCPU(StringRef Name);
 ReadGOTPtrMode getPPCReadGOTPtrMode(const Driver &D, const llvm::Triple &Triple,
                                     const llvm::opt::ArgList &Args);
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 27c451c565f2b..607a6cda6ae3f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -60,6 +60,7 @@
 #include "llvm/TargetParser/ARMTargetParserCommon.h"
 #include "llvm/TargetParser/Host.h"
 #include "llvm/TargetParser/LoongArchTargetParser.h"
+#include "llvm/TargetParser/PPCTargetParser.h"
 #include "llvm/TargetParser/RISCVISAInfo.h"
 #include "llvm/TargetParser/RISCVTargetParser.h"
 #include <cctype>
@@ -1963,8 +1964,11 @@ void Clang::AddPPCTargetArgs(const ArgList &Args,
   const llvm::Triple &T = getToolChain().getTriple();
   if (Args.getLastArg(options::OPT_mtune_EQ)) {
     CmdArgs.push_back("-tune-cpu");
-    std::string CPU = ppc::getPPCTuneCPU(Args, T);
-    CmdArgs.push_back(Args.MakeArgString(CPU));
+    StringRef CPU = "";
+    if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))
+      CPU = A->getValue();
+    CPU = llvm::PPC::getPPCGenericTuneCPU(T, CPU);
+    CmdArgs.push_back(Args.MakeArgString(CPU.str()));
   }
 
   // Select the ABI to use.
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index be4d7d2cffb16..4c8de4e9db63c 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -64,6 +64,7 @@
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/YAMLParser.h"
 #include "llvm/TargetParser/Host.h"
+#include "llvm/TargetParser/PPCTargetParser.h"
 #include "llvm/TargetParser/TargetParser.h"
 #include <optional>
 
@@ -629,7 +630,9 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
   case llvm::Triple::ppcle:
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le:
-    return ppc::getPPCTargetCPU(D, Args, T);
+    if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
+      return std::string(llvm::PPC::getPPCGenericTargetCPU(T, A->getValue()));
+    return std::string(llvm::PPC::getPPCGenericTargetCPU(T));
 
   case llvm::Triple::csky:
     if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
diff --git a/clang/test/CodeGen/aix-builtin-cpu-is.c b/clang/test/CodeGen/aix-builtin-cpu-is.c
index e17cf7353511a..fe321346b9d97 100644
--- a/clang/test/CodeGen/aix-builtin-cpu-is.c
+++ b/clang/test/CodeGen/aix-builtin-cpu-is.c
@@ -1,52 +1,60 @@
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc970\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc970\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc-cell-be\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc-cell-be\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppca2\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppca2\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc405\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc405\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc440\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc440\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc464\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc464\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc476\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc476\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power4\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power4\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power5\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power5\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power5+\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power5+\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power6\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power6\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power6x\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power6x\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power7\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power7\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=32768 \
 // RUN:   --check-prefix=CHECKOP
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power8\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"pwr7\");}" > %t.c
+// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=32768 \
+// RUN:   --check-prefix=CHECKOP
+
+// RUN: echo "int main() { return __builtin_cpu_is(\"power8\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=65536 \
 // RUN:   --check-prefix=CHECKOP
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power9\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power9\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=131072\
 // RUN:   --check-prefix=CHECKOP
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power10\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power10\");}" > %t.c
+// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=262144 \
+// RUN:   --check-prefix=CHECKOP
+
+// RUN: echo "int main() { return __builtin_cpu_is(\"pwr10\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=262144 \
 // RUN:   --check-prefix=CHECKOP
 
@@ -63,7 +71,7 @@
 // CHECKOP-NEXT:   %retval = alloca i32, align 4
 // CHECKOP-NEXT:   store i32 0, ptr %retval, align 4
 // CHECKOP-NEXT:   %0 = load i32, ptr getelementptr inbounds ({ i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i64, i32, i32, i32, i32, i64, i64, i64, i64, i32, i32, i32, i32, i32, i32, i64, i32, i8, i8, i8, i8, i32, i32, i16, i16, [3 x i32], i32 }, ptr @_system_configuration, i32 0, i32 1), align 4
-// CHECKOP-NEXT:   %1 = icmp eq i32 %0, [[VALUE]] 
+// CHECKOP-NEXT:   %1 = icmp eq i32 %0, [[VALUE]]
 // CHECKOP-NEXT:  %conv = zext i1 %1 to i32
 // CHECKOP-NEXT:   ret i32 %conv
 // CHECKOP-NEXT: }
diff --git a/clang/test/Misc/target-invalid-cpu-note.c b/clang/test/Misc/target-invalid-cpu-note.c
index a5f9ffa21220a..b77874acbfb9a 100644
--- a/clang/test/Misc/target-invalid-cpu-note.c
+++ b/clang/test/Misc/target-invalid-cpu-note.c
@@ -57,7 +57,7 @@
 
 // RUN: not %clang_cc1 -triple powerpc--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix PPC
 // PPC: error: unknown target CPU 'not-a-cpu'
-// PPC-NEXT: note: valid target CPU values are: generic, 440, 450, 601, 602, 603, 603e, 603ev, 604, 604e, 620, 630, g3, 7400, g4, 7450, g4+, 750, 8548, 970, g5, a2, e500, e500mc, e5500, power3, pwr3, power4, pwr4, power5, pwr5, power5x, pwr5x, power6, pwr6, power6x, pwr6x, power7, pwr7, power8, pwr8, power9, pwr9, power10, pwr10, powerpc, ppc, ppc32, powerpc64, ppc64, powerpc64le, ppc64le, future{{$}}
+// PPC-NEXT: note: valid target CPU values are: generic, 440, 440fp, 450, 601, 602, 603, 603e, 603ev, 604, 604e, 620, 630, g3, 7400, g4, 7450, g4+, 750, 8548, 970, g5, a2, e500, e500mc, e5500, power3, pwr3, pwr4, pwr5, pwr5+, power5x, pwr5x, pwr6, pwr6x, pwr7, pwr8, pwr9, pwr10, powerpc, ppc, ppc32, powerpc64, ppc64, powerpc64le, ppc64le, future, power4, ppc970, power5, power5+, power6, ppc-cell-be, power6x, power7, ppca2, ppc405, ppc440, ppc464, ppc476, power8, power9, power10{{$}}
 
 // RUN: not %clang_cc1 -triple mips--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix MIPS
 // MIPS: error: unknown target CPU 'not-a-cpu'
diff --git a/llvm/include/llvm/TargetParser/PPCTargetParser.def b/llvm/include/llvm/TargetParser/PPCTargetParser.def
index 44e97d56a059c..ec3de5e3925ad 100644
--- a/llvm/include/llvm/TargetParser/PPCTargetParser.def
+++ b/llvm/include/llvm/TargetParser/PPCTargetParser.def
@@ -85,8 +85,59 @@
 #define AIX_PPC9_VALUE 0x00020000
 #define AIX_PPC10_VALUE 0x00040000
 
-// __builtin_cpu_is() and __builtin_cpu_supports() are supported only on Power7 and up on AIX.
 // PPC_CPU(Name, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD, AIXID)
+
+// Valid CPUs not supported by __builtin_cpu_is()
+PPC_CPU("generic",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("440",SYS_CALL,42,BUILTIN_PPC_FALSE,0)
+PPC_CPU("440fp",SYS_CALL,42,BUILTIN_PPC_FALSE,0)
+PPC_CPU("450",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("601",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("602",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("603",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("603e",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("603ev",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("604",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("604e",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("620",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("630",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("g3",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("7400",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("g4",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("7450",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("g4+",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("750",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("8548",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("970",SYS_CALL,33,BUILTIN_PPC_FALSE,0)
+PPC_CPU("g5",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("a2",SYS_CALL,40,BUILTIN_PPC_FALSE,0)
+PPC_CPU("e500",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("e500mc",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("e5500",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("power3",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr3",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr4",SYS_CALL,32,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr5",SYS_CALL,34,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr5+",SYS_CALL,35,BUILTIN_PPC_FALSE,0)
+PPC_CPU("power5x",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr5x",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr6",SYS_CALL,36,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr6x",SYS_CALL,38,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr7",SYS_CALL,39,USE_SYS_CONF,AIX_PPC7_VALUE)
+PPC_CPU("pwr8",SYS_CALL,45,USE_SYS_CONF,AIX_PPC8_VALUE)
+PPC_CPU("pwr9",SYS_CALL,46,USE_SYS_CONF,AIX_PPC9_VALUE)
+PPC_CPU("pwr10",SYS_CALL,47,USE_SYS_CONF,AIX_PPC10_VALUE)
+PPC_CPU("powerpc",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("ppc",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("ppc32",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("powerpc64",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("ppc64",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("powerpc64le",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("ppc64le",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("future",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+
+// __builtin_cpu_is() and __builtin_cpu_supports() are supported only on Power7 and up on AIX.
+// CPUs supported by __builtin_cpu_is().
 PPC_CPU("power4",SYS_CALL,32,BUILTIN_PPC_FALSE,0)
 PPC_CPU("ppc970",SYS_CALL,33,BUILTIN_PPC_FALSE,0)
 PPC_CPU("power5",SYS_CALL,34,BUILTIN_PPC_FALSE,0)
diff --git a/llvm/include/llvm/TargetParser/PPCTargetParser.h b/llvm/include/llvm/TargetParser/PPCTargetParser.h
new file mode 100644
index 0000000000000..e2d42270255bf
--- /dev/null
+++ b/llvm/include/llvm/TargetParser/PPCTargetParser.h
@@ -0,0 +1,37 @@
+//===---- PPCTargetParser - Parser for target features ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a target parser to recognise hardware features
+// for PPC CPUs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGETPARSER_PPCTARGETPARSER_H
+#define LLVM_TARGETPARSER_PPCTARGETPARSER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/TargetParser/Triple.h"
+
+namespace llvm {
+namespace PPC {
+bool isValidCPU(StringRef CPU);
+void fillValidCPUList(SmallVectorImpl<StringRef> &Values);
+void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values);
+
+// Get default target CPU for PPC.
+StringRef getPPCGenericTargetCPU(const Triple &T, StringRef CPUName = "");
+// Get default tune CPU for PPC.
+StringRef getPPCGenericTuneCPU(const Triple &T, StringRef CPUName = "");
+
+// For PPC, there are some cpu names for same CPU, like pwr10 and power10,
+// normalize them.
+StringRef normalizeCPUName(StringRef CPUName);
+} // namespace PPC
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/TargetParser/CMakeLists.txt b/llvm/lib/TargetParser/CMakeLists.txt
index 4b5d582d57a42..8ec32f7410566 100644
--- a/llvm/lib/TargetParser/CMakeLists.txt
+++ b/llvm/lib/TargetParser/CMakeLists.txt
@@ -20,6 +20,7 @@ add_llvm_component_library(LLVMTargetParser
   CSKYTargetParser.cpp
   Host.cpp
   LoongArchTargetParser.cpp
+  PPCTargetParser.cpp
   RISCVISAInfo.cpp
   RISCVTargetParser.cpp
   SubtargetFeature.cpp
diff --git a/llvm/lib/TargetParser/PPCTargetParser.cpp b/llvm/lib/TargetParser/PPCTargetParser.cpp
new file mode 100644
index 0000000000000..3c7a64c215f80
--- /dev/null
+++ b/llvm/lib/TargetParser/PPCTargetPar...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Jul 3, 2024

@llvm/pr-subscribers-clang

Author: Chen Zheng (chenzheng1030)

Changes

For now only focus on the CPU type, will work on the CPU features part later.

With the CPU handling in TargetParser, clang and llc/opt are able to query common interfaces.

So we can set same default CPU and CPU features with same interfaces.


Patch is 24.14 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/97541.diff

12 Files Affected:

  • (modified) clang/lib/Basic/Targets/PPC.cpp (+3-15)
  • (modified) clang/lib/Driver/ToolChains/Arch/PPC.cpp (-72)
  • (modified) clang/lib/Driver/ToolChains/Arch/PPC.h (-4)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+6-2)
  • (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+4-1)
  • (modified) clang/test/CodeGen/aix-builtin-cpu-is.c (+25-17)
  • (modified) clang/test/Misc/target-invalid-cpu-note.c (+1-1)
  • (modified) llvm/include/llvm/TargetParser/PPCTargetParser.def (+52-1)
  • (added) llvm/include/llvm/TargetParser/PPCTargetParser.h (+37)
  • (modified) llvm/lib/TargetParser/CMakeLists.txt (+1)
  • (added) llvm/lib/TargetParser/PPCTargetParser.cpp (+121)
  • (modified) llvm/utils/gn/secondary/llvm/lib/TargetParser/BUILD.gn (+1)
diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 89c5566f7ad09..5543f4a100c46 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -14,6 +14,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/MacroBuilder.h"
 #include "clang/Basic/TargetBuiltins.h"
+#include "llvm/TargetParser/PPCTargetParser.h"
 
 using namespace clang;
 using namespace clang::targets;
@@ -866,25 +867,12 @@ ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const {
   return llvm::ArrayRef(GCCAddlRegNames);
 }
 
-static constexpr llvm::StringLiteral ValidCPUNames[] = {
-    {"generic"},     {"440"},     {"450"},    {"601"},       {"602"},
-    {"603"},         {"603e"},    {"603ev"},  {"604"},       {"604e"},
-    {"620"},         {"630"},     {"g3"},     {"7400"},      {"g4"},
-    {"7450"},        {"g4+"},     {"750"},    {"8548"},      {"970"},
-    {"g5"},          {"a2"},      {"e500"},   {"e500mc"},    {"e5500"},
-    {"power3"},      {"pwr3"},    {"power4"}, {"pwr4"},      {"power5"},
-    {"pwr5"},        {"power5x"}, {"pwr5x"},  {"power6"},    {"pwr6"},
-    {"power6x"},     {"pwr6x"},   {"power7"}, {"pwr7"},      {"power8"},
-    {"pwr8"},        {"power9"},  {"pwr9"},   {"power10"},   {"pwr10"},
-    {"powerpc"},     {"ppc"},     {"ppc32"},  {"powerpc64"}, {"ppc64"},
-    {"powerpc64le"}, {"ppc64le"}, {"future"}};
-
 bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
-  return llvm::is_contained(ValidCPUNames, Name);
+  return llvm::PPC::isValidCPU(Name);
 }
 
 void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
-  Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
+  llvm::PPC::fillValidCPUList(Values);
 }
 
 void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
diff --git a/clang/lib/Driver/ToolChains/Arch/PPC.cpp b/clang/lib/Driver/ToolChains/Arch/PPC.cpp
index 634c096523319..b63e16c22370d 100644
--- a/clang/lib/Driver/ToolChains/Arch/PPC.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/PPC.cpp
@@ -20,78 +20,6 @@ using namespace clang::driver::tools;
 using namespace clang;
 using namespace llvm::opt;
 
-static std::string getPPCGenericTargetCPU(const llvm::Triple &T) {
-  // LLVM may default to generating code for the native CPU,
-  // but, like gcc, we default to a more generic option for
-  // each architecture. (except on AIX)
-  if (T.isOSAIX())
-    return "pwr7";
-  else if (T.getArch() == llvm::Triple::ppc64le)
-    return "ppc64le";
-  else if (T.getArch() == llvm::Triple::ppc64)
-    return "ppc64";
-  else
-    return "ppc";
-}
-
-static std::string normalizeCPUName(StringRef CPUName, const llvm::Triple &T) {
-  // Clang/LLVM does not actually support code generation
-  // for the 405 CPU. However, there are uses of this CPU ID
-  // in projects that previously used GCC and rely on Clang
-  // accepting it. Clang has always ignored it and passed the
-  // generic CPU ID to the back end.
-  if (CPUName == "generic" || CPUName == "405")
-    return getPPCGenericTargetCPU(T);
-
-  if (CPUName == "native") {
-    std::string CPU = std::string(llvm::sys::getHostCPUName());
-    if (!CPU.empty() && CPU != "generic")
-      return CPU;
-    else
-      return getPPCGenericTargetCPU(T);
-  }
-
-  return llvm::StringSwitch<const char *>(CPUName)
-      .Case("common", "generic")
-      .Case("440fp", "440")
-      .Case("630", "pwr3")
-      .Case("G3", "g3")
-      .Case("G4", "g4")
-      .Case("G4+", "g4+")
-      .Case("8548", "e500")
-      .Case("G5", "g5")
-      .Case("power3", "pwr3")
-      .Case("power4", "pwr4")
-      .Case("power5", "pwr5")
-      .Case("power5x", "pwr5x")
-      .Case("power6", "pwr6")
-      .Case("power6x", "pwr6x")
-      .Case("power7", "pwr7")
-      .Case("power8", "pwr8")
-      .Case("power9", "pwr9")
-      .Case("power10", "pwr10")
-      .Case("future", "future")
-      .Case("powerpc", "ppc")
-      .Case("powerpc64", "ppc64")
-      .Case("powerpc64le", "ppc64le")
-      .Default(CPUName.data());
-}
-
-/// Get the (LLVM) name of the PowerPC cpu we are tuning for.
-std::string ppc::getPPCTuneCPU(const ArgList &Args, const llvm::Triple &T) {
-  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))
-    return normalizeCPUName(A->getValue(), T);
-  return getPPCGenericTargetCPU(T);
-}
-
-/// Get the (LLVM) name of the PowerPC cpu we are targeting.
-std::string ppc::getPPCTargetCPU(const Driver &D, const ArgList &Args,
-                                 const llvm::Triple &T) {
-  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
-    return normalizeCPUName(A->getValue(), T);
-  return getPPCGenericTargetCPU(T);
-}
-
 const char *ppc::getPPCAsmModeForCPU(StringRef Name) {
   return llvm::StringSwitch<const char *>(Name)
       .Case("pwr7", "-mpower7")
diff --git a/clang/lib/Driver/ToolChains/Arch/PPC.h b/clang/lib/Driver/ToolChains/Arch/PPC.h
index ec5b3c8140b66..89b9af92e8ddb 100644
--- a/clang/lib/Driver/ToolChains/Arch/PPC.h
+++ b/clang/lib/Driver/ToolChains/Arch/PPC.h
@@ -35,10 +35,6 @@ enum class ReadGOTPtrMode {
 
 FloatABI getPPCFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
 
-std::string getPPCTargetCPU(const Driver &D, const llvm::opt::ArgList &Args,
-                            const llvm::Triple &T);
-std::string getPPCTuneCPU(const llvm::opt::ArgList &Args,
-                          const llvm::Triple &T);
 const char *getPPCAsmModeForCPU(StringRef Name);
 ReadGOTPtrMode getPPCReadGOTPtrMode(const Driver &D, const llvm::Triple &Triple,
                                     const llvm::opt::ArgList &Args);
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 27c451c565f2b..607a6cda6ae3f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -60,6 +60,7 @@
 #include "llvm/TargetParser/ARMTargetParserCommon.h"
 #include "llvm/TargetParser/Host.h"
 #include "llvm/TargetParser/LoongArchTargetParser.h"
+#include "llvm/TargetParser/PPCTargetParser.h"
 #include "llvm/TargetParser/RISCVISAInfo.h"
 #include "llvm/TargetParser/RISCVTargetParser.h"
 #include <cctype>
@@ -1963,8 +1964,11 @@ void Clang::AddPPCTargetArgs(const ArgList &Args,
   const llvm::Triple &T = getToolChain().getTriple();
   if (Args.getLastArg(options::OPT_mtune_EQ)) {
     CmdArgs.push_back("-tune-cpu");
-    std::string CPU = ppc::getPPCTuneCPU(Args, T);
-    CmdArgs.push_back(Args.MakeArgString(CPU));
+    StringRef CPU = "";
+    if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))
+      CPU = A->getValue();
+    CPU = llvm::PPC::getPPCGenericTuneCPU(T, CPU);
+    CmdArgs.push_back(Args.MakeArgString(CPU.str()));
   }
 
   // Select the ABI to use.
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index be4d7d2cffb16..4c8de4e9db63c 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -64,6 +64,7 @@
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/YAMLParser.h"
 #include "llvm/TargetParser/Host.h"
+#include "llvm/TargetParser/PPCTargetParser.h"
 #include "llvm/TargetParser/TargetParser.h"
 #include <optional>
 
@@ -629,7 +630,9 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
   case llvm::Triple::ppcle:
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le:
-    return ppc::getPPCTargetCPU(D, Args, T);
+    if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
+      return std::string(llvm::PPC::getPPCGenericTargetCPU(T, A->getValue()));
+    return std::string(llvm::PPC::getPPCGenericTargetCPU(T));
 
   case llvm::Triple::csky:
     if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
diff --git a/clang/test/CodeGen/aix-builtin-cpu-is.c b/clang/test/CodeGen/aix-builtin-cpu-is.c
index e17cf7353511a..fe321346b9d97 100644
--- a/clang/test/CodeGen/aix-builtin-cpu-is.c
+++ b/clang/test/CodeGen/aix-builtin-cpu-is.c
@@ -1,52 +1,60 @@
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc970\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc970\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc-cell-be\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc-cell-be\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppca2\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppca2\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc405\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc405\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc440\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc440\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc464\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc464\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"ppc476\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"ppc476\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power4\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power4\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power5\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power5\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power5+\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power5+\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power6\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power6\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power6x\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power6x\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power7\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power7\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=32768 \
 // RUN:   --check-prefix=CHECKOP
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power8\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"pwr7\");}" > %t.c
+// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=32768 \
+// RUN:   --check-prefix=CHECKOP
+
+// RUN: echo "int main() { return __builtin_cpu_is(\"power8\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=65536 \
 // RUN:   --check-prefix=CHECKOP
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power9\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power9\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=131072\
 // RUN:   --check-prefix=CHECKOP
 
-// RUN: echo "int main() { return __builtin_cpu_is(\"power10\");}" > %t.c 
+// RUN: echo "int main() { return __builtin_cpu_is(\"power10\");}" > %t.c
+// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=262144 \
+// RUN:   --check-prefix=CHECKOP
+
+// RUN: echo "int main() { return __builtin_cpu_is(\"pwr10\");}" > %t.c
 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=262144 \
 // RUN:   --check-prefix=CHECKOP
 
@@ -63,7 +71,7 @@
 // CHECKOP-NEXT:   %retval = alloca i32, align 4
 // CHECKOP-NEXT:   store i32 0, ptr %retval, align 4
 // CHECKOP-NEXT:   %0 = load i32, ptr getelementptr inbounds ({ i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i64, i32, i32, i32, i32, i64, i64, i64, i64, i32, i32, i32, i32, i32, i32, i64, i32, i8, i8, i8, i8, i32, i32, i16, i16, [3 x i32], i32 }, ptr @_system_configuration, i32 0, i32 1), align 4
-// CHECKOP-NEXT:   %1 = icmp eq i32 %0, [[VALUE]] 
+// CHECKOP-NEXT:   %1 = icmp eq i32 %0, [[VALUE]]
 // CHECKOP-NEXT:  %conv = zext i1 %1 to i32
 // CHECKOP-NEXT:   ret i32 %conv
 // CHECKOP-NEXT: }
diff --git a/clang/test/Misc/target-invalid-cpu-note.c b/clang/test/Misc/target-invalid-cpu-note.c
index a5f9ffa21220a..b77874acbfb9a 100644
--- a/clang/test/Misc/target-invalid-cpu-note.c
+++ b/clang/test/Misc/target-invalid-cpu-note.c
@@ -57,7 +57,7 @@
 
 // RUN: not %clang_cc1 -triple powerpc--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix PPC
 // PPC: error: unknown target CPU 'not-a-cpu'
-// PPC-NEXT: note: valid target CPU values are: generic, 440, 450, 601, 602, 603, 603e, 603ev, 604, 604e, 620, 630, g3, 7400, g4, 7450, g4+, 750, 8548, 970, g5, a2, e500, e500mc, e5500, power3, pwr3, power4, pwr4, power5, pwr5, power5x, pwr5x, power6, pwr6, power6x, pwr6x, power7, pwr7, power8, pwr8, power9, pwr9, power10, pwr10, powerpc, ppc, ppc32, powerpc64, ppc64, powerpc64le, ppc64le, future{{$}}
+// PPC-NEXT: note: valid target CPU values are: generic, 440, 440fp, 450, 601, 602, 603, 603e, 603ev, 604, 604e, 620, 630, g3, 7400, g4, 7450, g4+, 750, 8548, 970, g5, a2, e500, e500mc, e5500, power3, pwr3, pwr4, pwr5, pwr5+, power5x, pwr5x, pwr6, pwr6x, pwr7, pwr8, pwr9, pwr10, powerpc, ppc, ppc32, powerpc64, ppc64, powerpc64le, ppc64le, future, power4, ppc970, power5, power5+, power6, ppc-cell-be, power6x, power7, ppca2, ppc405, ppc440, ppc464, ppc476, power8, power9, power10{{$}}
 
 // RUN: not %clang_cc1 -triple mips--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix MIPS
 // MIPS: error: unknown target CPU 'not-a-cpu'
diff --git a/llvm/include/llvm/TargetParser/PPCTargetParser.def b/llvm/include/llvm/TargetParser/PPCTargetParser.def
index 44e97d56a059c..ec3de5e3925ad 100644
--- a/llvm/include/llvm/TargetParser/PPCTargetParser.def
+++ b/llvm/include/llvm/TargetParser/PPCTargetParser.def
@@ -85,8 +85,59 @@
 #define AIX_PPC9_VALUE 0x00020000
 #define AIX_PPC10_VALUE 0x00040000
 
-// __builtin_cpu_is() and __builtin_cpu_supports() are supported only on Power7 and up on AIX.
 // PPC_CPU(Name, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD, AIXID)
+
+// Valid CPUs not supported by __builtin_cpu_is()
+PPC_CPU("generic",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("440",SYS_CALL,42,BUILTIN_PPC_FALSE,0)
+PPC_CPU("440fp",SYS_CALL,42,BUILTIN_PPC_FALSE,0)
+PPC_CPU("450",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("601",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("602",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("603",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("603e",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("603ev",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("604",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("604e",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("620",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("630",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("g3",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("7400",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("g4",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("7450",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("g4+",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("750",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("8548",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("970",SYS_CALL,33,BUILTIN_PPC_FALSE,0)
+PPC_CPU("g5",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("a2",SYS_CALL,40,BUILTIN_PPC_FALSE,0)
+PPC_CPU("e500",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("e500mc",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("e5500",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("power3",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr3",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr4",SYS_CALL,32,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr5",SYS_CALL,34,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr5+",SYS_CALL,35,BUILTIN_PPC_FALSE,0)
+PPC_CPU("power5x",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr5x",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr6",SYS_CALL,36,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr6x",SYS_CALL,38,BUILTIN_PPC_FALSE,0)
+PPC_CPU("pwr7",SYS_CALL,39,USE_SYS_CONF,AIX_PPC7_VALUE)
+PPC_CPU("pwr8",SYS_CALL,45,USE_SYS_CONF,AIX_PPC8_VALUE)
+PPC_CPU("pwr9",SYS_CALL,46,USE_SYS_CONF,AIX_PPC9_VALUE)
+PPC_CPU("pwr10",SYS_CALL,47,USE_SYS_CONF,AIX_PPC10_VALUE)
+PPC_CPU("powerpc",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("ppc",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("ppc32",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("powerpc64",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("ppc64",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("powerpc64le",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("ppc64le",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+PPC_CPU("future",BUILTIN_PPC_FALSE,0,BUILTIN_PPC_FALSE,0)
+
+// __builtin_cpu_is() and __builtin_cpu_supports() are supported only on Power7 and up on AIX.
+// CPUs supported by __builtin_cpu_is().
 PPC_CPU("power4",SYS_CALL,32,BUILTIN_PPC_FALSE,0)
 PPC_CPU("ppc970",SYS_CALL,33,BUILTIN_PPC_FALSE,0)
 PPC_CPU("power5",SYS_CALL,34,BUILTIN_PPC_FALSE,0)
diff --git a/llvm/include/llvm/TargetParser/PPCTargetParser.h b/llvm/include/llvm/TargetParser/PPCTargetParser.h
new file mode 100644
index 0000000000000..e2d42270255bf
--- /dev/null
+++ b/llvm/include/llvm/TargetParser/PPCTargetParser.h
@@ -0,0 +1,37 @@
+//===---- PPCTargetParser - Parser for target features ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a target parser to recognise hardware features
+// for PPC CPUs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGETPARSER_PPCTARGETPARSER_H
+#define LLVM_TARGETPARSER_PPCTARGETPARSER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/TargetParser/Triple.h"
+
+namespace llvm {
+namespace PPC {
+bool isValidCPU(StringRef CPU);
+void fillValidCPUList(SmallVectorImpl<StringRef> &Values);
+void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values);
+
+// Get default target CPU for PPC.
+StringRef getPPCGenericTargetCPU(const Triple &T, StringRef CPUName = "");
+// Get default tune CPU for PPC.
+StringRef getPPCGenericTuneCPU(const Triple &T, StringRef CPUName = "");
+
+// For PPC, there are some cpu names for same CPU, like pwr10 and power10,
+// normalize them.
+StringRef normalizeCPUName(StringRef CPUName);
+} // namespace PPC
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/TargetParser/CMakeLists.txt b/llvm/lib/TargetParser/CMakeLists.txt
index 4b5d582d57a42..8ec32f7410566 100644
--- a/llvm/lib/TargetParser/CMakeLists.txt
+++ b/llvm/lib/TargetParser/CMakeLists.txt
@@ -20,6 +20,7 @@ add_llvm_component_library(LLVMTargetParser
   CSKYTargetParser.cpp
   Host.cpp
   LoongArchTargetParser.cpp
+  PPCTargetParser.cpp
   RISCVISAInfo.cpp
   RISCVTargetParser.cpp
   SubtargetFeature.cpp
diff --git a/llvm/lib/TargetParser/PPCTargetParser.cpp b/llvm/lib/TargetParser/PPCTargetParser.cpp
new file mode 100644
index 0000000000000..3c7a64c215f80
--- /dev/null
+++ b/llvm/lib/TargetParser/PPCTargetPar...
[truncated]

Copy link

github-actions bot commented Jul 3, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

// Get default target CPU for PPC.
StringRef getPPCGenericTargetCPU(const Triple &T, StringRef CPUName = "");
// Get default tune CPU for PPC.
StringRef getPPCGenericTuneCPU(const Triple &T, StringRef CPUName = "");
Copy link
Member

Choose a reason for hiding this comment

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

We should rename this method (remove Generic or similar). Previous getPPCGenericTargetCPU does not have extra CPUName as parameter. What this function does now is not only returning a generic CPU for a platform.

Copy link
Collaborator Author

@chenzheng1030 chenzheng1030 left a comment

Choose a reason for hiding this comment

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

Thanks for your comments @daltenty @ecnelises . Comments addressed.

@chenzheng1030
Copy link
Collaborator Author

gentle ping : )

@chenzheng1030
Copy link
Collaborator Author

ping : )

Sorry, I may commit this directly if I don't get any further comments. I have follow up patches based on this one. Thanks.

Copy link
Member

@daltenty daltenty left a comment

Choose a reason for hiding this comment

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

Sorry for the delay, LGTM

@chenzheng1030 chenzheng1030 force-pushed the llc_cpu branch 2 times, most recently from abe45fe to 3b7cd8f Compare July 24, 2024 09:08
For now only focus on the CPU type, will work on the CPU features part later.
@chenzheng1030 chenzheng1030 merged commit 25482b3 into llvm:main Jul 25, 2024
4 of 7 checks passed
@chenzheng1030 chenzheng1030 deleted the llc_cpu branch July 25, 2024 05:47
chenzheng1030 pushed a commit that referenced this pull request Jul 25, 2024
for platform that returns nothing for getHostCPUName()
For example for target ARM on windows. For this case, -mcpu=native
should set CPU to the default according to triple instead of setting
CPU to "native"

Fixes https://lab.llvm.org/buildbot/#/builders/161/builds/873 caused by
#97541
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
Summary:
For now only focus on the CPU type, will work on the CPU features part
later.

With the CPU handling in TargetParser, clang and llc/opt are able to
query common interfaces.

So we can set same default CPU and CPU features with same interfaces.

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60250758
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
Summary:
for platform that returns nothing for getHostCPUName()
For example for target ARM on windows. For this case, -mcpu=native
should set CPU to the default according to triple instead of setting
CPU to "native"

Fixes https://lab.llvm.org/buildbot/#/builders/161/builds/873 caused by
#97541

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60250515
diggerlin added a commit that referenced this pull request Nov 4, 2024
…113943)

Utilize common API in PPCTargetParser
(#97541) to set default CPU
with same interfaces for LLC.
This will update AIX default CPU to pwr7 and LoP powerppc64 default CPU
to ppc64.
PhilippRados pushed a commit to PhilippRados/llvm-project that referenced this pull request Nov 6, 2024
…lvm#113943)

Utilize common API in PPCTargetParser
(llvm#97541) to set default CPU
with same interfaces for LLC.
This will update AIX default CPU to pwr7 and LoP powerppc64 default CPU
to ppc64.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:PowerPC clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants