Fix a constant lowering bug. Now we can do load and store instructions with funky getelementptr embedded in the address operand.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55975 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 4584bde..3f5d6f9 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -74,7 +74,8 @@
   bool X86FastEmitExtend(ISD::NodeType Opc, MVT DstVT, unsigned Src, MVT SrcVT,
                          unsigned &ResultReg);
   
-  bool X86SelectConstAddr(Value *V, unsigned &Op0, bool isCall = false);
+  bool X86SelectConstAddr(Value *V, unsigned &Op0,
+                          bool isCall = false, bool inReg = false);
 
   bool X86SelectLoad(Instruction *I);
   
@@ -285,7 +286,8 @@
 
 /// X86SelectConstAddr - Select and emit code to materialize constant address.
 /// 
-bool X86FastISel::X86SelectConstAddr(Value *V, unsigned &Op0, bool isCall) {
+bool X86FastISel::X86SelectConstAddr(Value *V, unsigned &Op0,
+                                     bool isCall, bool inReg) {
   // FIXME: Only GlobalAddress for now.
   GlobalValue *GV = dyn_cast<GlobalValue>(V);
   if (!GV)
@@ -308,7 +310,24 @@
     addFullAddress(BuildMI(MBB, TII.get(Opc), Op0), AM);
     // Prevent loading GV stub multiple times in same MBB.
     LocalValueMap[V] = Op0;
+  } else if (inReg) {
+    unsigned Opc = 0;
+    const TargetRegisterClass *RC = NULL;
+    if (TLI.getPointerTy() == MVT::i32) {
+      Opc = X86::LEA32r;
+      RC  = X86::GR32RegisterClass;
+    } else {
+      Opc = X86::LEA64r;
+      RC  = X86::GR64RegisterClass;
+    }
+    Op0 = createResultReg(RC);
+    X86AddressMode AM;
+    AM.GV = GV;
+    addFullAddress(BuildMI(MBB, TII.get(Opc), Op0), AM);
+    // Prevent materializing GV address multiple times in same MBB.
+    LocalValueMap[V] = Op0;
   }
+
   return true;
 }
 
@@ -323,12 +342,17 @@
     return false;    
 
   Value *V = I->getOperand(1);
-  unsigned Ptr = getRegForValue(V);
-  if (Ptr == 0) {
-    // Handle constant store address.
-    if (!isa<Constant>(V) || !X86SelectConstAddr(V, Ptr))
-      // Unhandled operand. Halt "fast" selection and bail.
-      return false;    
+  unsigned Ptr = lookUpRegForValue(V);
+  if (!Ptr) {
+    // Handle constant load address.
+    // FIXME: If load type is something we can't handle, this can result in
+    // a dead stub load instruction.
+    if (!isa<Constant>(V) || !X86SelectConstAddr(V, Ptr)) {
+      Ptr = getRegForValue(V);
+      if (Ptr == 0)
+        // Unhandled operand. Halt "fast" selection and bail.
+        return false;    
+    }
   }
 
   return X86FastEmitStore(VT, Val, Ptr, 0, V);
@@ -342,14 +366,17 @@
     return false;
 
   Value *V = I->getOperand(0);
-  unsigned Ptr = getRegForValue(V);
-  if (Ptr == 0) {
+  unsigned Ptr = lookUpRegForValue(V);
+  if (!Ptr) {
     // Handle constant load address.
     // FIXME: If load type is something we can't handle, this can result in
     // a dead stub load instruction.
-    if (!isa<Constant>(V) || !X86SelectConstAddr(V, Ptr))
-      // Unhandled operand. Halt "fast" selection and bail.
-      return false;    
+    if (!isa<Constant>(V) || !X86SelectConstAddr(V, Ptr)) {
+      Ptr = getRegForValue(V);
+      if (Ptr == 0)
+        // Unhandled operand. Halt "fast" selection and bail.
+        return false;    
+    }
   }
 
   unsigned ResultReg = 0;
@@ -917,18 +944,8 @@
   if (TM.getRelocationModel() == Reloc::PIC_)
     return 0;
   
-  MVT VT = MVT::getMVT(C->getType(), /*HandleUnknown=*/true);
-  if (VT == MVT::Other || !VT.isSimple())
-    // Unhandled type. Halt "fast" selection and bail.
-    return false;
-  if (VT == MVT::iPTR)
-    // Use pointer type.
-    VT = TLI.getPointerTy();
-  // We only handle legal types. For example, on x86-32 the instruction
-  // selector contains all of the 64-bit instructions from x86-64,
-  // under the assumption that i64 won't be used if the target doesn't
-  // support it.
-  if (!TLI.isTypeLegal(VT))
+  MVT VT;
+  if (!isTypeLegal(C->getType(), TLI, VT))
     return false;
   
   // Get opcode and regclass of the output for the given load instruction.
@@ -979,9 +996,7 @@
   
   unsigned ResultReg = createResultReg(RC);
   if (isa<GlobalValue>(C)) {
-    // FIXME: If store value type is something we can't handle, this can result
-    // in a dead stub load instruction.
-    if (X86SelectConstAddr(C, ResultReg))
+    if (X86SelectConstAddr(C, ResultReg, false, true))
       return ResultReg;
     return 0;
   }