diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 16 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb.td | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstructionSelector.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMSubtarget.cpp | 8 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMSubtarget.h | 9 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h | 5 |
9 files changed, 41 insertions, 40 deletions
diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp index be7afae5ea4..bf67bbdc379 100644 --- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -1311,6 +1311,7 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, unsigned DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); const MachineOperand &MO1 = MI.getOperand(1); + auto Flags = MO1.getTargetFlags(); const GlobalValue *GV = MO1.getGlobal(); bool IsARM = Opcode != ARM::tLDRLIT_ga_pcrel && Opcode != ARM::tLDRLIT_ga_abs; @@ -1329,7 +1330,9 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, if (IsPIC) { unsigned PCAdj = IsARM ? 8 : 4; - auto Modifier = STI->getCPModifier(GV); + auto Modifier = (Flags & ARMII::MO_GOT) + ? ARMCP::GOT_PREL + : ARMCP::no_modifier; ARMPCLabelIndex = AFI->createPICLabelUId(); CPV = ARMConstantPoolConstant::Create( GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj, Modifier, diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 135e20cf22f..44837898709 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -3164,28 +3164,12 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op, if (isPositionIndependent()) { bool UseGOT_PREL = !TM.shouldAssumeDSOLocal(*GV->getParent(), GV); - - MachineFunction &MF = DAG.getMachineFunction(); - ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); - 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( - PtrVT, dl, DAG.getEntryNode(), CPAddr, - MachinePointerInfo::getConstantPool(DAG.getMachineFunction())); - SDValue Chain = Result.getValue(1); - SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32); - Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); + SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, + UseGOT_PREL ? ARMII::MO_GOT : 0); + SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G); if (UseGOT_PREL) Result = - DAG.getLoad(PtrVT, dl, Chain, Result, + DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result, MachinePointerInfo::getGOT(DAG.getMachineFunction())); return Result; } else if (Subtarget->isROPI() && IsRO) { diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index c031f6ff7ac..d8cd076c17a 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -332,6 +332,8 @@ def UseNegativeImmediates : let RecomputePerFunction = 1 in { def UseMovt : Predicate<"Subtarget->useMovt(*MF)">; def DontUseMovt : Predicate<"!Subtarget->useMovt(*MF)">; + def UseMovtInPic : Predicate<"Subtarget->useMovt(*MF) && Subtarget->allowPositionIndependentMovt()">; + def DontUseMovtInPic : Predicate<"!Subtarget->useMovt(*MF) || !Subtarget->allowPositionIndependentMovt()">; } def UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">; def UseMulOps : Predicate<"Subtarget->useMulOps()">; @@ -5644,26 +5646,26 @@ let isReMaterializable = 1 in { def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), IIC_iMOVix2addpc, [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, - Requires<[IsARM, UseMovt]>; + Requires<[IsARM, UseMovtInPic]>; def LDRLIT_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadiALU, [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, - Requires<[IsARM, DontUseMovt]>; + Requires<[IsARM, DontUseMovtInPic]>; let AddedComplexity = 10 in def LDRLIT_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), NoItinerary, [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>, - Requires<[IsARM, DontUseMovt]>; + Requires<[IsARM, DontUseMovtInPic]>; let AddedComplexity = 10 in def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), IIC_iMOVix2ld, [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>, - Requires<[IsARM, UseMovt]>; + Requires<[IsARM, UseMovtInPic]>; } // isReMaterializable // The many different faces of TLS access. @@ -5676,15 +5678,15 @@ def : Pat<(ARMWrapper tglobaltlsaddr:$src), Requires<[IsARM, DontUseMovt]>; def : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr), - (MOV_ga_pcrel tglobaltlsaddr:$addr)>, Requires<[IsARM, UseMovt]>; + (MOV_ga_pcrel tglobaltlsaddr:$addr)>, Requires<[IsARM, UseMovtInPic]>; def : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr), (LDRLIT_ga_pcrel tglobaltlsaddr:$addr)>, - Requires<[IsARM, DontUseMovt]>; + Requires<[IsARM, DontUseMovtInPic]>; let AddedComplexity = 10 in def : Pat<(load (ARMWrapperPIC tglobaltlsaddr:$addr)), (MOV_ga_pcrel_ldr tglobaltlsaddr:$addr)>, - Requires<[IsARM, UseMovt]>; + Requires<[IsARM, UseMovtInPic]>; // ConstantPool, GlobalAddress, and JumpTable diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index d6b9a21c2b8..c2bcc087e07 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -1509,7 +1509,7 @@ def tLDRLIT_ga_pcrel : PseudoInst<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadiALU, [(set tGPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, - Requires<[IsThumb, DontUseMovt]>; + Requires<[IsThumb, DontUseMovtInPic]>; def tLDRLIT_ga_abs : PseudoInst<(outs tGPR:$dst), (ins i32imm:$src), IIC_iLoad_i, @@ -1520,7 +1520,7 @@ def tLDRLIT_ga_abs : PseudoInst<(outs tGPR:$dst), (ins i32imm:$src), // TLS globals def : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr), (tLDRLIT_ga_pcrel tglobaltlsaddr:$addr)>, - Requires<[IsThumb, DontUseMovt]>; + Requires<[IsThumb, DontUseMovtInPic]>; def : Pat<(ARMWrapper tglobaltlsaddr:$addr), (tLDRLIT_ga_abs tglobaltlsaddr:$addr)>, Requires<[IsThumb, DontUseMovt]>; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index f61cdc563d7..670ed127da7 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -3843,13 +3843,13 @@ let isReMaterializable = 1 in { def t2MOV_ga_pcrel : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr), IIC_iMOVix2addpc, [(set rGPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, - Requires<[IsThumb, HasV8MBaseline, UseMovt]>; + Requires<[IsThumb, HasV8MBaseline, UseMovtInPic]>; } def : T2Pat<(ARMWrapperPIC tglobaltlsaddr :$dst), (t2MOV_ga_pcrel tglobaltlsaddr:$dst)>, - Requires<[IsThumb2, UseMovt]>; + Requires<[IsThumb2, UseMovtInPic]>; def : T2Pat<(ARMWrapper tglobaltlsaddr:$dst), (t2MOVi32imm tglobaltlsaddr:$dst)>, Requires<[IsThumb2, UseMovt]>; diff --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp index fc61fd85670..aee3d850c02 100644 --- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp +++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp @@ -538,8 +538,12 @@ bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB, : (Indirect ? ARM::LDRLIT_ga_pcrel_ldr : ARM::LDRLIT_ga_pcrel); MIB->setDesc(TII.get(Opc)); + int TargetFlags = ARMII::MO_NO_FLAG; if (STI.isTargetDarwin()) - MIB->getOperand(1).setTargetFlags(ARMII::MO_NONLAZY); + TargetFlags |= ARMII::MO_NONLAZY; + if (STI.isGVInGOT(GV)) + TargetFlags |= ARMII::MO_GOT; + MIB->getOperand(1).setTargetFlags(TargetFlags); if (Indirect) MIB.addMemOperand(MF.getMachineMemOperand( diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp index a8546ec40a6..7e107e4f8fd 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.cpp +++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp @@ -344,11 +344,9 @@ bool ARMSubtarget::isGVIndirectSymbol(const GlobalValue *GV) const { return false; } -ARMCP::ARMCPModifier ARMSubtarget::getCPModifier(const GlobalValue *GV) const { - if (isTargetELF() && TM.isPositionIndependent() && - !TM.shouldAssumeDSOLocal(*GV->getParent(), GV)) - return ARMCP::GOT_PREL; - return ARMCP::no_modifier; +bool ARMSubtarget::isGVInGOT(const GlobalValue *GV) const { + return isTargetELF() && TM.isPositionIndependent() && + !TM.shouldAssumeDSOLocal(*GV->getParent(), GV); } unsigned ARMSubtarget::getMispredictionPenalty() const { diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h index c57c4e7dcd3..4b4a44f2fe2 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/llvm/lib/Target/ARM/ARMSubtarget.h @@ -752,7 +752,7 @@ public: bool isGVIndirectSymbol(const GlobalValue *GV) const; /// Returns the constant pool modifier needed to access the GV. - ARMCP::ARMCPModifier getCPModifier(const GlobalValue *GV) const; + bool isGVInGOT(const GlobalValue *GV) const; /// True if fast-isel is used. bool useFastISel() const; @@ -767,6 +767,13 @@ public: return ARM::BX_RET; return ARM::MOVPCLR; } + + /// Allow movt+movw for PIC global address calculation. + /// ELF does not have GOT relocations for movt+movw. + /// ROPI does not use GOT. + bool allowPositionIndependentMovt() const { + return isROPI() || !isTargetELF(); + } }; } // end namespace llvm diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h index 17da82b4ca3..c4480e3da50 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h @@ -228,7 +228,10 @@ namespace ARMII { /// MO_OPTION_MASK - Most flags are mutually exclusive; this mask selects /// just that part of the flag set. - MO_OPTION_MASK = 0x0f, + MO_OPTION_MASK = 0x3, + + /// MO_GOT - On a symbol operand, this represents a GOT relative relocation. + MO_GOT = 0x8, /// MO_SBREL - On a symbol operand, this represents a static base relative /// relocation. Used in movw and movt instructions. |

