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

>From 87cd7b2124ed6e1450f10a53726fcb8db6d7b8e7 Mon Sep 17 00:00:00 2001
From: Wael Yehia <wye...@ca.ibm.com>
Date: Mon, 11 Aug 2025 15:56:25 +0000
Subject: [PATCH 1/4] Create and implement lowering of two intrinsics: 
 int.ppc.get.function.descriptor  int.ppc.get.function.entry

---
 llvm/include/llvm/IR/IntrinsicsPowerPC.td   | 10 ++++++++
 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp   | 10 ++++++--
 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp |  4 +++
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 27 +++++++++++++++++++++
 4 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td 
b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 7dd9ff7f08b8b..75b64fba6e3ca 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -2090,3 +2090,13 @@ let TargetPrefix = "ppc" in {
     Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_ptr_ty],
               [IntrArgMemOnly, IntrWriteMem, NoCapture<ArgIndex<2>>]>;
 }
+
+
+//===----------------------------------------------------------------------===//
+// XCOFF Intrinsics
+let TargetPrefix = "ppc" in {
+  def int_ppc_get_function_entry :
+      DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_ptr_ty], [IntrNoMem]>;
+  def int_ppc_get_function_descriptor :
+      DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_ptr_ty], [IntrNoMem]>;
+}
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp 
b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 2ab2c147be0ec..8b9b4975643c4 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -763,6 +763,8 @@ static MCSymbol *getMCSymbolForTOCPseudoMO(const 
MachineOperand &MO,
     return AP.GetJTISymbol(MO.getIndex());
   case MachineOperand::MO_BlockAddress:
     return AP.GetBlockAddressSymbol(MO.getBlockAddress());
+  case MachineOperand::MO_MCSymbol:
+    return MO.getMCSymbol();
   default:
     llvm_unreachable("Unexpected operand type to get symbol.");
   }
@@ -792,6 +794,8 @@ getTOCEntryTypeForMO(const MachineOperand &MO) {
     return PPCAsmPrinter::TOCType_JumpTable;
   case MachineOperand::MO_BlockAddress:
     return PPCAsmPrinter::TOCType_BlockAddress;
+  case MachineOperand::MO_MCSymbol:
+    return PPCAsmPrinter::TOCType_GlobalExternal; // TODO
   default:
     llvm_unreachable("Unexpected operand type to get TOC type.");
   }
@@ -1043,7 +1047,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr 
*MI) {
     TmpInst.setOpcode(PPC::LWZ);
 
     const MachineOperand &MO = MI->getOperand(1);
-    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) 
&&
+    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress() ||
+            MO.isMCSymbol()) &&
            "Invalid operand for LWZtoc.");
 
     // Map the operand to its corresponding MCSymbol.
@@ -1127,7 +1132,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr 
*MI) {
     TmpInst.setOpcode(PPC::LD);
 
     const MachineOperand &MO = MI->getOperand(1);
-    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) 
&&
+    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress() ||
+            MO.isMCSymbol()) &&
            "Invalid operand!");
 
     // Map the operand to its corresponding MCSymbol.
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp 
b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 415164fc9e2cb..921cb72a83030 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -6158,6 +6158,10 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
         replaceWith(PPC::ADDItoc8, N, MVT::i64);
         return;
       }
+      if (N->getOperand(0).getOpcode() == ISD::MCSymbol) {
+        replaceWith(PPC::LDtoc, N, MVT::i64);
+        return;
+      }
       // Break if it doesn't have toc data attribute. Proceed with common
       // SelectCode.
       break;
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp 
b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 74ae8502dccea..83525797ce5ca 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -11167,6 +11167,33 @@ SDValue 
PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
   SDLoc dl(Op);
 
   switch (IntrinsicID) {
+  case Intrinsic::ppc_get_function_descriptor:
+    return Op.getOperand(1);
+  case Intrinsic::ppc_get_function_entry: {
+    SDValue Op1 = Op.getOperand(1);
+    if (auto *G = dyn_cast<GlobalAddressSDNode>(Op1)) {
+      const GlobalValue *GV = G->getGlobal();
+      assert(isFunctionGlobalAddress(GV));
+      assert(Subtarget.isAIXABI());
+      assert(!isa<GlobalIFunc>(GV) && "IFunc is not supported on AIX.");
+      const TargetMachine &TM = Subtarget.getTargetMachine();
+      const TargetLoweringObjectFile *TLOF = TM.getObjFileLowering();
+      MCSymbolXCOFF *S = static_cast<MCSymbolXCOFF *>(
+          TLOF->getFunctionEntryPointSymbol(GV, TM));
+
+      MVT PtrVT = 
DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
+      SDValue EntryPointSym = DAG.getMCSymbol(S, PtrVT);
+      return getTOCEntry(DAG, dl, EntryPointSym);
+    }
+    assert(Op1.getOpcode() == ISD::CopyFromReg);
+    SDLoc dl(Op);
+    EVT PtrVT = getPointerTy(DAG.getDataLayout());
+    SDValue Result =
+        DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Op1, MachinePointerInfo(),
+                    DAG.getDataLayout().getPointerABIAlignment(0),
+                    MachineMemOperand::MODereferenceable);
+    return Result;
+  }
   case Intrinsic::thread_pointer:
     // Reads the thread pointer register, used for __builtin_thread_pointer.
     if (Subtarget.isPPC64())

>From 0bc22a6d89c3b86ad3e8b1584298b28734e95031 Mon Sep 17 00:00:00 2001
From: Wael Yehia <wye...@ca.ibm.com>
Date: Tue, 5 Aug 2025 18:01:19 +0000
Subject: [PATCH 2/4] accept ifunc attribute on AIX

---
 clang/include/clang/Basic/TargetInfo.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index ce4677e540226..ffeab27b67911 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1545,6 +1545,8 @@ class TargetInfo : public TransferrableTargetInfo,
       return true;
     if (getTriple().getArch() == llvm::Triple::ArchType::avr)
       return true;
+    if (getTriple().isOSAIX())
+      return true;
     return getTriple().isOSBinFormatELF() &&
            ((getTriple().isOSLinux() && !getTriple().isMusl()) ||
             getTriple().isOSFreeBSD());

>From c294b4398dad26e5b7c05fb6e88dd82b2878d71c Mon Sep 17 00:00:00 2001
From: Wael Yehia <wye...@ca.ibm.com>
Date: Mon, 11 Aug 2025 16:01:25 +0000
Subject: [PATCH 3/4] initial LowerIFuncsOnAIX impl

---
 .../llvm/Transforms/Utils/ModuleUtils.h       |  7 ++
 llvm/lib/Target/PowerPC/PPCTargetMachine.cpp  | 12 +++
 llvm/lib/Target/PowerPC/PPCTargetMachine.h    |  2 +
 llvm/lib/Transforms/Utils/LowerIFunc.cpp      |  7 +-
 llvm/lib/Transforms/Utils/ModuleUtils.cpp     | 98 ++++++++++++++++++-
 5 files changed, 124 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Utils/ModuleUtils.h 
b/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
index 4036c4e947c75..2734422ba0329 100644
--- a/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
+++ b/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -159,6 +159,13 @@ LLVM_ABI bool
 lowerGlobalIFuncUsersAsGlobalCtor(Module &M,
                                   ArrayRef<GlobalIFunc *> IFuncsToLower = {});
 
+/// AIX specific lowering of ifuncs where we convert an ifunc to a regular
+/// function with the following implementation:
+///  Check if the function's descriptor still points to itself (true on first
+/// entry), if so then call the resolver function and atomically store the
+/// resulting function pointer into the descriptor. Make an indirect call
+/// through the function pointer in the descriptor.
+LLVM_ABI void lowerIFuncsOnAIX(Module &M);
 } // End llvm namespace
 
 #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
diff --git a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp 
b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
index b5c6ac111dff0..a2d8bca663274 100644
--- a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -36,6 +36,7 @@
 #include "llvm/InitializePasses.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Pass.h"
+#include "llvm/Passes/PassBuilder.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
@@ -43,6 +44,7 @@
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/TargetParser/Triple.h"
 #include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/LowerIFunc.h"
 #include <cassert>
 #include <memory>
 #include <optional>
@@ -452,6 +454,16 @@ class PPCPassConfig : public TargetPassConfig {
 
 } // end anonymous namespace
 
+void PPCTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
+  if (getTargetTriple().isOSAIX())
+    PB.registerOptimizerLastEPCallback([](ModulePassManager &PM,
+                                          OptimizationLevel Level,
+                                          ThinOrFullLTOPhase Phase) {
+      if (Phase == ThinOrFullLTOPhase::None)
+        PM.addPass(LowerIFuncPass());
+    });
+}
+
 TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM) {
   return new PPCPassConfig(*this, PM);
 }
diff --git a/llvm/lib/Target/PowerPC/PPCTargetMachine.h 
b/llvm/lib/Target/PowerPC/PPCTargetMachine.h
index cb02b446fadb3..608750f7a3f2b 100644
--- a/llvm/lib/Target/PowerPC/PPCTargetMachine.h
+++ b/llvm/lib/Target/PowerPC/PPCTargetMachine.h
@@ -54,6 +54,8 @@ class PPCTargetMachine final : public 
CodeGenTargetMachineImpl {
   // Pass Pipeline Configuration
   TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
 
+  void registerPassBuilderCallbacks(PassBuilder &PB) override;
+
   TargetTransformInfo getTargetTransformInfo(const Function &F) const override;
 
   TargetLoweringObjectFile *getObjFileLowering() const override {
diff --git a/llvm/lib/Transforms/Utils/LowerIFunc.cpp 
b/llvm/lib/Transforms/Utils/LowerIFunc.cpp
index 18ae0bbe2e731..991890aa56b83 100644
--- a/llvm/lib/Transforms/Utils/LowerIFunc.cpp
+++ b/llvm/lib/Transforms/Utils/LowerIFunc.cpp
@@ -13,6 +13,7 @@
 #include "llvm/Transforms/Utils/LowerIFunc.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Pass.h"
+#include "llvm/TargetParser/Triple.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
 
 using namespace llvm;
@@ -22,6 +23,10 @@ PreservedAnalyses LowerIFuncPass::run(Module &M, 
ModuleAnalysisManager &AM) {
   if (M.ifunc_empty())
     return PreservedAnalyses::all();
 
-  lowerGlobalIFuncUsersAsGlobalCtor(M, {});
+  Triple TargetTriple(M.getTargetTriple());
+  if (TargetTriple.isOSAIX())
+    lowerIFuncsOnAIX(M);
+  else
+    lowerGlobalIFuncUsersAsGlobalCtor(M, {});
   return PreservedAnalyses::none();
 }
diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp 
b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index 596849ecab742..10e898bf266f0 100644
--- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -11,11 +11,13 @@
 
//===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Utils/ModuleUtils.h"
-#include "llvm/Analysis/VectorUtils.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/Analysis/VectorUtils.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsPowerPC.h"
 #include "llvm/IR/MDBuilder.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Casting.h"
@@ -397,6 +399,100 @@ void llvm::embedBufferInModule(Module &M, MemoryBufferRef 
Buf,
   appendToCompilerUsed(M, GV);
 }
 
+void llvm::lowerIFuncsOnAIX(Module &M) {
+  for (GlobalIFunc &IFunc : make_early_inc_range(M.ifuncs())) {
+
+    // Let IFunc be:
+    //   @foo = ifunc rt-type (type1, type2), ptr @resolver
+    assert(isa<llvm::FunctionType>(IFunc.getValueType()));
+    FunctionType *FTy = cast<llvm::FunctionType>(IFunc.getValueType());
+
+    // Create the regular (non-ifunc) function:
+    //   define rt-type @foo(type1 %0, type2 %1)
+    Function *F = Function::Create(
+        FTy, IFunc.getLinkage(), IFunc.getAddressSpace(), IFunc.getName(), &M);
+    LLVMContext &Ctx = F->getContext();
+
+    // entry:
+    BasicBlock *CurBlock = BasicBlock::Create(Ctx, "entry", F);
+    IRBuilder<> Builder(CurBlock);
+
+    PointerType *PtrTy = Builder.getPtrTy();
+    //   %DescPtr = call ptr @ppc_get_function_descriptor(ptr noundef @foo)
+    auto *DescPtr = Builder.CreateIntrinsic(
+        /*RetTy*/ PtrTy, Intrinsic::ppc_get_function_descriptor, {F}, {},
+        "desc.ptr");
+
+    //   %DesctAddr = getelementptr inbounds %struct.Desc_t, ptr %DescPtr, i32
+    //   0, i32 0
+    StructType *DescriptorType = StructType::get(PtrTy, PtrTy, PtrTy);
+    auto *DesctAddr =
+        Builder.CreateStructGEP(DescriptorType, DescPtr, 0, "desc_t.addr");
+
+    //   %AddrInDesc = load ptr, ptr %DesctAddr, align 4
+    auto *AddrInDesc = Builder.CreateAlignedLoad(
+        PtrTy, DesctAddr, DesctAddr->getPointerAlignment(M.getDataLayout()),
+        "addr.in.desc");
+
+    //   %OriginalAddr = call ptr @ppc_get_function_entry(ptr noundef @foo) #3
+    auto *OriginalAddr = Builder.CreateIntrinsic(
+        /*RetTy*/ PtrTy, Intrinsic::ppc_get_function_entry, {F}, {},
+        "original.addr");
+
+    //   %cmp = icmp eq ptr %AddrInDesc, %OriginalAddr
+    auto *CMP = Builder.CreateICmpEQ(AddrInDesc, OriginalAddr);
+
+    //   br i1 %cmp, label %resolver, label %end
+    CurBlock = BasicBlock::Create(Ctx, "resolver", F);
+    BasicBlock *FinalBlock = BasicBlock::Create(Ctx, "end", F);
+    Builder.CreateCondBr(CMP, CurBlock, FinalBlock);
+
+    // Emit the 'then' (resolver) code:
+    Builder.SetInsertPoint(CurBlock);
+
+    // resolver:
+    //   %ResolvedFunc = call ptr @resolver()
+    //   %ResolvedAddr = call ptr @ppc_get_function_entry(ptr %ResolvedFunc)
+    //   %4 = ptrtoint ptr %ResolvedAddr to i32
+    //   store atomic i32 %4, ptr %desc_t.addr release, align 4
+    Function *ResolverFunc = IFunc.getResolverFunction();
+    auto *ResolvedFunc =
+        Builder.CreateCall(ResolverFunc, ArrayRef<Value *>(), "resolved.func");
+    auto *ResolvedAddr = Builder.CreateIntrinsic(
+        /*RetTy*/ PtrTy, Intrinsic::ppc_get_function_entry, {ResolvedFunc}, {},
+        "resolved.addr");
+    auto *PtrToInt = Builder.CreatePtrToInt(
+        ResolvedAddr, Builder.getIntPtrTy(M.getDataLayout()));
+    // TODO fix alignment
+    Builder.CreateAlignedStore(PtrToInt, DesctAddr, MaybeAlign())
+        ->setAtomic(AtomicOrdering::Release);
+
+    //   br label %if.end
+    Builder.CreateBr(FinalBlock);
+
+    // Emit the continuation block for code after the if.
+    Builder.SetInsertPoint(FinalBlock);
+
+    //   %res = musttail call i32 %DescPtr(i32 noundef %a) #3
+    SmallVector<Value *, 10> Args(make_pointer_range(F->args()));
+    CallInst *Result =
+        Builder.CreateCall(F->getFunctionType(), DescPtr, Args, "res");
+    // Result->setTailCallKind(CallInst::TCK_MustTail);
+
+    //   ret i32 %res
+    if (F->getReturnType()->isVoidTy())
+      Builder.CreateRetVoid();
+    else
+      Builder.CreateRet(Result);
+
+    // replace all uses of the ifunc with the newly created function
+    IFunc.replaceAllUsesWith(F);
+
+    std::string name = IFunc.getName().str();
+    IFunc.eraseFromParent();
+    F->setName(name);
+  }
+}
 bool llvm::lowerGlobalIFuncUsersAsGlobalCtor(
     Module &M, ArrayRef<GlobalIFunc *> FilteredIFuncsToLower) {
   SmallVector<GlobalIFunc *, 32> AllIFuncs;

>From a60e6b104cba91e39f7c04559277a14a96e9eb7f Mon Sep 17 00:00:00 2001
From: Wael Yehia <wye...@ca.ibm.com>
Date: Tue, 12 Aug 2025 03:10:06 +0000
Subject: [PATCH 4/4] add clang codegen tests

---
 clang/test/CodeGen/attr-ifunc.c            | 2 ++
 clang/test/CodeGen/attr-ifunc.cpp          | 2 ++
 clang/test/CodeGen/ifunc.c                 | 3 ++-
 clang/test/SemaCXX/ifunc-has-attribute.cpp | 1 +
 llvm/lib/Transforms/Utils/LowerIFunc.cpp   | 5 ++++-
 llvm/lib/Transforms/Utils/ModuleUtils.cpp  | 2 +-
 6 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/clang/test/CodeGen/attr-ifunc.c b/clang/test/CodeGen/attr-ifunc.c
index c9e70b17a8302..55d1866c17a69 100644
--- a/clang/test/CodeGen/attr-ifunc.c
+++ b/clang/test/CodeGen/attr-ifunc.c
@@ -4,6 +4,8 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx -verify -emit-llvm-only %s
 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -verify -emit-llvm-only %s
 // RUN: %clang_cc1 -triple aarch64-pc-windows-msvcu -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -verify -emit-llvm-only 
-DCHECK_ALIASES %s
 
 #if defined(_WIN32) && !defined(__aarch64__)
 void foo(void) {}
diff --git a/clang/test/CodeGen/attr-ifunc.cpp 
b/clang/test/CodeGen/attr-ifunc.cpp
index 9e6cd7312122d..601fad94530bd 100644
--- a/clang/test/CodeGen/attr-ifunc.cpp
+++ b/clang/test/CodeGen/attr-ifunc.cpp
@@ -1,9 +1,11 @@
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx -verify -emit-llvm-only %s
 // RUN: %clang_cc1 -triple arm64-apple-macosx -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -verify -emit-llvm-only %s
 // RUN: not %clang_cc1 -triple x86_64-linux -emit-llvm-only 
-fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 // RUN: not %clang_cc1 -triple x86_64-apple-macosx -emit-llvm-only 
-fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 // RUN: not %clang_cc1 -triple arm64-apple-macosx -emit-llvm-only 
-fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -emit-llvm-only 
-fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 void *f1_ifunc(void) { return nullptr; }
 void f1(void) __attribute__((ifunc("f1_ifunc")));
diff --git a/clang/test/CodeGen/ifunc.c b/clang/test/CodeGen/ifunc.c
index 7d21f742e8676..6aec451ff97aa 100644
--- a/clang/test/CodeGen/ifunc.c
+++ b/clang/test/CodeGen/ifunc.c
@@ -16,6 +16,7 @@
 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -O2 -emit-llvm -o - %s | 
FileCheck %s
 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsanitize=thread -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsanitize=address -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -mllvm -lower-ifuncs=0 
-emit-llvm -o - %s | FileCheck %s
 
 
 /// The ifunc is emitted before its resolver.
@@ -65,7 +66,7 @@ extern void hoo(int) __attribute__ ((ifunc("hoo_ifunc")));
 // AVR: @goo = ifunc void (), ptr addrspace(1) @goo_ifunc
 // AVR: @hoo = ifunc void (i16), ptr addrspace(1) @hoo_ifunc
 
-// CHECK: call i32 @foo(i32
+// CHECK: call {{(signext )?}}i32 @foo(i32
 // CHECK: call void @goo()
 
 // SAN: define {{(dso_local )?}}noalias {{(noundef )?}}ptr @goo_ifunc() 
#[[#GOO_IFUNC:]] {
diff --git a/clang/test/SemaCXX/ifunc-has-attribute.cpp 
b/clang/test/SemaCXX/ifunc-has-attribute.cpp
index 242f3b621745f..913bc40ffee44 100644
--- a/clang/test/SemaCXX/ifunc-has-attribute.cpp
+++ b/clang/test/SemaCXX/ifunc-has-attribute.cpp
@@ -2,6 +2,7 @@
 // RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-macosx -verify %s 
-DSUPPORTED=1
 // RUN: %clang_cc1 -emit-llvm-only -triple arm64-apple-macosx -verify %s 
-DSUPPORTED=1
 // RUN: %clang_cc1 -emit-llvm-only -triple x86_64-pc-win32 -verify %s 
-DNOT_SUPPORTED=1
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff -verify %s 
-DSUPPORTED=1
 
 // expected-no-diagnostics
 
diff --git a/llvm/lib/Transforms/Utils/LowerIFunc.cpp 
b/llvm/lib/Transforms/Utils/LowerIFunc.cpp
index 991890aa56b83..8c2bbce9215ef 100644
--- a/llvm/lib/Transforms/Utils/LowerIFunc.cpp
+++ b/llvm/lib/Transforms/Utils/LowerIFunc.cpp
@@ -13,14 +13,17 @@
 #include "llvm/Transforms/Utils/LowerIFunc.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Pass.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/TargetParser/Triple.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
 
 using namespace llvm;
 
+static cl::opt<bool> Enable("lower-ifuncs", cl::init(true), cl::Hidden);
+
 /// Replace all call users of ifuncs in the module.
 PreservedAnalyses LowerIFuncPass::run(Module &M, ModuleAnalysisManager &AM) {
-  if (M.ifunc_empty())
+  if (M.ifunc_empty() || !Enable)
     return PreservedAnalyses::all();
 
   Triple TargetTriple(M.getTargetTriple());
diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp 
b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index 10e898bf266f0..b8ad15f7de6c8 100644
--- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -476,7 +476,7 @@ void llvm::lowerIFuncsOnAIX(Module &M) {
     //   %res = musttail call i32 %DescPtr(i32 noundef %a) #3
     SmallVector<Value *, 10> Args(make_pointer_range(F->args()));
     CallInst *Result =
-        Builder.CreateCall(F->getFunctionType(), DescPtr, Args, "res");
+        Builder.CreateCall(F->getFunctionType(), DescPtr, Args);
     // Result->setTailCallKind(CallInst::TCK_MustTail);
 
     //   ret i32 %res

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to