From f4a03e0903c4dca8e3dbb83f0f8b3ae9ded86369 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Sun, 29 Jan 2017 16:46:22 +0000 Subject: [PATCH] ARM: support `-mlong-calls` with AEABI TLS on ELF Support lowering AEABI TLS access (__aeabi_read_tp) with long calls. This requires adjusting the call sequence to use an indirect call to get full addressability. Resolves PR31769! llvm-svn: 293433 --- lib/Target/ARM/ARMExpandPseudoInsts.cpp | 35 ++++++++++++++++++++----- test/CodeGen/ARM/aeabi-read-tp.ll | 26 ++++++++++++++++++ 2 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 test/CodeGen/ARM/aeabi-read-tp.ll diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp index 06226168e93..78a9144bd32 100644 --- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -1231,15 +1231,36 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, } case ARM::tTPsoft: case ARM::TPsoft: { + const bool Thumb = Opcode == ARM::tTPsoft; + MachineInstrBuilder MIB; - if (Opcode == ARM::tTPsoft) - MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tBL)) - .add(predOps(ARMCC::AL)) - .addExternalSymbol("__aeabi_read_tp", 0); - else + if (STI->genLongCalls()) { + MachineFunction *MF = MBB.getParent(); + MachineConstantPool *MCP = MF->getConstantPool(); + unsigned PCLabelID = AFI->createPICLabelUId(); + MachineConstantPoolValue *CPV = + ARMConstantPoolSymbol::Create(MF->getFunction()->getContext(), + "__aeabi_read_tp", PCLabelID, 0); + unsigned Reg = MI.getOperand(0).getReg(); MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), - TII->get( ARM::BL)) - .addExternalSymbol("__aeabi_read_tp", 0); + TII->get(Thumb ? ARM::tLDRpci : ARM::LDRi12), Reg) + .addConstantPoolIndex(MCP->getConstantPoolIndex(CPV, 4)); + if (!Thumb) + MIB.addImm(0); + MIB.add(predOps(ARMCC::AL)); + + MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), + TII->get(Thumb ? ARM::tBLXr : ARM::BLX)); + if (Thumb) + MIB.add(predOps(ARMCC::AL)); + MIB.addReg(Reg, RegState::Kill); + } else { + MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), + TII->get(Thumb ? ARM::tBL : ARM::BL)); + if (Thumb) + MIB.add(predOps(ARMCC::AL)); + MIB.addExternalSymbol("__aeabi_read_tp", 0); + } MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); TransferImpOps(MI, MIB, MIB); diff --git a/test/CodeGen/ARM/aeabi-read-tp.ll b/test/CodeGen/ARM/aeabi-read-tp.ll new file mode 100644 index 00000000000..5f9815b6cd7 --- /dev/null +++ b/test/CodeGen/ARM/aeabi-read-tp.ll @@ -0,0 +1,26 @@ +; RUN: llc -mtriple armv7---eabi -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-SHORT +; RUN: llc -mtriple thumbv7---eabi -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-SHORT +; RUN: llc -mtriple armv7---eabi -mattr=+long-calls -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-LONG +; RUN: llc -mtriple thumbv7---eabi -mattr=+long-calls -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-LONG + +@i = thread_local local_unnamed_addr global i32 0, align 4 + +define i32 @f() local_unnamed_addr { +entry: + %0 = load i32, i32* @i, align 4 + ret i32 %0 +} + +; CHECK-LABEL: f: +; CHECK-SHORT: ldr r1, [[VAR:.LCPI[0-9]+_[0-9]+]] +; CHECK-SHORT-NEXT: bl __aeabi_read_tp +; CHECK-SHORT: [[VAR]]: +; CHECK-SHORT-NEXT: .long i(TPOFF) + +; CHECK-LONG: ldr [[REG:r[0-9]+]], [[FUN:.LCPI[0-9]+_[0-9]+]] +; CHECK-LONG-NEXT: ldr r1, [[VAR:.LCPI[0-9]+_[0-9]+]] +; CHECK-LONG-NEXT: blx [[REG]] +; CHECK-LONG: [[VAR]]: +; CHECK-LONG-NEXT: .long i(TPOFF) +; CHECK-LONG: [[FUN]]: +; CHECK-LONG-NEXT: .long __aeabi_read_tp