Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1547,6 +1547,9 @@ class TargetInfo : public TransferrableTargetInfo,
return true;
if (getTriple().getArch() == llvm::Triple::ArchType::avr)
return true;
if (getTriple().isOSAIX())
return getTriple().getOSMajorVersion() == 0 ||
getTriple().getOSVersion() >= VersionTuple(7, 2);
return getTriple().isOSBinFormatELF() &&
((getTriple().isOSLinux() && !getTriple().isMusl()) ||
getTriple().isOSFreeBSD());
Expand Down
23 changes: 4 additions & 19 deletions clang/lib/Driver/ToolChains/AIX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,25 +146,10 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-bforceimprw");
}

// PGO instrumentation generates symbols belonging to special sections, and
// the linker needs to place all symbols in a particular section together in
// memory; the AIX linker does that under an option.
if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
false) ||
Args.hasFlag(options::OPT_fprofile_generate,
options::OPT_fno_profile_generate, false) ||
Args.hasFlag(options::OPT_fprofile_generate_EQ,
options::OPT_fno_profile_generate, false) ||
Args.hasFlag(options::OPT_fprofile_instr_generate,
options::OPT_fno_profile_instr_generate, false) ||
Args.hasFlag(options::OPT_fprofile_instr_generate_EQ,
options::OPT_fno_profile_instr_generate, false) ||
Args.hasFlag(options::OPT_fcs_profile_generate,
options::OPT_fno_profile_generate, false) ||
Args.hasFlag(options::OPT_fcs_profile_generate_EQ,
options::OPT_fno_profile_generate, false) ||
Args.hasArg(options::OPT_fcreate_profile) ||
Args.hasArg(options::OPT_coverage))
// PGO and ifunc support depends on the named sections linker feature that is
// available on AIX 7.2 TL5 SP5 onwards.
if (ToolChain.getTriple().getOSMajorVersion() == 0 ||
ToolChain.getTriple().getOSVersion() >= VersionTuple(7, 2))
CmdArgs.push_back("-bdbg:namedsects:ss");

if (Arg *A =
Expand Down
2 changes: 2 additions & 0 deletions clang/test/CodeGen/attr-ifunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor Author

Choose a reason for hiding this comment

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

shud have at least one 32-bit test here or in anothe LIT

Copy link
Contributor

Choose a reason for hiding this comment

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

since the test case only test whether the source code is compiled pass or not ? do it matter 32bit or 64bit ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, maybe in this test it's not useful to test 32-bit, but we need some where to test that ifunc is supported in 32-bit AIX.

// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -verify -emit-llvm-only -DCHECK_ALIASES %s

#if defined(_WIN32) && !defined(__aarch64__)
void foo(void) {}
Expand Down
2 changes: 2 additions & 0 deletions clang/test/CodeGen/attr-ifunc.cpp
Original file line number Diff line number Diff line change
@@ -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")));
Expand Down
4 changes: 3 additions & 1 deletion clang/test/CodeGen/ifunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
// 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 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -O2 -emit-llvm -o - %s | FileCheck %s


/// The ifunc is emitted before its resolver.
Expand Down Expand Up @@ -65,7 +67,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:]] {
Expand Down
1 change: 1 addition & 0 deletions clang/test/SemaCXX/ifunc-has-attribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 10 additions & 0 deletions compiler-rt/lib/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,16 @@ if (NOT OS_NAME MATCHES "AIX")
${powerpc64_SOURCES}
)
endif()
if (OS_NAME MATCHES "AIX")
set(powerpc_SOURCES
ppc/init_ifuncs.c
${powerpc_SOURCES}
)
set(powerpc64_SOURCES
ppc/init_ifuncs.c
${powerpc64_SOURCES}
)
endif()
set(powerpc64le_SOURCES ${powerpc64_SOURCES})

set(riscv_SOURCES
Expand Down
22 changes: 22 additions & 0 deletions compiler-rt/lib/builtins/ppc/init_ifuncs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
typedef void* Ptr;
typedef struct { Ptr addr, toc, env; } Descr;
typedef struct { Descr* desc; Ptr (*resolver)(); } IFUNC_PAIR;

// A zero-length entry in section "ifunc_sec" to satisfy the __start_ifunc_sec
// and __stop_ifunc_sec references in this file, when no user code has any.
__attribute__((section("ifunc_sec"))) static int dummy_ifunc_sec[0];

extern IFUNC_PAIR __start_ifunc_sec, __stop_ifunc_sec;

__attribute__((constructor))
void __init_ifuncs() {
void *volatile ref = &dummy_ifunc_sec; // hack to keep dummy_ifunc_sec alive

// hack to prevent compiler from assuming __start_ifunc_sec and
// __stop_ifunc_sec occupy different addresses.
IFUNC_PAIR *volatile volatile_end = &__stop_ifunc_sec;
for (IFUNC_PAIR *pair = &__start_ifunc_sec, *end = volatile_end; pair != end;
pair++)
pair->desc->addr = ((Descr*)(pair->resolver()))->addr;
}

2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/AsmPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
virtual void emitModuleCommandLines(Module &M);

GCMetadataPrinter *getOrCreateGCPrinter(GCStrategy &S);
void emitGlobalIFunc(Module &M, const GlobalIFunc &GI);
virtual void emitGlobalIFunc(Module &M, const GlobalIFunc &GI);

/// This method decides whether the specified basic block requires a label.
bool shouldEmitLabelForBasicBlock(const MachineBasicBlock &MBB) const;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
static XCOFF::StorageClass getStorageClassForGlobal(const GlobalValue *GV);

MCSection *
getSectionForFunctionDescriptor(const Function *F,
getSectionForFunctionDescriptor(const GlobalObject *F,
const TargetMachine &TM) const override;
MCSection *getSectionForTOCEntry(const MCSymbol *Sym,
const TargetMachine &TM) const override;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Target/TargetLoweringObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ class LLVM_ABI TargetLoweringObjectFile : public MCObjectFileInfo {
/// On targets that use separate function descriptor symbols, return a section
/// for the descriptor given its symbol. Use only with defined functions.
virtual MCSection *
getSectionForFunctionDescriptor(const Function *F,
getSectionForFunctionDescriptor(const GlobalObject *F,
const TargetMachine &TM) const {
return nullptr;
}
Expand Down
2 changes: 0 additions & 2 deletions llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2426,8 +2426,6 @@ void AsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) {
}

void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {
assert(!TM.getTargetTriple().isOSBinFormatXCOFF() &&
"IFunc is not supported on AIX.");

auto EmitLinkage = [&](MCSymbol *Sym) {
if (GI.hasExternalLinkage() || !MAI->getWeakRefDirective())
Expand Down
16 changes: 12 additions & 4 deletions llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2391,7 +2391,8 @@ MCSymbol *
TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
const TargetMachine &TM) const {
// We always use a qualname symbol for a GV that represents
// a declaration, a function descriptor, or a common symbol.
// a declaration, a function descriptor, or a common symbol. An IFunc is
// lowered as a function, so it has an entry point and a descriptor.
// If a GV represents a GlobalVariable and -fdata-sections is enabled, we
// also return a qualname so that a label symbol could be avoided.
// It is inherently ambiguous when the GO represents the address of a
Expand All @@ -2410,6 +2411,11 @@ TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
SectionForGlobal(GVar, SectionKind::getData(), TM))
->getQualNameSymbol();

if (isa<GlobalIFunc>(GO))
return static_cast<const MCSectionXCOFF *>(
getSectionForFunctionDescriptor(GO, TM))
->getQualNameSymbol();

SectionKind GOKind = getKindForGlobal(GO, TM);
if (GOKind.isText())
return static_cast<const MCSectionXCOFF *>(
Expand Down Expand Up @@ -2682,7 +2688,7 @@ TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(const GlobalValue *GV) {

MCSymbol *TargetLoweringObjectFileXCOFF::getFunctionEntryPointSymbol(
const GlobalValue *Func, const TargetMachine &TM) const {
assert((isa<Function>(Func) ||
assert((isa<Function>(Func) || isa<GlobalIFunc>(Func) ||
(isa<GlobalAlias>(Func) &&
isa_and_nonnull<Function>(
cast<GlobalAlias>(Func)->getAliaseeObject()))) &&
Expand All @@ -2699,7 +2705,7 @@ MCSymbol *TargetLoweringObjectFileXCOFF::getFunctionEntryPointSymbol(
// undefined symbols gets treated as csect with XTY_ER property.
if (((TM.getFunctionSections() && !Func->hasSection()) ||
Func->isDeclarationForLinker()) &&
isa<Function>(Func)) {
(isa<Function>(Func) || isa<GlobalIFunc>(Func))) {
return getContext()
.getXCOFFSection(
NameStr, SectionKind::getText(),
Expand All @@ -2713,7 +2719,9 @@ MCSymbol *TargetLoweringObjectFileXCOFF::getFunctionEntryPointSymbol(
}

MCSection *TargetLoweringObjectFileXCOFF::getSectionForFunctionDescriptor(
const Function *F, const TargetMachine &TM) const {
const GlobalObject *F, const TargetMachine &TM) const {
assert((isa<Function>(F) || isa<GlobalIFunc>(F)) &&
"F must be a function or ifunc object.");
SmallString<128> NameStr;
getNameWithPrefix(NameStr, F, TM);
return getContext().getXCOFFSection(
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/PowerPC/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ add_llvm_target(PowerPCCodeGen
PPCMachineScheduler.cpp
PPCMacroFusion.cpp
PPCMIPeephole.cpp
PPCPrepareIFuncsOnAIX.cpp
PPCRegisterInfo.cpp
PPCSelectionDAGInfo.cpp
PPCSubtarget.cpp
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/PowerPC/PPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class ModulePass;
FunctionPass *createPPCPreEmitPeepholePass();
FunctionPass *createPPCExpandAtomicPseudoPass();
FunctionPass *createPPCCTRLoopsPass();
ModulePass *createPPCPrepareIFuncsOnAIXPass();
void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
AsmPrinter &AP);
bool LowerPPCMachineOperandToMCOperand(const MachineOperand &MO,
Expand All @@ -78,6 +79,7 @@ class ModulePass;
void initializePPCExpandAtomicPseudoPass(PassRegistry &);
void initializePPCCTRLoopsPass(PassRegistry &);
void initializePPCDAGToDAGISelLegacyPass(PassRegistry &);
void initializePPCPrepareIFuncsOnAIXPass(PassRegistry &);
void initializePPCLinuxAsmPrinterPass(PassRegistry &);
void initializePPCAIXAsmPrinterPass(PassRegistry &);

Expand Down
Loading
Loading