From 97135e1ee51357245561a5108f90a8a1161431a1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 26 Sep 2008 19:15:30 +0000 Subject: [PATCH] Factor out the code for determining when symblic addresses require RIP-relative addressing and use it to fix a bug in X86FastISel in x86-64 PIC mode, where it was trying to use base/index registers with RIP-relative addresses. This fixes a bunch of x86-64 testsuite failures. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56676 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86FastISel.cpp | 40 ++++++++++++++++++++++++++++--------- lib/Target/X86/X86ISelDAGToDAG.cpp | 12 ++++------- lib/Target/X86/X86TargetMachine.cpp | 9 +++++++++ lib/Target/X86/X86TargetMachine.h | 6 ++++++ 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 0a3f5204868..159d3197f34 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -106,7 +106,10 @@ private: unsigned getGlobalBaseReg(); const X86InstrInfo *getInstrInfo() const { - return static_cast(TM.getInstrInfo()); + return getTargetMachine()->getInstrInfo(); + } + const X86TargetMachine *getTargetMachine() const { + return static_cast(&TM); } unsigned TargetMaterializeConstant(Constant *C); @@ -330,11 +333,12 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) { // Do static allocas. const AllocaInst *A = cast(V); DenseMap::iterator SI = StaticAllocaMap.find(A); - if (SI == StaticAllocaMap.end()) - return false; - AM.BaseType = X86AddressMode::FrameIndexBase; - AM.Base.FrameIndex = SI->second; - return true; + if (SI != StaticAllocaMap.end()) { + AM.BaseType = X86AddressMode::FrameIndexBase; + AM.Base.FrameIndex = SI->second; + return true; + } + break; } case Instruction::Add: { @@ -369,6 +373,8 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) { // Constant-offset addressing. Disp += CI->getZExtValue() * S; } else if (IndexReg == 0 && + (!AM.GV || + !getTargetMachine()->symbolicAddressesAreRIPRel()) && (S == 1 || S == 2 || S == 4 || S == 8)) { // Scaled-index addressing. Scale = S; @@ -399,6 +405,11 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) { TM.getCodeModel() != CodeModel::Small) return false; + // RIP-relative addresses can't have additional register operands. + if (getTargetMachine()->symbolicAddressesAreRIPRel() && + (AM.Base.Reg != 0 || AM.IndexReg != 0)) + return false; + // Set up the basic address. AM.GV = GV; if (!isCall && @@ -443,9 +454,20 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) { return true; } - // If all else fails, just materialize the value in a register. - AM.Base.Reg = getRegForValue(V); - return AM.Base.Reg != 0; + // If all else fails, try to materialize the value in a register. + if (!AM.GV && getTargetMachine()->symbolicAddressesAreRIPRel()) { + if (AM.Base.Reg == 0) { + AM.Base.Reg = getRegForValue(V); + return AM.Base.Reg != 0; + } + if (AM.IndexReg == 0) { + assert(AM.Scale == 1 && "Scale with no index!"); + AM.IndexReg = getRegForValue(V); + return AM.IndexReg != 0; + } + } + + return false; } /// X86SelectStore - Select and emit code to implement store instructions. diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index f72392df836..9fe19ab67d3 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -819,25 +819,21 @@ DOUT << "AlreadySelected " << AlreadySelected << "\n"; GlobalValue *GV = G->getGlobal(); AM.GV = GV; AM.Disp += G->getOffset(); - AM.isRIPRel = TM.getRelocationModel() != Reloc::Static && - Subtarget->isPICStyleRIPRel(); + AM.isRIPRel = TM.symbolicAddressesAreRIPRel(); return false; } else if (ConstantPoolSDNode *CP = dyn_cast(N0)) { AM.CP = CP->getConstVal(); AM.Align = CP->getAlignment(); AM.Disp += CP->getOffset(); - AM.isRIPRel = TM.getRelocationModel() != Reloc::Static && - Subtarget->isPICStyleRIPRel(); + AM.isRIPRel = TM.symbolicAddressesAreRIPRel(); return false; } else if (ExternalSymbolSDNode *S =dyn_cast(N0)) { AM.ES = S->getSymbol(); - AM.isRIPRel = TM.getRelocationModel() != Reloc::Static && - Subtarget->isPICStyleRIPRel(); + AM.isRIPRel = TM.symbolicAddressesAreRIPRel(); return false; } else if (JumpTableSDNode *J = dyn_cast(N0)) { AM.JT = J->getIndex(); - AM.isRIPRel = TM.getRelocationModel() != Reloc::Static && - Subtarget->isPICStyleRIPRel(); + AM.isRIPRel = TM.symbolicAddressesAreRIPRel(); return false; } } diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp index 08753e70e8c..860868adf16 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/lib/Target/X86/X86TargetMachine.cpp @@ -236,3 +236,12 @@ bool X86TargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, bool Fast, return false; } + +// symbolicAddressesAreRIPRel - Return true if symbolic addresses are +// RIP-relative on this machine, taking into consideration the relocation +// model and subtarget. RIP-relative addresses cannot have a separate +// base or index register. +bool X86TargetMachine::symbolicAddressesAreRIPRel() const { + return getRelocationModel() != Reloc::Static && + Subtarget.isPICStyleRIPRel(); +} diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h index 13b391dcfff..eaf81df5abc 100644 --- a/lib/Target/X86/X86TargetMachine.h +++ b/lib/Target/X86/X86TargetMachine.h @@ -82,6 +82,12 @@ public: bool DumpAsm, MachineCodeEmitter &MCE); virtual bool addSimpleCodeEmitter(PassManagerBase &PM, bool Fast, bool DumpAsm, MachineCodeEmitter &MCE); + + // symbolicAddressesAreRIPRel - Return true if symbolic addresses are + // RIP-relative on this machine, taking into consideration the relocation + // model and subtarget. RIP-relative addresses cannot have a separate + // base or index register. + bool symbolicAddressesAreRIPRel() const; }; /// X86_32TargetMachine - X86 32-bit target machine. -- 2.11.0