Skip to content

Commit

Permalink
[PowerPC] Allow using initial-exec TLS with PIC
Browse files Browse the repository at this point in the history
Using initial-exec TLS variables is a reasonable performance
optimisation for system libraries. Use the correct PIC mechanism to get
hold of the GOT to avoid text relocations.

Differential Revision: https://reviews.llvm.org/D61026

llvm-svn: 359146
  • Loading branch information
jsonn committed Apr 24, 2019
1 parent 2f49676 commit 8372b46
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 6 deletions.
13 changes: 10 additions & 3 deletions llvm/lib/Target/PowerPC/PPCISelLowering.cpp
Expand Up @@ -2757,7 +2757,8 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
const Module *M = DAG.getMachineFunction().getFunction().getParent();
PICLevel::Level picLevel = M->getPICLevel();

TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
const TargetMachine &TM = getTargetMachine();
TLSModel::Model Model = TM.getTLSModel(GV);

if (Model == TLSModel::LocalExec) {
SDValue TGAHi = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
Expand All @@ -2781,8 +2782,14 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
GOTPtr = DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl,
PtrVT, GOTReg, TGA);
} else
GOTPtr = DAG.getNode(PPCISD::PPC32_GOT, dl, PtrVT);
} else {
if (!TM.isPositionIndependent())
GOTPtr = DAG.getNode(PPCISD::PPC32_GOT, dl, PtrVT);
else if (picLevel == PICLevel::SmallPIC)
GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
else
GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
}
SDValue TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL_L, dl,
PtrVT, TGA, GOTPtr);
return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/PowerPC/PPCISelLowering.h
Expand Up @@ -264,11 +264,11 @@ namespace llvm {
CR6UNSET,

/// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by initial-exec TLS
/// on PPC32.
/// for non-position independent code on PPC32.
PPC32_GOT,

/// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by general dynamic and
/// local dynamic TLS on PPC32.
/// local dynamic TLS and position indendepent code on PPC32.
PPC32_PICGOT,

/// G8RC = ADDIS_GOT_TPREL_HA %x2, Symbol - Used by the initial-exec
Expand Down
10 changes: 9 additions & 1 deletion llvm/test/CodeGen/PowerPC/tls.ll
@@ -1,6 +1,7 @@
; RUN: llc -relocation-model=static -verify-machineinstrs -O0 < %s -mcpu=ppc64 | FileCheck -check-prefix=OPT0 %s
; RUN: llc -relocation-model=static -verify-machineinstrs -O1 < %s -mcpu=ppc64 | FileCheck -check-prefix=OPT1 %s
; RUN: llc -verify-machineinstrs -O0 < %s -mtriple=ppc32-- -mcpu=ppc | FileCheck -check-prefix=OPT0-PPC32 %s
; RUN: llc -relocation-model=pic -verify-machineinstrs -O0 < %s -mtriple=ppc32-- -mcpu=ppc | FileCheck -check-prefix=OPT0-PPC32-PIC %s

target triple = "powerpc64-unknown-linux-gnu"

Expand All @@ -24,7 +25,7 @@ entry:
; Test correct assembly code generation for thread-local storage
; using the initial-exec model.

@a2 = external thread_local global i32
@a2 = external thread_local(initialexec) global i32

define signext i32 @main2() nounwind {
entry:
Expand All @@ -44,3 +45,10 @@ entry:
;OPT0-PPC32: addis [[REG1]], [[REG1]], _GLOBAL_OFFSET_TABLE_@ha
;OPT0-PPC32: lwz [[REG2:[0-9]+]], a2@got@tprel@l([[REG1]])
;OPT0-PPC32: add 3, [[REG2]], a2@tls

;OPT0-PPC32-PIC-LABEL: main2:
;OPT0-PPC32-PIC: .long _GLOBAL_OFFSET_TABLE_-{{.*}}
;OPT0-PPC32-PIC-NOT: li {{[0-9]+}}, _GLOBAL_OFFSET_TABLE_@l
;OPT0-PPC32-PIC-NOT: addis {{[0-9]+}}, {{[0-9+]}}, _GLOBAL_OFFSET_TABLE_@ha
;OPT0-PPC32-PIC-NOT: bl __tls_get_addr(a2@tlsgd)@PLT
;OPT0-PPC32-PIC: lwz {{[0-9]+}}, a2@got@tprel@l({{[0-9]+}})

0 comments on commit 8372b46

Please sign in to comment.