diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp index 6624a009a70..f8e6e8e314d 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp @@ -282,10 +282,6 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { return false; } -static inline bool shouldPrintPLT(TargetMachine &TM, const X86Subtarget* ST) { - return ST->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_; -} - /// print_pcrel_imm - This is used to print an immediate value that ends up /// being encoded as a pc-relative value. These print slightly differently, for /// example, a $ is not emitted. @@ -352,14 +348,11 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { O << "__imp_"; O << Name; - if (shouldPrintPLT(TM, Subtarget)) { - // Assemble call via PLT for externally visible symbols - if (!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() && - !GV->hasLocalLinkage()) { - O << "@PLT"; - assert(MO.getTargetFlags() == 0); - } - } + // Assemble call via PLT for externally visible symbols. + if (MO.getTargetFlags() == X86II::MO_PLT) + O << "@PLT"; + + if (Subtarget->isTargetCygMing() && GV->isDeclaration()) // Save function name for later type emission FnStubs.insert(Name); @@ -400,10 +393,8 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { O << ']'; } - if (shouldPrintPLT(TM, Subtarget)) { + if (MO.getTargetFlags() == X86II::MO_PLT) O << "@PLT"; - assert(MO.getTargetFlags() == 0); - } if (needCloseParen) O << ')'; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index d8594233001..eba503d8f2a 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1901,11 +1901,33 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // We should use extra load for direct calls to dllimported functions in // non-JIT mode. if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), - getTargetMachine(), true)) + getTargetMachine(), true)) { + unsigned char OpFlags = 0; + + // On ELF targets, in both X86-64 and X86-32 mode, direct calls to + // external symbols most go through the PLT in PIC mode. If the symbol + // has hidden or protected visibility, or if it is static or local, then + // we don't need to use the PLT - we can directly call it. + if (Subtarget->isTargetELF() && + getTargetMachine().getRelocationModel() == Reloc::PIC_ && + G->getGlobal()->hasDefaultVisibility() && + !G->getGlobal()->hasLocalLinkage()) + OpFlags = X86II::MO_PLT; + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy(), - G->getOffset()); + G->getOffset(), OpFlags); + } } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) { - Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy()); + unsigned char OpFlags = 0; + + // On ELF targets, in either X86-64 or X86-32 mode, direct calls to external + // symbols should go through the PLT. + if (Subtarget->isTargetELF() && + getTargetMachine().getRelocationModel() == Reloc::PIC_) + OpFlags = X86II::MO_PLT; + + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(), + OpFlags); } else if (IsTailCall) { unsigned Opc = Is64Bit ? X86::R11 : X86::EAX;