Set up the shift and setcc types.
If we emit a load because we followed a token chain to get to it, try to
fold it into its single user if possible.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19620 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp
index ba359de..005433b 100644
--- a/lib/Target/X86/X86ISelPattern.cpp
+++ b/lib/Target/X86/X86ISelPattern.cpp
@@ -39,6 +39,12 @@
   public:
     X86TargetLowering(TargetMachine &TM) : TargetLowering(TM) {
       // Set up the TargetLowering object.
+
+      // X86 is wierd, it always uses i8 for shift amounts and setcc results.
+      setShiftAmountType(MVT::i8);
+      setSetCCResultType(MVT::i8);
+
+      // Set up the register classes.
       addRegisterClass(MVT::i8, X86::R8RegisterClass);
       addRegisterClass(MVT::i16, X86::R16RegisterClass);
       addRegisterClass(MVT::i32, X86::R32RegisterClass);
@@ -2303,10 +2309,35 @@
     return;
   }
 
+  case ISD::LOAD:
+    // If this load could be folded into the only using instruction, and if it
+    // is safe to emit the instruction here, try to do so now.
+    if (Node->hasNUsesOfValue(1, 0)) {
+      SDOperand TheVal = N.getValue(0);
+      SDNode *User = 0;
+      for (SDNode::use_iterator UI = Node->use_begin(); ; ++UI) {
+        assert(UI != Node->use_end() && "Didn't find use!");
+        SDNode *UN = *UI;
+        for (unsigned i = 0, e = UN->getNumOperands(); i != e; ++i)
+          if (UN->getOperand(i) == TheVal) {
+            User = UN;
+            goto FoundIt;
+          }
+      }
+    FoundIt:
+      // Only handle unary operators right now.
+      if (User->getNumOperands() == 1) {
+        LoweredTokens.erase(N);
+        SelectExpr(SDOperand(User, 0));
+        return;
+      }
+    }
+    SelectExpr(N);
+    return;
+
   case ISD::EXTLOAD:
   case ISD::SEXTLOAD:
   case ISD::ZEXTLOAD:
-  case ISD::LOAD:
   case ISD::CALL:
   case ISD::DYNAMIC_STACKALLOC:
     SelectExpr(N);