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.
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).
; 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
; 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
; 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
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