From 04eae396176ccebe359bbb47ca1458a6377bbc4f Mon Sep 17 00:00:00 2001 From: Nemanja Ivanovic Date: Fri, 10 Apr 2020 21:05:41 -0500 Subject: [PATCH] [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". --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 9 +++++++-- llvm/test/CodeGen/PowerPC/pcrel-call-linkage-leaf.ll | 9 +++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index 54fb4d5..1d33a47 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -1463,10 +1463,15 @@ void PPCLinuxAsmPrinter::emitFunctionBodyStart() { const PPCFunctionInfo *PPCFI = MF->getInfo(); 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(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). diff --git a/llvm/test/CodeGen/PowerPC/pcrel-call-linkage-leaf.ll b/llvm/test/CodeGen/PowerPC/pcrel-call-linkage-leaf.ll index 13d2660..66d2941 100644 --- a/llvm/test/CodeGen/PowerPC/pcrel-call-linkage-leaf.ll +++ b/llvm/test/CodeGen/PowerPC/pcrel-call-linkage-leaf.ll @@ -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 -- 2.7.4