Skip to content

Commit

Permalink
[PowerPC] Add function pointer alignment to DataLayout
Browse files Browse the repository at this point in the history
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
  • Loading branch information
daltenty committed Apr 18, 2023
1 parent 2213509 commit 8d2e9fc
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 33 deletions.
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/OSTargets.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
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");
}
};

Expand Down
20 changes: 12 additions & 8 deletions clang/lib/Basic/Targets/PPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,11 +363,11 @@ class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo {
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:
Expand Down Expand Up @@ -418,19 +418,23 @@ class LLVM_LIBRARY_VISIBILITY PPC64TargetInfo : public PPCTargetInfo {

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()) {
Expand Down
22 changes: 11 additions & 11 deletions clang/test/CodeGen/target-data.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
24 changes: 12 additions & 12 deletions llvm/test/CodeGen/PowerPC/pr45301.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/ThinLTO/X86/builtin-nostrip-aix.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down

0 comments on commit 8d2e9fc

Please sign in to comment.