- Use a different wrapper node for RIP-relative GV, etc.
- Proper support for both small static and PIC modes under X86-64
- Some (non-optimal) support for medium modes.

llvm-svn: 32046
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 1e3530f..375777a 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -3832,8 +3832,15 @@
   SDOperand Result = DAG.getTargetConstantPool(CP->getConstVal(),
                                                getPointerTy(),
                                                CP->getAlignment());
+  // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
+  TargetMachine &tm = getTargetMachine();
+  unsigned WrapperOpcode = (Subtarget->is64Bit() &&
+                            (tm.getCodeModel() == CodeModel::Small ||
+                             tm.getCodeModel() == CodeModel::Medium) &&
+                            tm.getRelocationModel() == Reloc::PIC_)
+    ? X86ISD::WrapperRIP : X86ISD::Wrapper;
+  Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
   if (Subtarget->isTargetDarwin()) {
-    Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
     // With PIC, the address is actually $g + Offset.
     if (!Subtarget->is64Bit() &&
         getTargetMachine().getRelocationModel() == Reloc::PIC_)
@@ -3848,8 +3855,15 @@
 X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
   GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
   SDOperand Result = DAG.getTargetGlobalAddress(GV, getPointerTy());
+  // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
+  TargetMachine &tm = getTargetMachine();
+  unsigned WrapperOpcode = (Subtarget->is64Bit() &&
+                            (tm.getCodeModel() == CodeModel::Small ||
+                             tm.getCodeModel() == CodeModel::Medium) &&
+                            tm.getRelocationModel() == Reloc::PIC_)
+    ? X86ISD::WrapperRIP : X86ISD::Wrapper;
+  Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
   if (Subtarget->isTargetDarwin()) {
-    Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
     // With PIC, the address is actually $g + Offset.
     if (!Subtarget->is64Bit() &&
         getTargetMachine().getRelocationModel() == Reloc::PIC_)
@@ -3865,7 +3879,6 @@
         Subtarget->GVRequiresExtraLoad(GV, false))
       Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
   } else if (Subtarget->GVRequiresExtraLoad(GV, false)) {
-    Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
     Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
   }
 
@@ -3876,8 +3889,15 @@
 X86TargetLowering::LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG) {
   const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
   SDOperand Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
+  // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
+  TargetMachine &tm = getTargetMachine();
+  unsigned WrapperOpcode = (Subtarget->is64Bit() &&
+                            (tm.getCodeModel() == CodeModel::Small ||
+                             tm.getCodeModel() == CodeModel::Medium) &&
+                            tm.getRelocationModel() == Reloc::PIC_)
+    ? X86ISD::WrapperRIP : X86ISD::Wrapper;
+  Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
   if (Subtarget->isTargetDarwin()) {
-    Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
     // With PIC, the address is actually $g + Offset.
     if (!Subtarget->is64Bit() &&
         getTargetMachine().getRelocationModel() == Reloc::PIC_)
@@ -4244,8 +4264,15 @@
 SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
   JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
   SDOperand Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
+  // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
+  TargetMachine &tm = getTargetMachine();
+  unsigned WrapperOpcode = (Subtarget->is64Bit() &&
+                            (tm.getCodeModel() == CodeModel::Small ||
+                             tm.getCodeModel() == CodeModel::Medium) &&
+                            tm.getRelocationModel() == Reloc::PIC_)
+    ? X86ISD::WrapperRIP : X86ISD::Wrapper;
+  Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
   if (Subtarget->isTargetDarwin()) {
-    Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
     // With PIC, the address is actually $g + Offset.
     if (!Subtarget->is64Bit() &&
         getTargetMachine().getRelocationModel() == Reloc::PIC_)
@@ -4978,6 +5005,7 @@
   case X86ISD::LOAD_UA:            return "X86ISD::LOAD_UA";
   case X86ISD::GlobalBaseReg:      return "X86ISD::GlobalBaseReg";
   case X86ISD::Wrapper:            return "X86ISD::Wrapper";
+  case X86ISD::WrapperRIP:         return "X86ISD::WrapperRIP";
   case X86ISD::S2VEC:              return "X86ISD::S2VEC";
   case X86ISD::PEXTRW:             return "X86ISD::PEXTRW";
   case X86ISD::PINSRW:             return "X86ISD::PINSRW";
@@ -5220,12 +5248,13 @@
 /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
 /// node is a GlobalAddress + an offset.
 static bool isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) {
-  if (N->getOpcode() == X86ISD::Wrapper) {
+  unsigned Opc = N->getOpcode();
+  if (Opc == X86ISD::Wrapper || Opc == X86ISD::WrapperRIP) {
     if (dyn_cast<GlobalAddressSDNode>(N->getOperand(0))) {
       GA = cast<GlobalAddressSDNode>(N->getOperand(0))->getGlobal();
       return true;
     }
-  } else if (N->getOpcode() == ISD::ADD) {
+  } else if (Opc == ISD::ADD) {
     SDOperand N1 = N->getOperand(0);
     SDOperand N2 = N->getOperand(1);
     if (isGAPlusOffset(N1.Val, GA, Offset)) {