allow the address of a global to be used with the "i" constraint when in
-static mode.  This implements PR882.

llvm-svn: 31326
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 83bf280..92bec91 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -5466,6 +5466,36 @@
   }
 }
 
+/// isOperandValidForConstraint - Return the specified operand (possibly
+/// modified) if the specified SDOperand is valid for the specified target
+/// constraint letter, otherwise return null.
+SDOperand X86TargetLowering::
+isOperandValidForConstraint(SDOperand Op, char Constraint, SelectionDAG &DAG) {
+  switch (Constraint) {
+  default: break;
+  case 'i':
+    // Literal immediates are always ok.
+    if (isa<ConstantSDNode>(Op)) return Op;
+    
+    // If we are in non-pic codegen mode, we allow the address of a global to
+    // be used with 'i'.
+    if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) {
+      if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
+        return SDOperand(0, 0);
+      
+      if (GA->getOpcode() != ISD::TargetGlobalAddress)
+        Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0),
+                                        GA->getOffset());
+      return Op;
+    }
+    
+    // Otherwise, not valid for this mode.
+    return SDOperand(0, 0);
+  }
+  return TargetLowering::isOperandValidForConstraint(Op, Constraint, DAG);
+}
+
+
 std::vector<unsigned> X86TargetLowering::
 getRegClassForInlineAsmConstraint(const std::string &Constraint,
                                   MVT::ValueType VT) const {
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 6de2964..dde123c 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -300,7 +300,12 @@
     std::vector<unsigned> 
       getRegClassForInlineAsmConstraint(const std::string &Constraint,
                                         MVT::ValueType VT) const;
-
+    /// isOperandValidForConstraint - Return the specified operand (possibly
+    /// modified) if the specified SDOperand is valid for the specified target
+    /// constraint letter, otherwise return null.
+    SDOperand isOperandValidForConstraint(SDOperand Op, char ConstraintLetter,
+                                          SelectionDAG &DAG);
+    
     /// getRegForInlineAsmConstraint - Given a physical register constraint
     /// (e.g. {edx}), return the register number and the register class for the
     /// register.  This should only be used for C_Register constraints.  On