aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-09-26 19:15:30 +0000
committerDan Gohman <gohman@apple.com>2008-09-26 19:15:30 +0000
commitc641336847d19f597db7c9ddfdce1bbebc6c4ef9 (patch)
treed9ebe8f9c8e3ac1ba267494a9fa12112ede80240
parentc275cf6b71d5a6ab0126fe2e1ac3b7052364e5de (diff)
downloadexternal_llvm-c641336847d19f597db7c9ddfdce1bbebc6c4ef9.zip
external_llvm-c641336847d19f597db7c9ddfdce1bbebc6c4ef9.tar.gz
external_llvm-c641336847d19f597db7c9ddfdce1bbebc6c4ef9.tar.bz2
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
-rw-r--r--lib/Target/X86/X86FastISel.cpp40
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp12
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp9
-rw-r--r--lib/Target/X86/X86TargetMachine.h6
4 files changed, 50 insertions, 17 deletions
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 0a3f520..159d319 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<const X86InstrInfo *>(TM.getInstrInfo());
+ return getTargetMachine()->getInstrInfo();
+ }
+ const X86TargetMachine *getTargetMachine() const {
+ return static_cast<const X86TargetMachine *>(&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<AllocaInst>(V);
DenseMap<const AllocaInst*, int>::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 f72392d..9fe19ab 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<ConstantPoolSDNode>(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<ExternalSymbolSDNode>(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<JumpTableSDNode>(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 08753e7..860868a 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 13b391d..eaf81df 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.