https://github.com/w2yehia updated 
https://github.com/llvm/llvm-project/pull/177428

>From f9ed73b88719aba0693e8a67fcf22fc866828478 Mon Sep 17 00:00:00 2001
From: Wael Yehia <[email protected]>
Date: Tue, 23 Sep 2025 14:22:57 -0400
Subject: [PATCH 1/6] refactor EmitPPCBuiltinCpu

---
 clang/lib/CodeGen/CodeGenFunction.h      |  1 +
 clang/lib/CodeGen/TargetBuiltins/PPC.cpp | 62 +++++++++++++-----------
 2 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 855e43631f436..2391ff76c05fe 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4869,6 +4869,7 @@ class CodeGenFunction : public CodeGenTypeCache {
 
   llvm::Value *BuildVector(ArrayRef<llvm::Value *> Ops);
   llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
+  llvm::Value *EmitPPCBuiltinCpu(unsigned BuiltinID, llvm::Type *ReturnType, 
StringRef CPUStr);
   llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
   llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
   llvm::Value *EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
diff --git a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp 
b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
index 1e1127350c301..ea25ed691b454 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -70,31 +70,18 @@ static llvm::Value 
*emitPPCLoadReserveIntrinsic(CodeGenFunction &CGF,
   return CI;
 }
 
-Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
-                                           const CallExpr *E) {
-  // Do not emit the builtin arguments in the arguments of a function call,
-  // because the evaluation order of function arguments is not specified in 
C++.
-  // This is important when testing to ensure the arguments are emitted in the
-  // same order every time. Eg:
-  // Instead of:
-  //   return Builder.CreateFDiv(EmitScalarExpr(E->getArg(0)),
-  //                             EmitScalarExpr(E->getArg(1)), "swdiv");
-  // Use:
-  //   Value *Op0 = EmitScalarExpr(E->getArg(0));
-  //   Value *Op1 = EmitScalarExpr(E->getArg(1));
-  //   return Builder.CreateFDiv(Op0, Op1, "swdiv")
-
-  Intrinsic::ID ID = Intrinsic::not_intrinsic;
+Value *CodeGenFunction::EmitPPCBuiltinCpu(
+    unsigned BuiltinID, llvm::Type *ReturnType, StringRef CPUStr) {
 
 #include "llvm/TargetParser/PPCTargetParser.def"
   auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx,
                                      unsigned Mask, CmpInst::Predicate CompOp,
                                      unsigned OpValue) -> Value * {
     if (SupportMethod == BUILTIN_PPC_FALSE)
-      return llvm::ConstantInt::getFalse(ConvertType(E->getType()));
+      return llvm::ConstantInt::getFalse(ReturnType);
 
     if (SupportMethod == BUILTIN_PPC_TRUE)
-      return llvm::ConstantInt::getTrue(ConvertType(E->getType()));
+      return llvm::ConstantInt::getTrue(ReturnType);
 
     assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod.");
 
@@ -137,12 +124,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned 
BuiltinID,
         ConstantInt::get(IsValueType64Bit ? Int64Ty : Int32Ty, OpValue));
   };
 
-  switch (BuiltinID) {
-  default: return nullptr;
-
-  case Builtin::BI__builtin_cpu_is: {
-    const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
-    StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
+  if (BuiltinID == Builtin::BI__builtin_cpu_is) {
     llvm::Triple Triple = getTarget().getTriple();
 
     typedef std::tuple<unsigned, unsigned, unsigned, unsigned> CPUInfo;
@@ -170,7 +152,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned 
BuiltinID,
            "Invalid CPU name. Missed by SemaChecking?");
 
     if (LinuxSupportMethod == BUILTIN_PPC_FALSE)
-      return llvm::ConstantInt::getFalse(ConvertType(E->getType()));
+      return llvm::ConstantInt::getFalse(ReturnType);
 
     Value *Op0 = llvm::ConstantInt::get(Int32Ty, PPC_FAWORD_CPUID);
     llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_fixed_addr_ld);
@@ -178,10 +160,8 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned 
BuiltinID,
     return Builder.CreateICmpEQ(TheCall,
                                 llvm::ConstantInt::get(Int32Ty, LinuxIDValue));
   }
-  case Builtin::BI__builtin_cpu_supports: {
+  else if (BuiltinID == Builtin::BI__builtin_cpu_supports) {
     llvm::Triple Triple = getTarget().getTriple();
-    const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
-    StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
     if (Triple.isOSAIX()) {
       typedef std::tuple<unsigned, unsigned, unsigned, CmpInst::Predicate,
                          unsigned>
@@ -218,7 +198,35 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned 
BuiltinID,
 #undef PPC_FAWORD_HWCAP2
 #undef PPC_FAWORD_CPUID
   }
+  else
+    assert(0 && "unexpected builtin");
+}
 
+Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
+                                           const CallExpr *E) {
+  // Do not emit the builtin arguments in the arguments of a function call,
+  // because the evaluation order of function arguments is not specified in 
C++.
+  // This is important when testing to ensure the arguments are emitted in the
+  // same order every time. Eg:
+  // Instead of:
+  //   return Builder.CreateFDiv(EmitScalarExpr(E->getArg(0)),
+  //                             EmitScalarExpr(E->getArg(1)), "swdiv");
+  // Use:
+  //   Value *Op0 = EmitScalarExpr(E->getArg(0));
+  //   Value *Op1 = EmitScalarExpr(E->getArg(1));
+  //   return Builder.CreateFDiv(Op0, Op1, "swdiv")
+
+  Intrinsic::ID ID = Intrinsic::not_intrinsic;
+
+  switch (BuiltinID) {
+  default: return nullptr;
+
+  case Builtin::BI__builtin_cpu_is:
+  case Builtin::BI__builtin_cpu_supports: {
+    const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
+    StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
+    return EmitPPCBuiltinCpu(BuiltinID, ConvertType(E->getType()), CPUStr);
+  }
   // __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we
   // call __builtin_readcyclecounter.
   case PPC::BI__builtin_ppc_get_timebase:

>From 6ec855bbb7744f4e618844ce9708dab2ce3ed528 Mon Sep 17 00:00:00 2001
From: Wael Yehia <[email protected]>
Date: Wed, 16 Jul 2025 20:02:11 +0000
Subject: [PATCH 2/6] clang codegen for target_clones

---
 clang/include/clang/Basic/TargetInfo.h |  2 +-
 clang/include/clang/Sema/SemaPPC.h     |  4 ++
 clang/lib/AST/ASTContext.cpp           |  2 +
 clang/lib/Basic/Targets/PPC.cpp        | 36 +++++++++++++
 clang/lib/Basic/Targets/PPC.h          |  4 ++
 clang/lib/CodeGen/CodeGenFunction.cpp  | 70 +++++++++++++++++++++++++-
 clang/lib/CodeGen/CodeGenFunction.h    |  3 ++
 clang/lib/CodeGen/CodeGenModule.cpp    | 10 ++--
 clang/lib/CodeGen/Targets/PPC.cpp      | 47 +++++++++++++++++
 clang/lib/Sema/SemaDeclAttr.cpp        |  4 ++
 clang/lib/Sema/SemaPPC.cpp             | 56 +++++++++++++++++++++
 11 files changed, 231 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 89e1d7c99426f..0b07093e09fb5 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1564,7 +1564,7 @@ class TargetInfo : public TransferrableTargetInfo,
   /// which requires support for cpu_supports and cpu_is functionality.
   bool supportsMultiVersioning() const {
     return getTriple().isX86() || getTriple().isAArch64() ||
-           getTriple().isRISCV();
+           getTriple().isRISCV() || getTriple().isOSBinFormatXCOFF();
   }
 
   /// Identify whether this target supports IFuncs.
diff --git a/clang/include/clang/Sema/SemaPPC.h 
b/clang/include/clang/Sema/SemaPPC.h
index f8edecc4fcb7b..0cf6ba7ff29dd 100644
--- a/clang/include/clang/Sema/SemaPPC.h
+++ b/clang/include/clang/Sema/SemaPPC.h
@@ -53,6 +53,10 @@ class SemaPPC : public SemaBase {
   // vector double vec_xxpermdi(vector double, vector double, int);
   // vector short vec_xxsldwi(vector short, vector short, int);
   bool BuiltinVSX(CallExpr *TheCall);
+
+  bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
+                             SmallVectorImpl<SourceLocation> &Locs,
+                             SmallVectorImpl<SmallString<64>> &NewParams);
 };
 } // namespace clang
 
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index f52470a4d7458..223f65ed1bf95 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -15021,6 +15021,8 @@ void 
ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
       StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
       if (VersionStr.starts_with("arch="))
         TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1);
+      else if (Target->getTriple().isOSAIX() && 
VersionStr.starts_with("cpu=")) // TODO make a function that extracts CPU from 
a feature string
+        TargetCPU = VersionStr.drop_front(sizeof("cpu=") - 1);
       else if (VersionStr != "default")
         Features.push_back((StringRef{"+"} + VersionStr).str());
       Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, 
Features);
diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index a6e1ad10568bb..517e429ddfa1a 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -671,6 +671,42 @@ void 
PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
   }
 }
 
+ParsedTargetAttr PPCTargetInfo::parseTargetAttr(StringRef Features) const {
+  ParsedTargetAttr Ret;
+  if (Features == "default")
+    return Ret;
+  SmallVector<StringRef, 1> AttrFeatures;
+  Features.split(AttrFeatures, ",");
+
+  // Grab the various features and prepend a "+" to turn on the feature to
+  // the backend and add them to our existing set of features.
+  for (auto &Feature : AttrFeatures) {
+    // Go ahead and trim whitespace rather than either erroring or
+    // accepting it weirdly.
+    Feature = Feature.trim();
+
+    // While we're here iterating check for a different target cpu.
+    if (Feature.starts_with("cpu=")) {
+      assert(Ret.CPU.empty());
+      Ret.CPU = Feature.split("=").second.trim();
+    } else assert(0);
+//    else if (Feature.starts_with("tune=")) {
+//      if (!Ret.Tune.empty())
+//        Ret.Duplicate = "tune=";
+//      else
+//        Ret.Tune = Feature.split("=").second.trim();
+//    } else if (Feature.starts_with("no-"))
+//      Ret.Features.push_back("-" + Feature.split("-").second.str());
+//    else
+//      Ret.Features.push_back("+" + Feature.str());
+  }
+  return Ret;
+}
+
+llvm::APInt PPCTargetInfo::getFMVPriority(ArrayRef<StringRef> Features) const {
+  return llvm::APInt(32, Features.empty() ? 0 : 1);
+}
+
 // Make sure that registers are added in the correct array index which should 
be
 // the DWARF number for PPC registers.
 const char *const PPCTargetInfo::GCCRegNames[] = {
diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index 664c9e15d8d18..6f90ff1f5d57c 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -199,6 +199,10 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public 
TargetInfo {
 
   bool supportsTargetAttributeTune() const override { return true; }
 
+  ParsedTargetAttr parseTargetAttr(StringRef Str) const override;
+
+  llvm::APInt getFMVPriority(ArrayRef<StringRef> Features) const override;
+
   ArrayRef<const char *> getGCCRegNames() const override;
 
   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp 
b/clang/lib/CodeGen/CodeGenFunction.cpp
index 02947c1df2c59..f52bd212a4170 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsPowerPC.h"
 #include "llvm/IR/MDBuilder.h"
 #include "llvm/Support/CRC.h"
 #include "llvm/Support/xxhash.h"
@@ -3009,12 +3010,77 @@ void CodeGenFunction::EmitMultiVersionResolver(
   case llvm::Triple::riscv64:
     EmitRISCVMultiVersionResolver(Resolver, Options);
     return;
-
+  case llvm::Triple::ppc:
+  case llvm::Triple::ppc64:
+    if (getContext().getTargetInfo().getTriple().isOSAIX()) {
+      EmitPPCAIXMultiVersionResolver(Resolver, Options);
+      return;
+    }
+    [[fallthrough]];
   default:
-    assert(false && "Only implemented for x86, AArch64 and RISC-V targets");
+    assert(false && "Only implemented for x86, AArch64, RISC-V, and PowerPC 
targets");
+  }
+}
+
+/*
+ *  Desc_t *foo_desc = ppc_get_function_descriptor(&foo);
+ *  if (foo_desc->addr == ppc_get_function_entry(&foo)) {
+ *    FuncPtr fp = resolver();
+ *    __c11_atomic_store((_Atomic FuncPtr *)&foo_desc->addr, fp, 0);
+ *  }
+ *  return ((int (*)(int)) foo_desc)(a);
+ */
+void CodeGenFunction::EmitPPCAIXMultiVersionResolver(
+               llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {
+
+  llvm::PointerType *PtrTy = Builder.getPtrTy();
+  // entry:
+  llvm::BasicBlock *CurBlock = createBasicBlock("entry", Resolver);
+
+  SmallVector<std::pair<llvm::Value *, llvm::BasicBlock *>, 3> PhiArgs;
+  for (const FMVResolverOption &RO : Options) {
+    Builder.SetInsertPoint(CurBlock);
+    // The 'default' or 'generic' case.
+    if (!RO.Architecture && RO.Features.empty()) {
+      // if.default:
+      //   %fmv.default = call ptr @getEntryPoint(ptr noundef @foo_default)
+      //   br label %resolver_exit
+      assert(&RO == Options.end() - 1 && "Default or Generic case must be 
last");
+      Builder.CreateRet(RO.Function);
+      break;
+    }
+    // if.else_n:
+    //   %is_version_n = __builtin_cpu_supports(version_n)
+    //   br i1 %is_version_n, label %if.version_n, label %if.default
+    //
+    // if.version_n:
+    //   %fmv.version.n = call ptr @getEntryPoint(ptr noundef @foo_version_n)
+    //   br label %resolver_exit
+    assert(RO.Features.size() == 1 && "for now one feature requirement per 
version");
+    llvm::Value *Condition;
+    if (RO.Features[0].starts_with("cpu=")) {
+      Condition = EmitPPCBuiltinCpu(Builtin::BI__builtin_cpu_is, 
Builder.getInt1Ty(), RO.Features[0].split("=").second.trim());
+    } else {
+      Condition = EmitPPCBuiltinCpu(Builtin::BI__builtin_cpu_supports, 
Builder.getInt1Ty(), RO.Features[0]);
+    }
+    llvm::BasicBlock *ThenBlock = createBasicBlock("if.version", Resolver);
+    CurBlock = createBasicBlock("if.else", Resolver);
+    Builder.CreateCondBr(Condition, ThenBlock, CurBlock);
+
+    Builder.SetInsertPoint(ThenBlock);
+    Builder.CreateRet(RO.Function);
   }
+
+  // If no generic/default, emit an unreachable.
+//  Builder.SetInsertPoint(CurBlock);
+//  llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
+//  TrapCall->setDoesNotReturn();
+//  TrapCall->setDoesNotThrow();
+//  Builder.CreateUnreachable();
+//  Builder.ClearInsertionPoint();
 }
 
+
 void CodeGenFunction::EmitRISCVMultiVersionResolver(
     llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {
 
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 2391ff76c05fe..978dc2602a469 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -5537,6 +5537,9 @@ class CodeGenFunction : public CodeGenTypeCache {
   void EmitRISCVMultiVersionResolver(llvm::Function *Resolver,
                                      ArrayRef<FMVResolverOption> Options);
 
+  void EmitPPCAIXMultiVersionResolver(llvm::Function *Resolver,
+                                     ArrayRef<FMVResolverOption> Options);
+
 private:
   QualType getVarArgType(const Expr *Arg);
 
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 85ed38f144627..4d9b000dfa52e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2952,9 +2952,10 @@ bool 
CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD,
     // While we populated the feature map above, we still need to
     // get and parse the target attribute so we can get the cpu for
     // the function.
-    if (TD) {
-      ParsedTargetAttr ParsedAttr =
-          Target.parseTargetAttr(TD->getFeaturesStr());
+    StringRef FeatureStr = TD ? TD->getFeaturesStr() :
+                          (TC ? TC->getFeatureStr(GD.getMultiVersionIndex()) : 
StringRef());
+    if (!FeatureStr.empty()) {
+      ParsedTargetAttr ParsedAttr = Target.parseTargetAttr(FeatureStr);
       if (!ParsedAttr.CPU.empty() &&
           getTarget().isValidCPUName(ParsedAttr.CPU)) {
         TargetCPU = ParsedAttr.CPU;
@@ -4715,7 +4716,8 @@ void CodeGenModule::emitMultiVersionFunctions() {
     if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) {
       ResolverConstant = IFunc->getResolver();
       if (FD->isTargetClonesMultiVersion() &&
-          !getTarget().getTriple().isAArch64()) {
+          !getTarget().getTriple().isAArch64() &&
+                 !getTarget().getTriple().isOSAIX()) {
         std::string MangledName = getMangledNameImpl(
             *this, GD, FD, /*OmitMultiVersionMangling=*/true);
         if (!GetGlobalValue(MangledName + ".ifunc")) {
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp 
b/clang/lib/CodeGen/Targets/PPC.cpp
index 35e7655646ade..bc357e0908a5e 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -128,8 +128,55 @@ class AIXABIInfo : public ABIInfo {
 
   RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
                    AggValueSlot Slot) const override;
+
+  using ABIInfo::appendAttributeMangling;
+  void appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
+                               raw_ostream &Out) const override;
+  void appendAttributeMangling(StringRef AttrStr,
+                               raw_ostream &Out) const override;
 };
 
+void AIXABIInfo::appendAttributeMangling(TargetClonesAttr *Attr,
+                                         unsigned Index,
+                                         raw_ostream &Out) const {
+  appendAttributeMangling(Attr->getFeatureStr(Index), Out);
+}
+
+void AIXABIInfo::appendAttributeMangling(StringRef AttrStr,
+                                         raw_ostream &Out) const {
+  if (AttrStr == "default") {
+    Out << ".default";
+    return;
+  }
+
+  Out << '.';
+  const TargetInfo &TI = CGT.getTarget();
+  ParsedTargetAttr Info = TI.parseTargetAttr(AttrStr);
+
+  llvm::sort(Info.Features, [&TI](StringRef LHS, StringRef RHS) {
+    // Multiversioning doesn't allow "no-${feature}", so we can
+    // only have "+" prefixes here.
+    assert(LHS.starts_with("+") && RHS.starts_with("+") &&
+           "Features should always have a prefix.");
+    return TI.getFMVPriority({LHS.substr(1)})
+            .ugt(TI.getFMVPriority({RHS.substr(1)}));
+  });
+
+  bool IsFirst = true;
+  if (!Info.CPU.empty()) {
+    IsFirst = false;
+    Out << "cpu_" << Info.CPU;
+  }
+
+  assert(Info.Features.empty() && "unhandled case");
+  for (StringRef Feat : Info.Features) {
+    if (!IsFirst)
+      Out << '_';
+    IsFirst = false;
+    Out << Feat.substr(1);
+  }
+}
+
 class AIXTargetCodeGenInfo : public TargetCodeGenInfo {
   const bool Is64Bit;
 
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index d762bcd789bf5..b309fcff1a6d1 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -54,6 +54,7 @@
 #include "clang/Sema/SemaObjC.h"
 #include "clang/Sema/SemaOpenCL.h"
 #include "clang/Sema/SemaOpenMP.h"
+#include "clang/Sema/SemaPPC.h"
 #include "clang/Sema/SemaRISCV.h"
 #include "clang/Sema/SemaSYCL.h"
 #include "clang/Sema/SemaSwift.h"
@@ -3521,6 +3522,9 @@ static void handleTargetClonesAttr(Sema &S, Decl *D, 
const ParsedAttr &AL) {
     if (S.X86().checkTargetClonesAttr(Params, Locations, NewParams,
                                       AL.getLoc()))
       return;
+  } else if (S.Context.getTargetInfo().getTriple().isOSAIX()) {
+    if (S.PPC().checkTargetClonesAttr(Params, Locations, NewParams))
+      return;
   }
   Params.clear();
   for (auto &SmallStr : NewParams)
diff --git a/clang/lib/Sema/SemaPPC.cpp b/clang/lib/Sema/SemaPPC.cpp
index 536ba11088c8d..a6cf29c5c77ef 100644
--- a/clang/lib/Sema/SemaPPC.cpp
+++ b/clang/lib/Sema/SemaPPC.cpp
@@ -470,4 +470,60 @@ bool SemaPPC::BuiltinVSX(CallExpr *TheCall) {
   return false;
 }
 
+bool SemaPPC::checkTargetClonesAttr(
+    SmallVectorImpl<StringRef> &Params, SmallVectorImpl<SourceLocation> &Locs,
+    SmallVectorImpl<SmallString<64>> &NewParams) {
+  using namespace DiagAttrParams;
+
+  assert(Params.size() == Locs.size() &&
+         "Mismatch between number of string parameters and locations");
+
+  bool HasDefault = false;
+  bool HasComma = false;
+  for (unsigned I = 0, E = Params.size(); I < E; ++I) {
+    const StringRef Param = Params[I].trim();
+    const SourceLocation &Loc = Locs[I];
+
+    if (Param.empty() || Param.ends_with(','))
+      return Diag(Loc, diag::warn_unsupported_target_attribute)
+             << Unsupported << None << "" << TargetClones;
+
+    if (Param.contains(','))
+      HasComma = true;
+
+    StringRef LHS;
+    StringRef RHS = Param;
+    do {
+      std::tie(LHS, RHS) = RHS.split(',');
+      LHS = LHS.trim();
+      const SourceLocation &CurLoc =
+          Loc.getLocWithOffset(LHS.data() - Param.data());
+
+      if (LHS.starts_with("cpu=")) {
+        if (!getASTContext().getTargetInfo().isValidCPUName(
+                LHS.drop_front(sizeof("cpu=") - 1)))
+          return Diag(CurLoc, diag::warn_unsupported_target_attribute)
+                 << Unsupported << CPU << LHS.drop_front(sizeof("cpu=") - 1)
+                 << TargetClones;
+      } else if (LHS == "default")
+        HasDefault = true;
+      else if (!getASTContext().getTargetInfo().isValidFeatureName(LHS) ||
+               getASTContext().getTargetInfo().getFMVPriority(LHS) == 0)
+        return Diag(CurLoc, diag::warn_unsupported_target_attribute)
+               << Unsupported << None << LHS << TargetClones;
+
+      if (llvm::is_contained(NewParams, LHS))
+        Diag(CurLoc, diag::warn_target_clone_duplicate_options);
+      // Note: Add even if there are duplicates, since it changes name 
mangling.
+      NewParams.push_back(LHS);
+    } while (!RHS.empty());
+  }
+  if (HasComma && Params.size() > 1)
+    Diag(Locs[0], diag::warn_target_clone_mixed_values);
+
+  if (!HasDefault)
+    return Diag(Locs[0], diag::err_target_clone_must_have_default);
+
+  return false;
+}
 } // namespace clang

>From ae54a3245ff9c41632be9d1b42d4b6d7b4fb128a Mon Sep 17 00:00:00 2001
From: Wael Yehia <[email protected]>
Date: Sat, 27 Sep 2025 23:26:33 -0400
Subject: [PATCH 3/6] ignore target_clones on a declaration and internalize the
 resolver and the clones

---
 clang/lib/CodeGen/CodeGenModule.cpp | 40 ++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 4d9b000dfa52e..2261efca7c8e2 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2043,6 +2043,19 @@ static bool isUniqueInternalLinkageDecl(GlobalDecl GD,
          (CGM.getFunctionLinkage(GD) == llvm::GlobalValue::InternalLinkage);
 }
 
+// On certain platforms, a declared (but not defined) FMV shall be treated
+// like a regular non-FMV function.
+static bool IgnoreFMVOnADeclaration(const llvm::Triple &Triple, const 
FunctionDecl *FD) {
+  if (!FD->isMultiVersion())
+    return false;
+
+  if (Triple.isOSAIX()) {
+    assert(FD->isTargetClonesMultiVersion());
+    return !FD->isDefined();
+  }
+  return false;
+}
+
 static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
                                       const NamedDecl *ND,
                                       bool OmitMultiVersionMangling = false) {
@@ -2092,8 +2105,9 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, 
GlobalDecl GD,
     Out << CGM.getModuleNameHash();
   }
 
-  if (const auto *FD = dyn_cast<FunctionDecl>(ND))
-    if (FD->isMultiVersion() && !OmitMultiVersionMangling) {
+  if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
+    if (FD->isMultiVersion() && !OmitMultiVersionMangling &&
+         !IgnoreFMVOnADeclaration(CGM.getTriple(), FD)) {
       switch (FD->getMultiVersionKind()) {
       case MultiVersionKind::CPUDispatch:
       case MultiVersionKind::CPUSpecific:
@@ -2130,6 +2144,7 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, 
GlobalDecl GD,
         llvm_unreachable("None multiversion type isn't valid here");
       }
     }
+  }
 
   // Make unique name for device side static file-scope variable for HIP.
   if (CGM.getContext().shouldExternalize(ND) &&
@@ -4630,7 +4645,8 @@ getFMVPriority(const TargetInfo &TI,
 static llvm::GlobalValue::LinkageTypes
 getMultiversionLinkage(CodeGenModule &CGM, GlobalDecl GD) {
   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
-  if (FD->getFormalLinkage() == Linkage::Internal)
+  if (FD->getFormalLinkage() == Linkage::Internal ||
+      CGM.getTriple().isOSAIX())
     return llvm::GlobalValue::InternalLinkage;
   return llvm::GlobalValue::WeakODRLinkage;
 }
@@ -4664,7 +4680,7 @@ void CodeGenModule::emitMultiVersionFunctions() {
     // For AArch64, a resolver is only emitted if a function marked with
     // target_version("default")) or target_clones("default") is defined
     // in this TU. For other architectures it is always emitted.
-    bool ShouldEmitResolver = !getTarget().getTriple().isAArch64();
+    bool ShouldEmitResolver = !getTriple().isAArch64();
     SmallVector<CodeGenFunction::FMVResolverOption, 10> Options;
     llvm::DenseMap<llvm::Function *, const FunctionDecl *> DeclMap;
 
@@ -4983,8 +4999,11 @@ llvm::Constant 
*CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
     llvm::Constant *Resolver = GetOrCreateLLVMFunction(
         MangledName + ".resolver", ResolverType, GlobalDecl{},
         /*ForVTable=*/false);
+
+    auto Linkage = getTriple().isOSAIX() ? getFunctionLinkage(GD) : 
getMultiversionLinkage(*this, GD);
+
     llvm::GlobalIFunc *GIF =
-        llvm::GlobalIFunc::create(DeclTy, AS, getMultiversionLinkage(*this, 
GD),
+        llvm::GlobalIFunc::create(DeclTy, AS, Linkage,
                                   "", Resolver, &getModule());
     GIF->setName(ResolverName);
     SetCommonAttributes(FD, GIF);
@@ -5004,7 +5023,9 @@ llvm::Constant 
*CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
 void CodeGenModule::setMultiVersionResolverAttributes(llvm::Function *Resolver,
                                                       GlobalDecl GD) {
   const NamedDecl *D = dyn_cast_or_null<NamedDecl>(GD.getDecl());
-  Resolver->setLinkage(getMultiversionLinkage(*this, GD));
+
+  auto ResolverLinkage = getTriple().isOSAIX() ? 
llvm::GlobalValue::InternalLinkage : getMultiversionLinkage(*this, GD);
+  Resolver->setLinkage(ResolverLinkage);
 
   // Function body has to be emitted before calling setGlobalVisibility
   // for Resolver to be considered as definition.
@@ -5083,6 +5104,10 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
           AddDeferredMultiVersionResolverToEmit(GD);
           NameWithoutMultiVersionMangling = getMangledNameImpl(
               *this, GD, FD, /*OmitMultiVersionMangling=*/true);
+        } else if (IgnoreFMVOnADeclaration(getTriple(), FD)) {
+          // TODO this might not be necessary after fix in getMangledNameImpl
+          NameWithoutMultiVersionMangling = getMangledNameImpl(
+              *this, GD, FD, /*OmitMultiVersionMangling=*/true);
         } else
           return GetOrCreateMultiVersionResolver(GD);
       }
@@ -6543,6 +6568,9 @@ void 
CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
   auto *Fn = cast<llvm::Function>(GV);
   setFunctionLinkage(GD, Fn);
 
+  if (getTriple().isOSAIX() && D->isTargetClonesMultiVersion())
+      Fn->setLinkage(llvm::GlobalValue::InternalLinkage);
+
   // FIXME: this is redundant with part of setFunctionDefinitionAttributes
   setGVProperties(Fn, GD);
 

>From de08e992b49822699b2505c16146b5c2829d09f4 Mon Sep 17 00:00:00 2001
From: Wael Yehia <[email protected]>
Date: Tue, 30 Sep 2025 15:27:07 -0400
Subject: [PATCH 4/6] fix PPCTargetInfo::parseTargetAttr

---
 clang/lib/Basic/Targets/PPC.cpp | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 517e429ddfa1a..8386291d002b3 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -687,18 +687,20 @@ ParsedTargetAttr PPCTargetInfo::parseTargetAttr(StringRef 
Features) const {
 
     // While we're here iterating check for a different target cpu.
     if (Feature.starts_with("cpu=")) {
-      assert(Ret.CPU.empty());
-      Ret.CPU = Feature.split("=").second.trim();
-    } else assert(0);
-//    else if (Feature.starts_with("tune=")) {
-//      if (!Ret.Tune.empty())
-//        Ret.Duplicate = "tune=";
-//      else
-//        Ret.Tune = Feature.split("=").second.trim();
-//    } else if (Feature.starts_with("no-"))
-//      Ret.Features.push_back("-" + Feature.split("-").second.str());
-//    else
-//      Ret.Features.push_back("+" + Feature.str());
+      if (!Ret.CPU.empty())
+        Ret.Duplicate = "cpu=";
+      else
+        Ret.CPU = Feature.split("=").second.trim();
+    }
+    else if (Feature.starts_with("tune=")) {
+      if (!Ret.Tune.empty())
+        Ret.Duplicate = "tune=";
+      else
+        Ret.Tune = Feature.split("=").second.trim();
+    } else if (Feature.starts_with("no-"))
+      Ret.Features.push_back("-" + Feature.split("-").second.str());
+    else
+      Ret.Features.push_back("+" + Feature.str());
   }
   return Ret;
 }

>From 1ab4d6739d7280392710e5bcc540932b781029c3 Mon Sep 17 00:00:00 2001
From: Wael Yehia <[email protected]>
Date: Tue, 30 Sep 2025 19:38:35 +0000
Subject: [PATCH 5/6] fix Sema/attr-target.c

---
 clang/test/Sema/attr-target.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/clang/test/Sema/attr-target.c b/clang/test/Sema/attr-target.c
index 65ece3c27d299..ddf6654632187 100644
--- a/clang/test/Sema/attr-target.c
+++ b/clang/test/Sema/attr-target.c
@@ -75,15 +75,13 @@ int __attribute__((target("tune=pwr8"))) baz(void) { return 
4; }
 //expected-warning@+1 {{unsupported 'fpmath=' in the 'target' attribute 
string; 'target' attribute ignored}}
 int __attribute__((target("fpmath=387"))) walrus(void) { return 4; }
 //expected-warning@+1 {{unknown CPU 'hiss' in the 'target' attribute string; 
'target' attribute ignored}}
-int __attribute__((target("float128,arch=hiss"))) meow(void) {  return 4; }
+int __attribute__((target("float128,cpu=hiss"))) meow(void) {  return 4; }
 // no warning, same as saying 'nothing'.
-int __attribute__((target("arch="))) turtle(void) { return 4; }
+int __attribute__((target("cpu="))) turtle(void) { return 4; }
 //expected-warning@+1 {{unknown CPU 'hiss' in the 'target' attribute string; 
'target' attribute ignored}}
-int __attribute__((target("arch=hiss,arch=woof"))) pine_tree(void) { return 4; 
}
-//expected-warning@+1 {{duplicate 'arch=' in the 'target' attribute string; 
'target' attribute ignored}}
-int __attribute__((target("arch=pwr9,arch=pwr10"))) oak_tree(void) { return 4; 
}
-//expected-warning@+1 {{unsupported 'branch-protection' in the 'target' 
attribute string; 'target' attribute ignored}}
-int __attribute__((target("branch-protection=none"))) birch_tree(void) { 
return 5; }
+int __attribute__((target("cpu=hiss,cpu=woof"))) pine_tree(void) { return 4; }
+//expected-warning@+1 {{duplicate 'cpu=' in the 'target' attribute string; 
'target' attribute ignored}}
+int __attribute__((target("cpu=pwr9,cpu=pwr10"))) oak_tree(void) { return 4; }
 //expected-warning@+1 {{unknown tune CPU 'hiss' in the 'target' attribute 
string; 'target' attribute ignored}}
 int __attribute__((target("tune=hiss,tune=woof"))) apple_tree(void) { return 
4; }
 

>From c6358f5bbc77f7c9d35279832f08129b6988cf75 Mon Sep 17 00:00:00 2001
From: Wael Yehia <[email protected]>
Date: Tue, 7 Oct 2025 23:11:21 +0000
Subject: [PATCH 6/6] clang-format

---
 clang/lib/AST/ASTContext.cpp             |  5 +++-
 clang/lib/Basic/Targets/PPC.cpp          |  3 +--
 clang/lib/CodeGen/CodeGenFunction.cpp    | 31 ++++++++++++++----------
 clang/lib/CodeGen/CodeGenFunction.h      |  5 ++--
 clang/lib/CodeGen/CodeGenModule.cpp      | 29 ++++++++++++----------
 clang/lib/CodeGen/TargetBuiltins/PPC.cpp | 14 +++++------
 clang/lib/CodeGen/Targets/PPC.cpp        |  5 ++--
 7 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 223f65ed1bf95..65c8871ab5f0b 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -15021,7 +15021,10 @@ void 
ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
       StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
       if (VersionStr.starts_with("arch="))
         TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1);
-      else if (Target->getTriple().isOSAIX() && 
VersionStr.starts_with("cpu=")) // TODO make a function that extracts CPU from 
a feature string
+      else if (Target->getTriple().isOSAIX() &&
+               VersionStr.starts_with(
+                   "cpu=")) // TODO make a function that extracts CPU from a
+                            // feature string
         TargetCPU = VersionStr.drop_front(sizeof("cpu=") - 1);
       else if (VersionStr != "default")
         Features.push_back((StringRef{"+"} + VersionStr).str());
diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 8386291d002b3..a6eb61fdc9907 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -691,8 +691,7 @@ ParsedTargetAttr PPCTargetInfo::parseTargetAttr(StringRef 
Features) const {
         Ret.Duplicate = "cpu=";
       else
         Ret.CPU = Feature.split("=").second.trim();
-    }
-    else if (Feature.starts_with("tune=")) {
+    } else if (Feature.starts_with("tune=")) {
       if (!Ret.Tune.empty())
         Ret.Duplicate = "tune=";
       else
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp 
b/clang/lib/CodeGen/CodeGenFunction.cpp
index f52bd212a4170..67f83f3db732c 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -3018,7 +3018,8 @@ void CodeGenFunction::EmitMultiVersionResolver(
     }
     [[fallthrough]];
   default:
-    assert(false && "Only implemented for x86, AArch64, RISC-V, and PowerPC 
targets");
+    assert(false &&
+           "Only implemented for x86, AArch64, RISC-V, and PowerPC targets");
   }
 }
 
@@ -3031,7 +3032,7 @@ void CodeGenFunction::EmitMultiVersionResolver(
  *  return ((int (*)(int)) foo_desc)(a);
  */
 void CodeGenFunction::EmitPPCAIXMultiVersionResolver(
-               llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {
+    llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {
 
   llvm::PointerType *PtrTy = Builder.getPtrTy();
   // entry:
@@ -3045,7 +3046,8 @@ void CodeGenFunction::EmitPPCAIXMultiVersionResolver(
       // if.default:
       //   %fmv.default = call ptr @getEntryPoint(ptr noundef @foo_default)
       //   br label %resolver_exit
-      assert(&RO == Options.end() - 1 && "Default or Generic case must be 
last");
+      assert(&RO == Options.end() - 1 &&
+             "Default or Generic case must be last");
       Builder.CreateRet(RO.Function);
       break;
     }
@@ -3056,12 +3058,16 @@ void CodeGenFunction::EmitPPCAIXMultiVersionResolver(
     // if.version_n:
     //   %fmv.version.n = call ptr @getEntryPoint(ptr noundef @foo_version_n)
     //   br label %resolver_exit
-    assert(RO.Features.size() == 1 && "for now one feature requirement per 
version");
+    assert(RO.Features.size() == 1 &&
+           "for now one feature requirement per version");
     llvm::Value *Condition;
     if (RO.Features[0].starts_with("cpu=")) {
-      Condition = EmitPPCBuiltinCpu(Builtin::BI__builtin_cpu_is, 
Builder.getInt1Ty(), RO.Features[0].split("=").second.trim());
+      Condition =
+          EmitPPCBuiltinCpu(Builtin::BI__builtin_cpu_is, Builder.getInt1Ty(),
+                            RO.Features[0].split("=").second.trim());
     } else {
-      Condition = EmitPPCBuiltinCpu(Builtin::BI__builtin_cpu_supports, 
Builder.getInt1Ty(), RO.Features[0]);
+      Condition = EmitPPCBuiltinCpu(Builtin::BI__builtin_cpu_supports,
+                                    Builder.getInt1Ty(), RO.Features[0]);
     }
     llvm::BasicBlock *ThenBlock = createBasicBlock("if.version", Resolver);
     CurBlock = createBasicBlock("if.else", Resolver);
@@ -3072,15 +3078,14 @@ void CodeGenFunction::EmitPPCAIXMultiVersionResolver(
   }
 
   // If no generic/default, emit an unreachable.
-//  Builder.SetInsertPoint(CurBlock);
-//  llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
-//  TrapCall->setDoesNotReturn();
-//  TrapCall->setDoesNotThrow();
-//  Builder.CreateUnreachable();
-//  Builder.ClearInsertionPoint();
+  //  Builder.SetInsertPoint(CurBlock);
+  //  llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
+  //  TrapCall->setDoesNotReturn();
+  //  TrapCall->setDoesNotThrow();
+  //  Builder.CreateUnreachable();
+  //  Builder.ClearInsertionPoint();
 }
 
-
 void CodeGenFunction::EmitRISCVMultiVersionResolver(
     llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {
 
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 978dc2602a469..9c38df935c9bc 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4869,7 +4869,8 @@ class CodeGenFunction : public CodeGenTypeCache {
 
   llvm::Value *BuildVector(ArrayRef<llvm::Value *> Ops);
   llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
-  llvm::Value *EmitPPCBuiltinCpu(unsigned BuiltinID, llvm::Type *ReturnType, 
StringRef CPUStr);
+  llvm::Value *EmitPPCBuiltinCpu(unsigned BuiltinID, llvm::Type *ReturnType,
+                                 StringRef CPUStr);
   llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
   llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
   llvm::Value *EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
@@ -5538,7 +5539,7 @@ class CodeGenFunction : public CodeGenTypeCache {
                                      ArrayRef<FMVResolverOption> Options);
 
   void EmitPPCAIXMultiVersionResolver(llvm::Function *Resolver,
-                                     ArrayRef<FMVResolverOption> Options);
+                                      ArrayRef<FMVResolverOption> Options);
 
 private:
   QualType getVarArgType(const Expr *Arg);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 2261efca7c8e2..35835e66bb2e6 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2045,7 +2045,8 @@ static bool isUniqueInternalLinkageDecl(GlobalDecl GD,
 
 // On certain platforms, a declared (but not defined) FMV shall be treated
 // like a regular non-FMV function.
-static bool IgnoreFMVOnADeclaration(const llvm::Triple &Triple, const 
FunctionDecl *FD) {
+static bool IgnoreFMVOnADeclaration(const llvm::Triple &Triple,
+                                    const FunctionDecl *FD) {
   if (!FD->isMultiVersion())
     return false;
 
@@ -2107,7 +2108,7 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, 
GlobalDecl GD,
 
   if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
     if (FD->isMultiVersion() && !OmitMultiVersionMangling &&
-         !IgnoreFMVOnADeclaration(CGM.getTriple(), FD)) {
+        !IgnoreFMVOnADeclaration(CGM.getTriple(), FD)) {
       switch (FD->getMultiVersionKind()) {
       case MultiVersionKind::CPUDispatch:
       case MultiVersionKind::CPUSpecific:
@@ -2967,8 +2968,9 @@ bool 
CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD,
     // While we populated the feature map above, we still need to
     // get and parse the target attribute so we can get the cpu for
     // the function.
-    StringRef FeatureStr = TD ? TD->getFeaturesStr() :
-                          (TC ? TC->getFeatureStr(GD.getMultiVersionIndex()) : 
StringRef());
+    StringRef FeatureStr =
+        TD ? TD->getFeaturesStr()
+           : (TC ? TC->getFeatureStr(GD.getMultiVersionIndex()) : StringRef());
     if (!FeatureStr.empty()) {
       ParsedTargetAttr ParsedAttr = Target.parseTargetAttr(FeatureStr);
       if (!ParsedAttr.CPU.empty() &&
@@ -4645,8 +4647,7 @@ getFMVPriority(const TargetInfo &TI,
 static llvm::GlobalValue::LinkageTypes
 getMultiversionLinkage(CodeGenModule &CGM, GlobalDecl GD) {
   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
-  if (FD->getFormalLinkage() == Linkage::Internal ||
-      CGM.getTriple().isOSAIX())
+  if (FD->getFormalLinkage() == Linkage::Internal || CGM.getTriple().isOSAIX())
     return llvm::GlobalValue::InternalLinkage;
   return llvm::GlobalValue::WeakODRLinkage;
 }
@@ -4733,7 +4734,7 @@ void CodeGenModule::emitMultiVersionFunctions() {
       ResolverConstant = IFunc->getResolver();
       if (FD->isTargetClonesMultiVersion() &&
           !getTarget().getTriple().isAArch64() &&
-                 !getTarget().getTriple().isOSAIX()) {
+          !getTarget().getTriple().isOSAIX()) {
         std::string MangledName = getMangledNameImpl(
             *this, GD, FD, /*OmitMultiVersionMangling=*/true);
         if (!GetGlobalValue(MangledName + ".ifunc")) {
@@ -5000,11 +5001,11 @@ llvm::Constant 
*CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
         MangledName + ".resolver", ResolverType, GlobalDecl{},
         /*ForVTable=*/false);
 
-    auto Linkage = getTriple().isOSAIX() ? getFunctionLinkage(GD) : 
getMultiversionLinkage(*this, GD);
+    auto Linkage = getTriple().isOSAIX() ? getFunctionLinkage(GD)
+                                         : getMultiversionLinkage(*this, GD);
 
-    llvm::GlobalIFunc *GIF =
-        llvm::GlobalIFunc::create(DeclTy, AS, Linkage,
-                                  "", Resolver, &getModule());
+    llvm::GlobalIFunc *GIF = llvm::GlobalIFunc::create(DeclTy, AS, Linkage, "",
+                                                       Resolver, &getModule());
     GIF->setName(ResolverName);
     SetCommonAttributes(FD, GIF);
     if (ResolverGV)
@@ -5024,7 +5025,9 @@ void 
CodeGenModule::setMultiVersionResolverAttributes(llvm::Function *Resolver,
                                                       GlobalDecl GD) {
   const NamedDecl *D = dyn_cast_or_null<NamedDecl>(GD.getDecl());
 
-  auto ResolverLinkage = getTriple().isOSAIX() ? 
llvm::GlobalValue::InternalLinkage : getMultiversionLinkage(*this, GD);
+  auto ResolverLinkage = getTriple().isOSAIX()
+                             ? llvm::GlobalValue::InternalLinkage
+                             : getMultiversionLinkage(*this, GD);
   Resolver->setLinkage(ResolverLinkage);
 
   // Function body has to be emitted before calling setGlobalVisibility
@@ -6569,7 +6572,7 @@ void 
CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
   setFunctionLinkage(GD, Fn);
 
   if (getTriple().isOSAIX() && D->isTargetClonesMultiVersion())
-      Fn->setLinkage(llvm::GlobalValue::InternalLinkage);
+    Fn->setLinkage(llvm::GlobalValue::InternalLinkage);
 
   // FIXME: this is redundant with part of setFunctionDefinitionAttributes
   setGVProperties(Fn, GD);
diff --git a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp 
b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
index ea25ed691b454..881585cffe47b 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -70,8 +70,9 @@ static llvm::Value 
*emitPPCLoadReserveIntrinsic(CodeGenFunction &CGF,
   return CI;
 }
 
-Value *CodeGenFunction::EmitPPCBuiltinCpu(
-    unsigned BuiltinID, llvm::Type *ReturnType, StringRef CPUStr) {
+Value *CodeGenFunction::EmitPPCBuiltinCpu(unsigned BuiltinID,
+                                          llvm::Type *ReturnType,
+                                          StringRef CPUStr) {
 
 #include "llvm/TargetParser/PPCTargetParser.def"
   auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx,
@@ -159,8 +160,7 @@ Value *CodeGenFunction::EmitPPCBuiltinCpu(
     Value *TheCall = Builder.CreateCall(F, {Op0}, "cpu_is");
     return Builder.CreateICmpEQ(TheCall,
                                 llvm::ConstantInt::get(Int32Ty, LinuxIDValue));
-  }
-  else if (BuiltinID == Builtin::BI__builtin_cpu_supports) {
+  } else if (BuiltinID == Builtin::BI__builtin_cpu_supports) {
     llvm::Triple Triple = getTarget().getTriple();
     if (Triple.isOSAIX()) {
       typedef std::tuple<unsigned, unsigned, unsigned, CmpInst::Predicate,
@@ -197,8 +197,7 @@ Value *CodeGenFunction::EmitPPCBuiltinCpu(
 #undef PPC_FAWORD_HWCAP
 #undef PPC_FAWORD_HWCAP2
 #undef PPC_FAWORD_CPUID
-  }
-  else
+  } else
     assert(0 && "unexpected builtin");
 }
 
@@ -219,7 +218,8 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned 
BuiltinID,
   Intrinsic::ID ID = Intrinsic::not_intrinsic;
 
   switch (BuiltinID) {
-  default: return nullptr;
+  default:
+    return nullptr;
 
   case Builtin::BI__builtin_cpu_is:
   case Builtin::BI__builtin_cpu_supports: {
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp 
b/clang/lib/CodeGen/Targets/PPC.cpp
index bc357e0908a5e..61d110e3c7ae3 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -136,8 +136,7 @@ class AIXABIInfo : public ABIInfo {
                                raw_ostream &Out) const override;
 };
 
-void AIXABIInfo::appendAttributeMangling(TargetClonesAttr *Attr,
-                                         unsigned Index,
+void AIXABIInfo::appendAttributeMangling(TargetClonesAttr *Attr, unsigned 
Index,
                                          raw_ostream &Out) const {
   appendAttributeMangling(Attr->getFeatureStr(Index), Out);
 }
@@ -159,7 +158,7 @@ void AIXABIInfo::appendAttributeMangling(StringRef AttrStr,
     assert(LHS.starts_with("+") && RHS.starts_with("+") &&
            "Features should always have a prefix.");
     return TI.getFMVPriority({LHS.substr(1)})
-            .ugt(TI.getFMVPriority({RHS.substr(1)}));
+        .ugt(TI.getFMVPriority({RHS.substr(1)}));
   });
 
   bool IsFirst = true;

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to