From: David Tenty Date: Tue, 18 Apr 2023 15:36:10 +0000 (-0400) Subject: [PowerPC] Add function pointer alignment to DataLayout X-Git-Tag: upstream/17.0.6~11173 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8d2e9fc8553c91b1f22e82ffc2c00020f40bb0a2;p=platform%2Fupstream%2Fllvm.git [PowerPC] Add function pointer alignment to DataLayout The alignment of function pointers was added to the Datalayout by D57335 but currently is unset for the Power target. This will cause us to compute a conservative minimum alignment of one if places like Value::getPointerAlignment. This patch implements the function pointer alignment in the Datalayout for the Power backend and Power targets in clang, so we can query the value for a particular Power target. We come up with the correct value one of two ways: - If the target uses function descriptor objects (i.e. ELFv1 & AIX ABIs), then a function pointer points to the descriptor, so use the alignment we would emit the descriptor with. - If the target doesn't use function descriptor objects (i.e. ELFv2), a function pointer points to the global entry point, so use the minimum alignment for code on Power (i.e. 4-bytes). Reviewed By: nemanjai Differential Revision: https://reviews.llvm.org/D147016 --- diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index ea21f7e..cb2a68f 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -519,7 +519,7 @@ public: 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 index 07a8a3a..8564fc0 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -363,11 +363,11 @@ public: 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 @@ public: 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 index e5ee17b..a7650c8 100644 --- 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 index 683a84e..3858d44 100644 --- a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -161,6 +161,17 @@ static std::string getDataLayoutString(const Triple &T) { 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 index fbd042f..bb6252e 100644 --- a/llvm/test/CodeGen/PowerPC/pr45301.ll +++ b/llvm/test/CodeGen/PowerPC/pr45301.ll @@ -12,21 +12,21 @@ define dso_local void @g(ptr %agg.result) local_unnamed_addr #0 { ; 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 index 428a521..0f2a3c5 100644 --- 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() {