Index: llvm/trunk/include/llvm/MC/MCExpr.h =================================================================== --- llvm/trunk/include/llvm/MC/MCExpr.h +++ llvm/trunk/include/llvm/MC/MCExpr.h @@ -188,6 +188,7 @@ VK_WEAKREF, // The link between the symbols in .weakref foo, bar VK_ARM_NONE, + VK_ARM_GOT_PREL, VK_ARM_TARGET1, VK_ARM_TARGET2, VK_ARM_PREL31, Index: llvm/trunk/lib/MC/MCExpr.cpp =================================================================== --- llvm/trunk/lib/MC/MCExpr.cpp +++ llvm/trunk/lib/MC/MCExpr.cpp @@ -202,6 +202,7 @@ case VK_SIZE: return "SIZE"; case VK_WEAKREF: return "WEAKREF"; case VK_ARM_NONE: return "none"; + case VK_ARM_GOT_PREL: return "GOT_PREL"; case VK_ARM_TARGET1: return "target1"; case VK_ARM_TARGET2: return "target2"; case VK_ARM_PREL31: return "prel31"; @@ -311,7 +312,6 @@ .Case("got", VK_GOT) .Case("gotoff", VK_GOTOFF) .Case("gotpcrel", VK_GOTPCREL) - .Case("got_prel", VK_GOTPCREL) .Case("gottpoff", VK_GOTTPOFF) .Case("indntpoff", VK_INDNTPOFF) .Case("ntpoff", VK_NTPOFF) @@ -383,6 +383,7 @@ .Case("got@tlsld@h", VK_PPC_GOT_TLSLD_HI) .Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA) .Case("none", VK_ARM_NONE) + .Case("got_prel", VK_ARM_GOT_PREL) .Case("target1", VK_ARM_TARGET1) .Case("target2", VK_ARM_TARGET2) .Case("prel31", VK_ARM_PREL31) Index: llvm/trunk/lib/Target/ARM/ARM.h =================================================================== --- llvm/trunk/lib/Target/ARM/ARM.h +++ llvm/trunk/lib/Target/ARM/ARM.h @@ -35,7 +35,6 @@ FunctionPass *createA15SDOptimizerPass(); FunctionPass *createARMLoadStoreOptimizationPass(bool PreAlloc = false); FunctionPass *createARMExpandPseudoPass(); -FunctionPass *createARMGlobalBaseRegPass(); FunctionPass *createARMConstantIslandPass(); FunctionPass *createMLxExpansionPass(); FunctionPass *createThumb2ITBlockPass(); Index: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp @@ -819,8 +819,7 @@ case ARMCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; case ARMCP::TPOFF: return MCSymbolRefExpr::VK_TPOFF; case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_GOTTPOFF; - case ARMCP::GOT: return MCSymbolRefExpr::VK_GOT; - case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_GOTOFF; + case ARMCP::GOT_PREL: return MCSymbolRefExpr::VK_ARM_GOT_PREL; } llvm_unreachable("Invalid ARMCPModifier!"); } Index: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1379,9 +1379,9 @@ // instructions, so that's probably OK, but is PIC always correct when // we get here? if (ACPV->isGlobalValue()) - NewCPV = ARMConstantPoolConstant:: - Create(cast(ACPV)->getGV(), PCLabelId, - ARMCP::CPValue, 4); + NewCPV = ARMConstantPoolConstant::Create( + cast(ACPV)->getGV(), PCLabelId, ARMCP::CPValue, + 4, ACPV->getModifier(), ACPV->mustAddCurrentAddress()); else if (ACPV->isExtSymbol()) NewCPV = ARMConstantPoolSymbol:: Create(MF.getFunction()->getContext(), Index: llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h =================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h +++ llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h @@ -39,8 +39,7 @@ enum ARMCPModifier { no_modifier, TLSGD, - GOT, - GOTOFF, + GOT_PREL, GOTTPOFF, TPOFF }; Index: llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp +++ llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp @@ -52,8 +52,7 @@ // strings if that's legal. case ARMCP::no_modifier: return "none"; case ARMCP::TLSGD: return "tlsgd"; - case ARMCP::GOT: return "GOT"; - case ARMCP::GOTOFF: return "GOTOFF"; + case ARMCP::GOT_PREL: return "GOT_PREL"; case ARMCP::GOTTPOFF: return "gottpoff"; case ARMCP::TPOFF: return "tpoff"; } Index: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp @@ -2939,48 +2939,51 @@ unsigned ARMFastISel::ARMLowerPICELF(const GlobalValue *GV, unsigned Align, MVT VT) { - bool UseGOTOFF = GV->hasLocalLinkage() || GV->hasHiddenVisibility(); - ARMConstantPoolConstant *CPV = - ARMConstantPoolConstant::Create(GV, UseGOTOFF ? ARMCP::GOTOFF : ARMCP::GOT); - unsigned Idx = MCP.getConstantPoolIndex(CPV, Align); + bool UseGOT_PREL = + !(GV->hasHiddenVisibility() || GV->isStrongDefinitionForLinker()); - unsigned Opc; - unsigned DestReg1 = createResultReg(TLI.getRegClassFor(VT)); - // Load value. - if (isThumb2) { - DestReg1 = constrainOperandRegClass(TII.get(ARM::t2LDRpci), DestReg1, 0); - AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, - TII.get(ARM::t2LDRpci), DestReg1) - .addConstantPoolIndex(Idx)); - Opc = UseGOTOFF ? ARM::t2ADDrr : ARM::t2LDRs; - } else { - // The extra immediate is for addrmode2. - DestReg1 = constrainOperandRegClass(TII.get(ARM::LDRcp), DestReg1, 0); - AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, - DbgLoc, TII.get(ARM::LDRcp), DestReg1) - .addConstantPoolIndex(Idx).addImm(0)); - Opc = UseGOTOFF ? ARM::ADDrr : ARM::LDRrs; - } - - unsigned GlobalBaseReg = AFI->getGlobalBaseReg(); - if (GlobalBaseReg == 0) { - GlobalBaseReg = MRI.createVirtualRegister(TLI.getRegClassFor(VT)); - AFI->setGlobalBaseReg(GlobalBaseReg); - } - - unsigned DestReg2 = createResultReg(TLI.getRegClassFor(VT)); - DestReg2 = constrainOperandRegClass(TII.get(Opc), DestReg2, 0); - DestReg1 = constrainOperandRegClass(TII.get(Opc), DestReg1, 1); - GlobalBaseReg = constrainOperandRegClass(TII.get(Opc), GlobalBaseReg, 2); - MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, - DbgLoc, TII.get(Opc), DestReg2) - .addReg(DestReg1) - .addReg(GlobalBaseReg); - if (!UseGOTOFF) + LLVMContext *Context = &MF->getFunction()->getContext(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); + unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; + ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create( + GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj, + UseGOT_PREL ? ARMCP::GOT_PREL : ARMCP::no_modifier, + /*AddCurrentAddress=*/UseGOT_PREL); + + unsigned ConstAlign = + MF->getDataLayout().getPrefTypeAlignment(Type::getInt32PtrTy(*Context)); + unsigned Idx = MF->getConstantPool()->getConstantPoolIndex(CPV, ConstAlign); + + unsigned TempReg = MF->getRegInfo().createVirtualRegister(&ARM::rGPRRegClass); + unsigned Opc = isThumb2 ? ARM::t2LDRpci : ARM::LDRcp; + MachineInstrBuilder MIB = + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), TempReg) + .addConstantPoolIndex(Idx); + if (Opc == ARM::LDRcp) MIB.addImm(0); - AddOptionalDefs(MIB); + AddDefaultPred(MIB); + + // Fix the address by adding pc. + unsigned DestReg = createResultReg(TLI.getRegClassFor(VT)); + Opc = Subtarget->isThumb() ? ARM::tPICADD : UseGOT_PREL ? ARM::PICLDR + : ARM::PICADD; + DestReg = constrainOperandRegClass(TII.get(Opc), DestReg, 0); + MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), DestReg) + .addReg(TempReg) + .addImm(ARMPCLabelIndex); + if (!Subtarget->isThumb()) + AddDefaultPred(MIB); - return DestReg2; + if (UseGOT_PREL && Subtarget->isThumb()) { + unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT)); + MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(ARM::t2LDRi12), NewDestReg) + .addReg(DestReg) + .addImm(0); + DestReg = NewDestReg; + AddOptionalDefs(MIB); + } + return DestReg; } bool ARMFastISel::fastLowerArguments() { Index: llvm/trunk/lib/Target/ARM/ARMISelLowering.h =================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h @@ -514,7 +514,6 @@ SDValue LowerToTLSExecModels(GlobalAddressSDNode *GA, SelectionDAG &DAG, TLSModel::Model model) const; - SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const; SDValue LowerXALUO(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const; Index: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp @@ -788,7 +788,6 @@ setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); - setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom); setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); setOperationAction(ISD::BlockAddress, MVT::i32, Custom); @@ -2637,10 +2636,19 @@ SDLoc dl(Op); const GlobalValue *GV = cast(Op)->getGlobal(); if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { - bool UseGOTOFF = GV->hasLocalLinkage() || GV->hasHiddenVisibility(); - ARMConstantPoolValue *CPV = - ARMConstantPoolConstant::Create(GV, - UseGOTOFF ? ARMCP::GOTOFF : ARMCP::GOT); + bool UseGOT_PREL = + !(GV->hasHiddenVisibility() || GV->isStrongDefinitionForLinker()); + + MachineFunction &MF = DAG.getMachineFunction(); + ARMFunctionInfo *AFI = MF.getInfo(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); + EVT PtrVT = getPointerTy(DAG.getDataLayout()); + SDLoc dl(Op); + unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; + ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create( + GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj, + UseGOT_PREL ? ARMCP::GOT_PREL : ARMCP::no_modifier, + /*AddCurrentAddress=*/UseGOT_PREL); SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); SDValue Result = DAG.getLoad( @@ -2648,9 +2656,9 @@ MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), false, false, false, 0); SDValue Chain = Result.getValue(1); - SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(PtrVT); - Result = DAG.getNode(ISD::ADD, dl, PtrVT, Result, GOT); - if (!UseGOTOFF) + SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32); + Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); + if (UseGOT_PREL) Result = DAG.getLoad(PtrVT, dl, Chain, Result, MachinePointerInfo::getGOT(DAG.getMachineFunction()), false, false, false, 0); @@ -2727,29 +2735,6 @@ return Result; } -SDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op, - SelectionDAG &DAG) const { - assert(Subtarget->isTargetELF() && - "GLOBAL OFFSET TABLE not implemented for non-ELF targets"); - MachineFunction &MF = DAG.getMachineFunction(); - ARMFunctionInfo *AFI = MF.getInfo(); - unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); - EVT PtrVT = getPointerTy(DAG.getDataLayout()); - SDLoc dl(Op); - unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; - ARMConstantPoolValue *CPV = - ARMConstantPoolSymbol::Create(*DAG.getContext(), "_GLOBAL_OFFSET_TABLE_", - ARMPCLabelIndex, PCAdj); - SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); - CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); - SDValue Result = - DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, - MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), - false, false, false, 0); - SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32); - return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); -} - SDValue ARMTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const { SDLoc dl(Op); @@ -6783,7 +6768,6 @@ case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); - case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG); case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG); case ISD::EH_SJLJ_SETUP_DISPATCH: return LowerEH_SJLJ_SETUP_DISPATCH(Op, DAG); Index: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp @@ -132,73 +132,3 @@ MIB.setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); AddDefaultPred(MIB); } - -namespace { -/// ARMCGBR - Create Global Base Reg pass. This initializes the PIC -/// global base register for ARM ELF. -struct ARMCGBR : public MachineFunctionPass { - static char ID; - ARMCGBR() : MachineFunctionPass(ID) {} - - bool runOnMachineFunction(MachineFunction &MF) override { - ARMFunctionInfo *AFI = MF.getInfo(); - if (AFI->getGlobalBaseReg() == 0) - return false; - const ARMSubtarget &STI = - static_cast(MF.getSubtarget()); - // Don't do this for Thumb1. - if (STI.isThumb1Only()) - return false; - - const TargetMachine &TM = MF.getTarget(); - if (TM.getRelocationModel() != Reloc::PIC_) - return false; - - LLVMContext *Context = &MF.getFunction()->getContext(); - unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); - unsigned PCAdj = STI.isThumb() ? 4 : 8; - ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create( - *Context, "_GLOBAL_OFFSET_TABLE_", ARMPCLabelIndex, PCAdj); - - unsigned Align = - MF.getDataLayout().getPrefTypeAlignment(Type::getInt32PtrTy(*Context)); - unsigned Idx = MF.getConstantPool()->getConstantPoolIndex(CPV, Align); - - MachineBasicBlock &FirstMBB = MF.front(); - MachineBasicBlock::iterator MBBI = FirstMBB.begin(); - DebugLoc DL = FirstMBB.findDebugLoc(MBBI); - unsigned TempReg = - MF.getRegInfo().createVirtualRegister(&ARM::rGPRRegClass); - unsigned Opc = STI.isThumb2() ? ARM::t2LDRpci : ARM::LDRcp; - const TargetInstrInfo &TII = *STI.getInstrInfo(); - MachineInstrBuilder MIB = BuildMI(FirstMBB, MBBI, DL, TII.get(Opc), TempReg) - .addConstantPoolIndex(Idx); - if (Opc == ARM::LDRcp) - MIB.addImm(0); - AddDefaultPred(MIB); - - // Fix the GOT address by adding pc. - unsigned GlobalBaseReg = AFI->getGlobalBaseReg(); - Opc = STI.isThumb2() ? ARM::tPICADD : ARM::PICADD; - MIB = BuildMI(FirstMBB, MBBI, DL, TII.get(Opc), GlobalBaseReg) - .addReg(TempReg) - .addImm(ARMPCLabelIndex); - if (Opc == ARM::PICADD) - AddDefaultPred(MIB); - - return true; - } - - const char *getPassName() const override { - return "ARM PIC Global Base Reg Initialization"; - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - MachineFunctionPass::getAnalysisUsage(AU); - } -}; -} - -char ARMCGBR::ID = 0; -FunctionPass *llvm::createARMGlobalBaseRegPass() { return new ARMCGBR(); } Index: llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h =================================================================== --- llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h +++ llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h @@ -110,11 +110,6 @@ /// pass. DenseMap CPEClones; - /// GlobalBaseReg - keeps track of the virtual register initialized for - /// use as the global base register. This is used for PIC in some PIC - /// relocation models. - unsigned GlobalBaseReg; - /// ArgumentStackSize - amount of bytes on stack consumed by the arguments /// being passed on the stack unsigned ArgumentStackSize; @@ -133,7 +128,7 @@ FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0), GPRCS1Size(0), GPRCS2Size(0), DPRCSAlignGapSize(0), DPRCSSize(0), NumAlignedDPRCS2Regs(0), PICLabelUId(0), - VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {} + VarArgsFrameIndex(0), HasITBlocks(false) {} explicit ARMFunctionInfo(MachineFunction &MF); @@ -204,9 +199,6 @@ bool hasITBlocks() const { return HasITBlocks; } void setHasITBlocks(bool h) { HasITBlocks = h; } - unsigned getGlobalBaseReg() const { return GlobalBaseReg; } - void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; } - void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) { if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second) llvm_unreachable("Duplicate entries!"); Index: llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.cpp +++ llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.cpp @@ -20,5 +20,4 @@ RestoreSPFromFP(false), LRSpilledForFarJump(false), FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0), GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), - PICLabelUId(0), VarArgsFrameIndex(0), HasITBlocks(false), - GlobalBaseReg(0) {} + PICLabelUId(0), VarArgsFrameIndex(0), HasITBlocks(false) {} Index: llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp @@ -362,9 +362,6 @@ bool ARMPassConfig::addInstSelector() { addPass(createARMISelDag(getARMTargetMachine(), getOptLevel())); - - if (TM->getTargetTriple().isOSBinFormatELF() && TM->Options.EnableFastISel) - addPass(createARMGlobalBaseRegPass()); return false; } Index: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -95,7 +95,7 @@ case MCSymbolRefExpr::VK_GOTTPOFF: Type = ELF::R_ARM_TLS_IE32; break; - case MCSymbolRefExpr::VK_GOTPCREL: + case MCSymbolRefExpr::VK_ARM_GOT_PREL: Type = ELF::R_ARM_GOT_PREL; break; } @@ -192,7 +192,7 @@ case MCSymbolRefExpr::VK_GOTOFF: Type = ELF::R_ARM_GOTOFF32; break; - case MCSymbolRefExpr::VK_GOTPCREL: + case MCSymbolRefExpr::VK_ARM_GOT_PREL: Type = ELF::R_ARM_GOT_PREL; break; case MCSymbolRefExpr::VK_ARM_TARGET1: Index: llvm/trunk/test/CodeGen/ARM/emutls.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/emutls.ll +++ llvm/trunk/test/CodeGen/ARM/emutls.ll @@ -10,9 +10,7 @@ define i32 @my_get_xyz() { ; ARM32-LABEL: my_get_xyz: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl my_emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -34,9 +32,7 @@ define i32 @f1() { ; ARM32-LABEL: f1: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -48,9 +44,7 @@ define i32* @f2() { ; ARM32-LABEL: f2: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: pop @@ -61,9 +55,7 @@ define i32 @f3() nounwind { ; ARM32-LABEL: f3: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -75,9 +67,7 @@ define i32* @f4() { ; ARM32-LABEL: f4: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: pop @@ -88,9 +78,7 @@ define i32 @f5() nounwind { ; ARM32-LABEL: f5: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -102,9 +90,7 @@ define i32* @f6() { ; ARM32-LABEL: f6: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: pop @@ -115,9 +101,7 @@ define i32 @f7() { ; ARM32-LABEL: f7: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -129,9 +113,7 @@ define i32* @f8() { ; ARM32-LABEL: f8: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: pop @@ -142,9 +124,7 @@ define i32 @f9() { ; ARM32-LABEL: f9: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -156,9 +136,7 @@ define i32* @f10() { ; ARM32-LABEL: f10: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: pop @@ -169,9 +147,7 @@ define i16 @f11() { ; ARM32-LABEL: f11: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldrh r0, [r0] @@ -183,9 +159,7 @@ define i32 @f12() { ; ARM32-LABEL: f12: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldrsh r0, [r0] @@ -198,9 +172,7 @@ define i8 @f13() { ; ARM32-LABEL: f13: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldrb r0, [r0] ; ARM32-NEXT: pop @@ -213,9 +185,7 @@ define i32 @f14() { ; ARM32-LABEL: f14: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldrsb r0, [r0] ; ARM32-NEXT: pop Index: llvm/trunk/test/CodeGen/ARM/fast-isel-pic.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/fast-isel-pic.ll +++ llvm/trunk/test/CodeGen/ARM/fast-isel-pic.ll @@ -1,7 +1,7 @@ ; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB ; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARMv7 -; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=pic -mtriple=thumbv7-none-linux-gnueabi | FileCheck %s --check-prefix=THUMB-ELF -; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=pic -mtriple=armv7-none-linux-gnueabi | FileCheck %s --check-prefix=ARMv7-ELF +; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -arm-force-fast-isel -relocation-model=pic -mtriple=thumbv7-none-linux-gnueabi | FileCheck %s --check-prefix=THUMB-ELF +; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -arm-force-fast-isel -relocation-model=pic -mtriple=armv7-none-linux-gnueabi | FileCheck %s --check-prefix=ARMv7-ELF @g = global i32 0, align 4 @@ -13,8 +13,8 @@ ; THUMB: add [[reg0]], pc ; THUMB-ELF: LoadGV ; THUMB-ELF: ldr r[[reg0:[0-9]+]], -; THUMB-ELF: ldr r[[reg1:[0-9]+]], -; THUMB-ELF: ldr r[[reg0]], [r[[reg0]], r[[reg1]]] +; THUMB-ELF: add r[[reg0]], pc +; THUMB-ELF: ldr r[[reg0]], [r[[reg0]]] ; ARM: LoadGV ; ARM: ldr [[reg1:r[0-9]+]], ; ARM: add [[reg1]], pc, [[reg1]] @@ -26,8 +26,7 @@ ; ARMv7-ELF: ldr r[[reg2:[0-9]+]], ; ARMv7-ELF: .LPC ; ARMv7-ELF-NEXT: add r[[reg2]], pc -; ARMv7-ELF: ldr r[[reg3:[0-9]+]], -; ARMv7-ELF: ldr r[[reg2]], [r[[reg3]], r[[reg2]]] +; ARMv7-ELF: ldr r[[reg2]], [r[[reg2]]] %tmp = load i32, i32* @g ret i32 %tmp } @@ -43,8 +42,8 @@ ; THUMB: ldr r[[reg3]], [r[[reg3]]] ; THUMB-ELF: LoadIndirectSymbol ; THUMB-ELF: ldr r[[reg3:[0-9]+]], -; THUMB-ELF: ldr r[[reg4:[0-9]+]], -; THUMB-ELF: ldr r[[reg3]], [r[[reg3]], r[[reg4]]] +; THUMB-ELF: ldr r[[reg4:[0-9]+]], [r[[reg3]]] +; THUMB-ELF: ldr r0, [r[[reg4]]] ; ARM: LoadIndirectSymbol ; ARM: ldr [[reg4:r[0-9]+]], ; ARM: ldr [[reg4]], [pc, [[reg4]]] @@ -56,9 +55,8 @@ ; ARMv7-ELF: LoadIndirectSymbol ; ARMv7-ELF: ldr r[[reg5:[0-9]+]], ; ARMv7-ELF: .LPC -; ARMv7-ELF-NEXT: add r[[reg5]], pc -; ARMv7-ELF: ldr r[[reg6:[0-9]+]], -; ARMv7-ELF: ldr r[[reg5]], [r[[reg6]], r[[reg5]]] +; ARMv7-ELF: ldr r[[reg6:[0-9]+]], [pc, r[[reg5]]] +; ARMv7-ELF: ldr r0, [r[[reg5]]] %tmp = load i32, i32* @i ret i32 %tmp } Index: llvm/trunk/test/CodeGen/ARM/globals.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/globals.ll +++ llvm/trunk/test/CodeGen/ARM/globals.ll @@ -60,16 +60,13 @@ ; LinuxPIC-LABEL: test1: ; LinuxPIC: ldr r0, .LCPI0_0 -; LinuxPIC: ldr r1, .LCPI0_1 ; LinuxPIC: .LPC0_0: -; LinuxPIC: add r0, pc, r0 -; LinuxPIC: ldr r0, [r1, r0] +; LinuxPIC: ldr r0, [pc, r0] ; LinuxPIC: ldr r0, [r0] ; LinuxPIC: bx lr ; LinuxPIC: .align 2 ; LinuxPIC: .LCPI0_0: -; LinuxPIC: .long _GLOBAL_OFFSET_TABLE_-(.LPC0_0+8) -; LinuxPIC: .LCPI0_1: -; LinuxPIC: .long G(GOT) +; LinuxPIC: .Ltmp0: +; LinuxPIC: .long G(GOT_PREL)-((.LPC0_0+8)-.Ltmp0) Index: llvm/trunk/test/CodeGen/ARM/load-global.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/load-global.ll +++ llvm/trunk/test/CodeGen/ARM/load-global.ll @@ -4,6 +4,7 @@ ; RUN: llc < %s -mtriple=thumbv6-apple-darwin -relocation-model=pic | FileCheck %s -check-prefix=PIC_T ; RUN: llc < %s -mtriple=armv7-apple-darwin -relocation-model=pic | FileCheck %s -check-prefix=PIC_V7 ; RUN: llc < %s -mtriple=armv6-linux-gnueabi -relocation-model=pic | FileCheck %s -check-prefix=LINUX +; RUN: llc < %s -mtriple=thumbv6-linux-gnueabi -relocation-model=pic | FileCheck %s -check-prefix=LINUX_T @G = external global i32 @@ -40,11 +41,14 @@ ; LINUX: test1 ; LINUX: ldr r0, .LCPI0_0 -; LINUX: ldr r1, .LCPI0_1 -; LINUX: add r0, pc, r0 -; LINUX: ldr r0, [r1, r0] +; LINUX: ldr r0, [pc, r0] ; LINUX: ldr r0, [r0] -; LINUX: .long G(GOT) +; LINUX: .long G(GOT_PREL)-((.LPC0_0+8)-.Ltmp0) + +; LINUX_T: ldr r0, .LCPI0_0 +; LINUX_T: add r0, pc +; LINUX_T: ldr r0, [r0] +; LINUX_T: ldr r0, [r0] %tmp = load i32, i32* @G ret i32 %tmp }