[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp

Chris Lattner sabre at nondot.org
Thu May 3 09:52:47 PDT 2007



Changes in directory llvm/lib/Target/X86:

X86ISelLowering.cpp updated: 1.398 -> 1.399
---
Log message:

Fix two classes of bugs:
  1. x86 backend rejected (&gv+c) for the 'i' constraint when in static mode.
  2. the matcher didn't correctly reject and accept some global addresses.
     the right predicate is GVRequiresExtraLoad, not "relomodel = pic".


---
Diffs of the changes:  (+32 -8)

 X86ISelLowering.cpp |   40 ++++++++++++++++++++++++++++++++--------
 1 files changed, 32 insertions(+), 8 deletions(-)


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.398 llvm/lib/Target/X86/X86ISelLowering.cpp:1.399
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.398	Wed May  2 14:53:33 2007
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Thu May  3 11:52:29 2007
@@ -4734,25 +4734,49 @@
         return Op;
     }
     return SDOperand(0,0);
-  case 'i':
+  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_)
+    // If we are in non-pic codegen mode, we allow the address of a global (with
+    // an optional displacement) to be used with 'i'.
+    GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op);
+    int64_t Offset = 0;
+    
+    // Match either (GA) or (GA+C)
+    if (GA) {
+      Offset = GA->getOffset();
+    } else if (Op.getOpcode() == ISD::ADD) {
+      ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
+      GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(0));
+      if (C && GA) {
+        Offset = GA->getOffset()+C->getValue();
+      } else {
+        C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
+        GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(0));
+        if (C && GA)
+          Offset = GA->getOffset()+C->getValue();
+        else
+          C = 0, GA = 0;
+      }
+    }
+    
+    if (GA) {
+      // If addressing this global requires a load (e.g. in PIC mode), we can't
+      // match.
+      if (Subtarget->GVRequiresExtraLoad(GA->getGlobal(), getTargetMachine(),
+                                         false))
         return SDOperand(0, 0);
 
-      if (GA->getOpcode() != ISD::TargetGlobalAddress)
-        Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0),
-                                        GA->getOffset());
+      Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0),
+                                      Offset);
       return Op;
     }
 
     // Otherwise, not valid for this mode.
     return SDOperand(0, 0);
   }
+  }
   return TargetLowering::isOperandValidForConstraint(Op, Constraint, DAG);
 }
 






More information about the llvm-commits mailing list