1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 13:11:39 +01:00

[PowerPC] Another folow-up fix for 6c4b40def776

There was another issue introduced by this commit that the OP
initially missed. Namely, for functions that are free to use
R2 as a callee-saved register, we emit a TOC expression based
on the address of the GEP label without emitting the GEP label.
Since we only emit such expressions for the large code model, this
issue only surfaced there.

I have confirmed that with this fix, the kernel build is successful
with target "all".
This commit is contained in:
Nemanja Ivanovic 2020-04-10 21:05:41 -05:00
parent bb552531fd
commit f3d07ae265
2 changed files with 16 additions and 2 deletions

View File

@ -1463,10 +1463,15 @@ void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
!MF->getRegInfo().use_empty(PPC::R2);
const bool PCrelGEPRequired = Subtarget->isUsingPCRelativeCalls() &&
UsesX2OrR2 && PPCFI->usesTOCBasePtr();
const bool NonPCrelGEPRequired = !Subtarget->isUsingPCRelativeCalls() &&
Subtarget->isELFv2ABI() && UsesX2OrR2;
// Only do all that if the function uses R2 as the TOC pointer
// in the first place. We don't need the global entry point if the
// function uses R2 as an allocatable register.
if (Subtarget->isELFv2ABI() && UsesX2OrR2 && PPCFI->usesTOCBasePtr()) {
if (NonPCrelGEPRequired || PCrelGEPRequired) {
// Note: The logic here must be synchronized with the code in the
// branch-selection pass which sets the offset of the first block in the
// function. This matters because it affects the alignment.
@ -1521,7 +1526,7 @@ void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
if (TS)
TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
} else if (Subtarget->isELFv2ABI() && Subtarget->isUsingPCRelativeCalls()) {
} else if (Subtarget->isUsingPCRelativeCalls()) {
// When generating the entry point for a function we have a few scenarios
// based on whether or not that function uses R2 and whether or not that
// function makes calls (or is a leaf function).

View File

@ -4,6 +4,9 @@
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
; RUN: -mcpu=pwr9 -ppc-asm-full-reg-names < %s \
; RUN: | FileCheck %s --check-prefixes=CHECK-P9,CHECK-ALL
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
; RUN: -mcpu=pwr9 --code-model=large -ppc-asm-full-reg-names < %s \
; RUN: | FileCheck %s --check-prefixes=CHECK-LARGE,CHECK-ALL
@global_int = common dso_local local_unnamed_addr global i32 0, align 4
@ -38,6 +41,8 @@ define dso_local signext i32 @AsmClobberX2WithTOC(i32 signext %a, i32 signext %b
; CHECK-ALL-LABEL: AsmClobberX2WithTOC:
; CHECK-S: addis r2, r12, .TOC.-.Lfunc_gep2@ha
; CHECK-S-NEXT: addi r2, r2, .TOC.-.Lfunc_gep2@l
; CHECK-LARGE: ld r2, .Lfunc_toc2-.Lfunc_gep2(r12)
; CHECK-LARGE: add r2, r2, r12
; CHECK-S: .localentry AsmClobberX2WithTOC, .Lfunc_lep2-.Lfunc_gep2
; CHECK-S: #APP
; CHECK-S-NEXT: li r2, 0
@ -155,6 +160,8 @@ define dso_local signext i32 @UsesX2AsTOC() local_unnamed_addr {
; CHECK-ALL-LABEL: UsesX2AsTOC:
; CHECK-S: addis r2, r12, .TOC.-.Lfunc_gep6@ha
; CHECK-S-NEXT: addi r2, r2, .TOC.-.Lfunc_gep6@l
; CHECK-LARGE: ld r2, .Lfunc_toc6-.Lfunc_gep6(r12)
; CHECK-LARGE: add r2, r2, r12
; CHECK-S: .localentry UsesX2AsTOC, .Lfunc_lep6-.Lfunc_gep6
; CHECK-ALL: # %bb.0: # %entry
; CHECK-S-NEXT: addis r3, r2, global_int@toc@ha
@ -168,6 +175,8 @@ entry:
define dso_local double @UsesX2AsConstPoolTOC() local_unnamed_addr {
; CHECK-ALL-LABEL: UsesX2AsConstPoolTOC:
; CHECK-LARGE: ld r2, .Lfunc_toc7-.Lfunc_gep7(r12)
; CHECK-LARGE: add r2, r2, r12
; CHECK-S-NOT: .localentry
; CHECK-ALL: # %bb.0: # %entry
; CHECK-S-NEXT: plfd f1, .LCPI7_0@PCREL(0), 1