diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -519,7 +519,7 @@ this->IntMaxType = TargetInfo::SignedLongLong; this->Int64Type = TargetInfo::SignedLongLong; this->SizeType = TargetInfo::UnsignedInt; - this->resetDataLayout("E-m:e-p:32:32-i64:64-n32:64"); + this->resetDataLayout("E-m:e-p:32:32-Fi64-i64:64-n32:64"); } }; diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -363,11 +363,11 @@ PPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : PPCTargetInfo(Triple, Opts) { if (Triple.isOSAIX()) - resetDataLayout("E-m:a-p:32:32-i64:64-n32"); + resetDataLayout("E-m:a-p:32:32-Fi32-i64:64-n32"); else if (Triple.getArch() == llvm::Triple::ppcle) - resetDataLayout("e-m:e-p:32:32-i64:64-n32"); + resetDataLayout("e-m:e-p:32:32-Fn32-i64:64-n32"); else - resetDataLayout("E-m:e-p:32:32-i64:64-n32"); + resetDataLayout("E-m:e-p:32:32-Fn32-i64:64-n32"); switch (getTriple().getOS()) { case llvm::Triple::Linux: @@ -418,19 +418,23 @@ if (Triple.isOSAIX()) { // TODO: Set appropriate ABI for AIX platform. - DataLayout = "E-m:a-i64:64-n32:64"; + DataLayout = "E-m:a-Fi64-i64:64-n32:64"; LongDoubleWidth = 64; LongDoubleAlign = DoubleAlign = 32; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } else if ((Triple.getArch() == llvm::Triple::ppc64le)) { - DataLayout = "e-m:e-i64:64-n32:64"; + DataLayout = "e-m:e-Fn32-i64:64-n32:64"; ABI = "elfv2"; } else { - DataLayout = "E-m:e-i64:64-n32:64"; - if (Triple.isPPC64ELFv2ABI()) + DataLayout = "E-m:e"; + if (Triple.isPPC64ELFv2ABI()) { ABI = "elfv2"; - else + DataLayout += "-Fn32"; + } else { ABI = "elfv1"; + DataLayout += "-Fi64"; + } + DataLayout += "-i64:64-n32:64"; } if (Triple.isOSFreeBSD() || Triple.isOSOpenBSD() || Triple.isMusl()) { diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c --- a/clang/test/CodeGen/target-data.c +++ b/clang/test/CodeGen/target-data.c @@ -88,7 +88,7 @@ // RUN: %clang_cc1 -triple powerpc64-lv2 -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PS3 -// PS3: target datalayout = "E-m:e-p:32:32-i64:64-n32:64" +// PS3: target datalayout = "E-m:e-p:32:32-Fi64-i64:64-n32:64" // RUN: %clang_cc1 -triple i686-nacl -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=I686-NACL @@ -120,43 +120,43 @@ // RUN: %clang_cc1 -triple powerpc-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PPC -// PPC: target datalayout = "E-m:e-p:32:32-i64:64-n32" +// PPC: target datalayout = "E-m:e-p:32:32-Fn32-i64:64-n32" // RUN: %clang_cc1 -triple powerpcle-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PPCLE -// PPCLE: target datalayout = "e-m:e-p:32:32-i64:64-n32" +// PPCLE: target datalayout = "e-m:e-p:32:32-Fn32-i64:64-n32" // RUN: %clang_cc1 -triple powerpc64-freebsd -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PPC64-FREEBSD -// PPC64-FREEBSD: target datalayout = "E-m:e-i64:64-n32:64" +// PPC64-FREEBSD: target datalayout = "E-m:e-Fn32-i64:64-n32:64" // RUN: %clang_cc1 -triple powerpc64le-freebsd -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PPC64LE-FREEBSD -// PPC64LE-FREEBSD: target datalayout = "e-m:e-i64:64-n32:64" +// PPC64LE-FREEBSD: target datalayout = "e-m:e-Fn32-i64:64-n32:64" // RUN: %clang_cc1 -triple powerpc64-linux -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PPC64-LINUX -// PPC64-LINUX: target datalayout = "E-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64-LINUX: target datalayout = "E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple powerpc64-linux -o - -emit-llvm -target-cpu future %s | \ // RUN: FileCheck %s -check-prefix=PPC64-FUTURE -// PPC64-FUTURE: target datalayout = "E-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64-FUTURE: target datalayout = "E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple powerpc64-linux -o - -emit-llvm -target-cpu pwr10 %s | \ // RUN: FileCheck %s -check-prefix=PPC64-P10 -// PPC64-P10: target datalayout = "E-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64-P10: target datalayout = "E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple powerpc64le-linux -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PPC64LE-LINUX -// PPC64LE-LINUX: target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64LE-LINUX: target datalayout = "e-m:e-Fn32-i64:64-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple powerpc64le-linux -o - -emit-llvm -target-cpu future %s | \ // RUN: FileCheck %s -check-prefix=PPC64LE-FUTURE -// PPC64LE-FUTURE: target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64LE-FUTURE: target datalayout = "e-m:e-Fn32-i64:64-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple powerpc64le-linux -o - -emit-llvm -target-cpu pwr10 %s | \ // RUN: FileCheck %s -check-prefix=PPC64LE-P10 -// PPC64LE-P10: target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64LE-P10: target datalayout = "e-m:e-Fn32-i64:64-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple nvptx-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=NVPTX diff --git a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp --- a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -161,6 +161,17 @@ if (!is64Bit || T.getOS() == Triple::Lv2) Ret += "-p:32:32"; + // If the target ABI uses function descriptors, then the alignment of function + // pointers depends on the alignment used to emit the descriptor. Otherwise, + // function pointers are aligned to 32 bits because the instructions must be. + if ((T.getArch() == Triple::ppc64 && !T.isPPC64ELFv2ABI())) { + Ret += "-Fi64"; + } else if (T.isOSAIX()) { + Ret += is64Bit ? "-Fi64" : "-Fi32"; + } else { + Ret += "-Fn32"; + } + // Note, the alignment values for f64 and i64 on ppc64 in Darwin // documentation are wrong; these are correct (i.e. "what gcc does"). Ret += "-i64:64"; diff --git a/llvm/test/CodeGen/PowerPC/pr45301.ll b/llvm/test/CodeGen/PowerPC/pr45301.ll --- a/llvm/test/CodeGen/PowerPC/pr45301.ll +++ b/llvm/test/CodeGen/PowerPC/pr45301.ll @@ -12,21 +12,21 @@ ; CHECK-NEXT: bl i ; CHECK-NEXT: nop ; CHECK-NEXT: addis r4, r2, g@toc@ha -; CHECK-NEXT: addi r4, r4, g@toc@l -; CHECK-NEXT: ld r5, 16(r4) -; CHECK-NEXT: std r5, 16(r3) -; CHECK-NEXT: ld r6, 0(r4) -; CHECK-NEXT: std r6, 0(r3) -; CHECK-NEXT: rldicl r6, r6, 32, 32 -; CHECK-NEXT: ld r7, 8(r4) +; CHECK-NEXT: addi r5, r4, g@toc@l +; CHECK-NEXT: ld r6, 16(r5) +; CHECK-NEXT: std r6, 16(r3) +; CHECK-NEXT: ld r4, g@toc@l(r4) +; CHECK-NEXT: std r4, 0(r3) +; CHECK-NEXT: rldicl r4, r4, 32, 32 +; CHECK-NEXT: ld r7, 8(r5) ; CHECK-NEXT: std r7, 8(r3) -; CHECK-NEXT: ld r7, 24(r4) +; CHECK-NEXT: ld r7, 24(r5) ; CHECK-NEXT: std r7, 24(r3) -; CHECK-NEXT: ld r4, 32(r4) -; CHECK-NEXT: std r4, 32(r3) +; CHECK-NEXT: ld r5, 32(r5) +; CHECK-NEXT: std r5, 32(r3) +; CHECK-NEXT: stwbrx r4, 0, r3 ; CHECK-NEXT: li r4, 20 -; CHECK-NEXT: stwbrx r6, 0, r3 -; CHECK-NEXT: stwbrx r5, r3, r4 +; CHECK-NEXT: stwbrx r6, r3, r4 ; CHECK-NEXT: addi r1, r1, 112 ; CHECK-NEXT: ld r0, 16(r1) ; CHECK-NEXT: mtlr r0 diff --git a/llvm/test/ThinLTO/X86/builtin-nostrip-aix.ll b/llvm/test/ThinLTO/X86/builtin-nostrip-aix.ll --- a/llvm/test/ThinLTO/X86/builtin-nostrip-aix.ll +++ b/llvm/test/ThinLTO/X86/builtin-nostrip-aix.ll @@ -30,7 +30,7 @@ ; CHECK-NM: D __ssp_canary_word ; CHECK-NM: T __stack_chk_fail -target datalayout = "E-m:a-p:32:32-i64:64-n32" +target datalayout = "E-m:a-p:32:32-Fi32-i64:64-n32" target triple = "powerpc-ibm-aix-xcoff" define void @bar() {