Index: lib/Target/PowerPC/PPCAsmPrinter.cpp =================================================================== --- lib/Target/PowerPC/PPCAsmPrinter.cpp +++ lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -583,34 +583,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: 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,17 @@ !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-BSS: bl call_foo@PLT{{$}} +; SMALL-SECURE: bl call_foo@PLT+32768 +; SMALL: lwz 30, 24(1)