Factor out the code for determining when symblic addresses
authorDan Gohman <gohman@apple.com>
Fri, 26 Sep 2008 19:15:30 +0000 (19:15 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 26 Sep 2008 19:15:30 +0000 (19:15 +0000)
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
lib/Target/X86/X86ISelDAGToDAG.cpp
lib/Target/X86/X86TargetMachine.cpp
lib/Target/X86/X86TargetMachine.h

index 0a3f5204868875b77c3416189e5f9db8fb5d3d4a..159d3197f34d53449ebf27b58b53f30b934c9f14 100644 (file)
@@ -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.
index f72392df836179353adc3b3bbebe8a23863e71f3..9fe19ab67d387823614fdcde369f0dbe0c361adf 100644 (file)
@@ -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;
       }
     }
index 08753e70e8c9bc07fee23b6c2ba48a629ed30b71..860868adf16a005ea03a4d4fdbf9e4b0b429a96d 100644 (file)
@@ -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();
+}
index 13b391dcfff64ae5aa4309df6da544cf3ef3d2cd..eaf81df5abcc95a5643a3329632ba75cf0678db7 100644 (file)
@@ -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.