diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index f4aaf09038a..628b5141408 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -2460,15 +2460,22 @@ bool ARMFastISel::SelectCall(const Instruction *I, MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc)); + unsigned char OpFlags = 0; + + // Add MO_PLT for global address or external symbol in the PIC relocation + // model. + if (Subtarget->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_) + OpFlags = ARMII::MO_PLT; + // ARM calls don't take a predicate, but tBL / tBLX do. if(isThumb2) AddDefaultPred(MIB); if (UseReg) MIB.addReg(CalleeReg); else if (!IntrMemName) - MIB.addGlobalAddress(GV, 0, 0); + MIB.addGlobalAddress(GV, 0, OpFlags); else - MIB.addExternalSymbol(IntrMemName, 0); + MIB.addExternalSymbol(IntrMemName, OpFlags); // Add implicit physical register uses to the call. for (unsigned i = 0, e = RegArgs.size(); i != e; ++i) diff --git a/test/CodeGen/ARM/pic.ll b/test/CodeGen/ARM/pic.ll new file mode 100644 index 00000000000..32cea50caee --- /dev/null +++ b/test/CodeGen/ARM/pic.ll @@ -0,0 +1,23 @@ +; Check the function call in PIC relocation model. + +; If the relocation model is PIC, then the "bl" instruction for the function +; call to the external function should come with PLT fixup type. + +; RUN: llc < %s -mtriple=armv7-unknown-linux-gnueabi \ +; RUN: -relocation-model=pic -fast-isel \ +; RUN: | FileCheck %s + +define void @test() { +entry: + + %0 = call i32 @get() +; CHECK: bl get(PLT) + + call void @put(i32 %0) +; CHECK: bl put(PLT) + + ret void +} + +declare i32 @get() +declare void @put(i32)