diff --git a/llvm/lib/Target/ARM/ARMFastISel.cpp b/llvm/lib/Target/ARM/ARMFastISel.cpp index 436b6ac4d090..9849cb57d191 100644 --- a/llvm/lib/Target/ARM/ARMFastISel.cpp +++ b/llvm/lib/Target/ARM/ARMFastISel.cpp @@ -617,10 +617,7 @@ unsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, EVT VT) { if (VT != MVT::i32) return 0; Reloc::Model RelocM = TM.getRelocationModel(); - - // TODO: Need more magic for ARM PIC. - if (!isThumb2 && (RelocM == Reloc::PIC_)) return 0; - + bool IsIndirect = Subtarget->GVIsIndirectSymbol(GV, RelocM); unsigned DestReg = createResultReg(TLI.getRegClassFor(VT)); // Use movw+movt when possible, it avoids constant pool entries. @@ -668,17 +665,30 @@ unsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, EVT VT) { .addConstantPoolIndex(Idx); if (RelocM == Reloc::PIC_) MIB.addImm(Id); + AddOptionalDefs(MIB); } else { // The extra immediate is for addrmode2. MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(ARM::LDRcp), DestReg) .addConstantPoolIndex(Idx) .addImm(0); + AddOptionalDefs(MIB); + + if (RelocM == Reloc::PIC_) { + unsigned Opc = IsIndirect ? ARM::PICLDR : ARM::PICADD; + unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT)); + + MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, + DL, TII.get(Opc), NewDestReg) + .addReg(DestReg) + .addImm(Id); + AddOptionalDefs(MIB); + return NewDestReg; + } } - AddOptionalDefs(MIB); } - if (Subtarget->GVIsIndirectSymbol(GV, RelocM)) { + if (IsIndirect) { MachineInstrBuilder MIB; unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT)); if (isThumb2) diff --git a/llvm/test/CodeGen/ARM/fast-isel-pic.ll b/llvm/test/CodeGen/ARM/fast-isel-pic.ll new file mode 100644 index 000000000000..392a845d2cc3 --- /dev/null +++ b/llvm/test/CodeGen/ARM/fast-isel-pic.ll @@ -0,0 +1,43 @@ +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=pic -mtriple=arm-apple-ios | FileCheck %s --check-prefix=ARM +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARMv7 + +@g = global i32 0, align 4 + +define i32 @LoadGV() { +entry: +; THUMB: LoadGV +; THUMB: movw [[reg0:r[0-9]+]], +; THUMB: movt [[reg0]], +; THUMB: add [[reg0]], pc +; ARM: LoadGV +; ARM: ldr [[reg1:r[0-9]+]], +; ARM: add [[reg1]], pc, [[reg1]] +; ARMv7: LoadGV +; ARMv7: movw [[reg2:r[0-9]+]], +; ARMv7: movt [[reg2]], +; ARMv7: add [[reg2]], pc, [[reg2]] + %tmp = load i32* @g + ret i32 %tmp +} + +@i = external global i32 + +define i32 @LoadIndirectSymbol() { +entry: +; THUMB: LoadIndirectSymbol +; THUMB: movw r[[reg3:[0-9]+]], +; THUMB: movt r[[reg3]], +; THUMB: add r[[reg3]], pc +; THUMB: ldr r[[reg3]], [r[[reg3]]] +; ARM: LoadIndirectSymbol +; ARM: ldr [[reg4:r[0-9]+]], +; ARM: ldr [[reg4]], [pc, [[reg4]]] +; ARMv7: LoadIndirectSymbol +; ARMv7: movw r[[reg5:[0-9]+]], +; ARMv7: movt r[[reg5]], +; ARMv7: add r[[reg5]], pc, r[[reg5]] +; ARMv7: ldr r[[reg5]], [r[[reg5]]] + %tmp = load i32* @i + ret i32 %tmp +}