Index: lib/Target/PowerPC/PPCAsmPrinter.cpp =================================================================== --- lib/Target/PowerPC/PPCAsmPrinter.cpp +++ lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -461,6 +461,7 @@ StringRef Name = "__tls_get_addr"; MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name); MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; + const Module *M = MF->getFunction().getParent(); assert(MI->getOperand(0).isReg() && ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) || @@ -478,10 +479,10 @@ MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext); // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI. - if (Kind == MCSymbolRefExpr::VK_PLT && Subtarget->isSecurePlt()) - TlsRef = MCBinaryExpr::createAdd(TlsRef, - MCConstantExpr::create(32768, OutContext), - OutContext); + if (Kind == MCSymbolRefExpr::VK_PLT && Subtarget->isSecurePlt() && + M->getPICLevel() == PICLevel::BigPIC) + TlsRef = MCBinaryExpr::createAdd( + TlsRef, MCConstantExpr::create(32768, OutContext), OutContext); const MachineOperand &MO = MI->getOperand(2); const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); @@ -583,34 +584,30 @@ // Into: lwz %rt, .L0$poff - .L0$pb(%ri) // add %rd, %rt, %ri // or into (if secure plt mode is on): - // addis r30, r30, .LTOC - .L0$pb@ha - // addi r30, r30, .LTOC - .L0$pb@l + // addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha + // addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l // Get the offset from the GOT Base Register to the GOT LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); if (Subtarget->isSecurePlt() && isPositionIndependent() ) { unsigned PICR = TmpInst.getOperand(0).getReg(); - MCSymbol *LTOCSymbol = OutContext.getOrCreateSymbol(StringRef(".LTOC")); + MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol( + M->getPICLevel() == PICLevel::SmallPIC ? "_GLOBAL_OFFSET_TABLE_" + : ".LTOC"); const MCExpr *PB = - MCSymbolRefExpr::create(MF->getPICBaseSymbol(), - OutContext); + MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext); - const MCExpr *LTOCDeltaExpr = - MCBinaryExpr::createSub(MCSymbolRefExpr::create(LTOCSymbol, OutContext), - PB, OutContext); + const MCExpr *DeltaExpr = MCBinaryExpr::createSub( + MCSymbolRefExpr::create(BaseSymbol, OutContext), PB, OutContext); - const MCExpr *LTOCDeltaHi = - PPCMCExpr::createHa(LTOCDeltaExpr, false, OutContext); - EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS) - .addReg(PICR) - .addReg(PICR) - .addExpr(LTOCDeltaHi)); + const MCExpr *DeltaHi = PPCMCExpr::createHa(DeltaExpr, false, OutContext); + EmitToStreamer( + *OutStreamer, + MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi)); - const MCExpr *LTOCDeltaLo = - PPCMCExpr::createLo(LTOCDeltaExpr, false, OutContext); - EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI) - .addReg(PICR) - .addReg(PICR) - .addExpr(LTOCDeltaLo)); + const MCExpr *DeltaLo = PPCMCExpr::createLo(DeltaExpr, false, OutContext); + EmitToStreamer( + *OutStreamer, + MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo)); return; } else { MCSymbol *PICOffset = Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp =================================================================== --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -439,7 +439,8 @@ if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) == MVT::i32) { if (PPCSubTarget->isTargetELF()) { GlobalBaseReg = PPC::R30; - if (M->getPICLevel() == PICLevel::SmallPIC) { + if (!PPCSubTarget->isSecurePlt() && + M->getPICLevel() == PICLevel::SmallPIC) { BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MoveGOTtoLR)); BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg); MF->getInfo()->setUsesPICBase(true); @@ -4399,7 +4400,7 @@ if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) != MVT::i32 || (!TM.isPositionIndependent() || !PPCSubTarget->isSecurePlt()) || - !PPCSubTarget->isTargetELF() || M->getPICLevel() == PICLevel::SmallPIC) + !PPCSubTarget->isTargetELF()) break; SDValue Op = N->getOperand(1); Index: lib/Target/PowerPC/PPCMCInstLower.cpp =================================================================== --- lib/Target/PowerPC/PPCMCInstLower.cpp +++ lib/Target/PowerPC/PPCMCInstLower.cpp @@ -110,16 +110,16 @@ RefKind = MCSymbolRefExpr::VK_PLT; const MachineFunction *MF = MO.getParent()->getParent()->getParent(); + const Module *M = MF->getFunction().getParent(); const PPCSubtarget *Subtarget = &(MF->getSubtarget()); const TargetMachine &TM = Printer.TM; const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, RefKind, Ctx); - // -msecure-plt option works only in PIC mode. If secure plt mode - // is on add 32768 to symbol. + // If -msecure-plt -fPIC, add 32768 to symbol. if (Subtarget->isSecurePlt() && TM.isPositionIndependent() && + M->getPICLevel() == PICLevel::BigPIC && MO.getTargetFlags() == PPCII::MO_PLT) - Expr = MCBinaryExpr::createAdd(Expr, - MCConstantExpr::create(32768, Ctx), - Ctx); + Expr = + MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(32768, Ctx), Ctx); if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::createAdd(Expr, Index: test/CodeGen/PowerPC/ppc32-pic.ll =================================================================== --- test/CodeGen/PowerPC/ppc32-pic.ll +++ test/CodeGen/PowerPC/ppc32-pic.ll @@ -1,4 +1,7 @@ -; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck -check-prefix=SMALL-BSS %s +; RUN: llc < %s -mtriple=powerpc -relocation-model=pic | \ +; RUN: FileCheck -check-prefixes=SMALL,SMALL-BSS %s +; RUN: llc < %s -mtriple=powerpc -relocation-model=pic -mattr=+secure-plt | \ +; RUN: FileCheck -check-prefixes=SMALL,SMALL-SECUREPLT %s @bar = common global i32 0, align 4 declare i32 @call_foo(i32, ...) @@ -12,13 +15,16 @@ !llvm.module.flags = !{!0} !0 = !{i32 1, !"PIC Level", i32 1} -; SMALL-BSS-LABEL:foo: -; SMALL-BSS: stwu 1, -32(1) -; SMALL-BSS: stw 30, 24(1) -; SMALL-BSS: bl _GLOBAL_OFFSET_TABLE_@local-4 -; SMALL-BSS: mflr 30 -; SMALL-BSS-DAG: stw {{[0-9]+}}, 8(1) -; SMALL-BSS-DAG: lwz [[VREG:[0-9]+]], bar@GOT(30) -; SMALL-BSS-DAG: lwz {{[0-9]+}}, 0([[VREG]]) -; SMALL-BSS: bl call_foo@PLT -; SMALL-BSS: lwz 30, 24(1) +; SMALL-LABEL: foo: +; SMALL: stwu 1, -32(1) +; SMALL: stw 30, 24(1) +; SMALL-BSS: bl _GLOBAL_OFFSET_TABLE_@local-4 +; SMALL-SECURE: bl .L0$pb +; SMALL: mflr 30 +; SMALL-SECURE: addis 30, 30, _GLOBAL_OFFSET_TABLE_-.Lo$pb@ha +; SMALL-SECURE: addi 30, 30, _GLOBAL_OFFSET_TABLE_-.Lo$pb@l +; SMALL-DAG: stw {{[0-9]+}}, 8(1) +; SMALL-DAG: lwz [[VREG:[0-9]+]], bar@GOT(30) +; SMALL-DAG: lwz {{[0-9]+}}, 0([[VREG]]) +; SMALL: bl call_foo@PLT{{$}} +; SMALL: lwz 30, 24(1) Index: test/CodeGen/PowerPC/ppc32-secure-plt-tls2.ll =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/ppc32-secure-plt-tls2.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -mtriple=powerpc -mattr=+secure-plt -relocation-model=pic | FileCheck -check-prefix=SECURE-PLT-TLS %s + +@a = thread_local local_unnamed_addr global i32 6, align 4 +define i32 @main() local_unnamed_addr #0 { +entry: + %0 = load i32, i32* @a, align 4 + ret i32 %0 +} + + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"PIC Level", i32 1} + +; SECURE-PLT-TLS: mflr 30 +; SECURE-PLT-TLS-NEXT: addis 30, 30, _GLOBAL_OFFSET_TABLE_-.L0$pb@ha +; SECURE-PLT-TLS-NEXT: addi 30, 30, _GLOBAL_OFFSET_TABLE_-.L0$pb@l +; SECURE-PLT-TLS: addi 3, 30, a@got@tlsgd +; SECURE-PLT-TLS: bl __tls_get_addr(a@tlsgd)@PLT{{$}}