Index: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h @@ -264,11 +264,11 @@ 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 Index: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp @@ -2757,7 +2757,8 @@ 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, @@ -2781,8 +2782,14 @@ 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); Index: llvm/trunk/test/CodeGen/PowerPC/tls.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/tls.ll +++ llvm/trunk/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" @@ -24,7 +25,7 @@ ; 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: @@ -44,3 +45,10 @@ ;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]+}})