Port some integer multiplication fixes from LegalizeDAG.
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeIntegerTypes.cpp
index 90b800e14f78dded1572a2d2c662df784879786b..d8dd4ed49e1be60c3de9a6e70d788090486874ff 100644 (file)
@@ -192,7 +192,7 @@ SDOperand DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {
 }
 
 SDOperand DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
-  // FIXME: Add support for indexed loads.
+  assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
   ISD::LoadExtType ExtType =
     ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
@@ -636,7 +636,7 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
 }
 
 SDOperand DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
-  // FIXME: Add support for indexed stores.
+  assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
   SDOperand Ch = N->getChain(), Ptr = N->getBasePtr();
   int SVOffset = N->getSrcValueOffset();
   unsigned Alignment = N->getAlignment();
@@ -763,6 +763,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
 
   case ISD::BIT_CONVERT:        ExpandRes_BIT_CONVERT(N, Lo, Hi); break;
   case ISD::BUILD_PAIR:         ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
+  case ISD::EXTRACT_ELEMENT:    ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break;
   case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
 
   case ISD::Constant:    ExpandIntRes_Constant(N, Lo, Hi); break;
@@ -1000,8 +1001,8 @@ void DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDOperand &Lo,
 
 void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
                                          SDOperand &Lo, SDOperand &Hi) {
-  if (ISD::isNON_EXTLoad(N)) {
-    ExpandRes_NON_EXTLOAD(N, Lo, Hi);
+  if (ISD::isNormalLoad(N)) {
+    ExpandRes_NormalLoad(N, Lo, Hi);
     return;
   }
 
@@ -1202,14 +1203,13 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
     GetExpandedInteger(N->getOperand(0), LL, LH);
     GetExpandedInteger(N->getOperand(1), RL, RH);
     unsigned OuterBitSize = VT.getSizeInBits();
-    unsigned BitSize = NVT.getSizeInBits();
+    unsigned InnerBitSize = NVT.getSizeInBits();
     unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
     unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
 
-    if (DAG.MaskedValueIsZero(N->getOperand(0),
-                              APInt::getHighBitsSet(OuterBitSize, LHSSB)) &&
-        DAG.MaskedValueIsZero(N->getOperand(1),
-                              APInt::getHighBitsSet(OuterBitSize, RHSSB))) {
+    APInt HighMask = APInt::getHighBitsSet(OuterBitSize, InnerBitSize);
+    if (DAG.MaskedValueIsZero(N->getOperand(0), HighMask) &&
+        DAG.MaskedValueIsZero(N->getOperand(1), HighMask)) {
       // The inputs are both zero-extended.
       if (HasUMUL_LOHI) {
         // We can emit a umul_lohi.
@@ -1224,7 +1224,7 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
         return;
       }
     }
-    if (LHSSB > BitSize && RHSSB > BitSize) {
+    if (LHSSB > InnerBitSize && RHSSB > InnerBitSize) {
       // The input values are both sign-extended.
       if (HasSMUL_LOHI) {
         // We can emit a smul_lohi.
@@ -1251,12 +1251,29 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
       Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
       return;
     }
+    if (HasMULHU) {
+      Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
+      Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
+      RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
+      LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
+      Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
+      Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
+      return;
+    }
   }
 
   // If nothing else, we can make a libcall.
+  RTLIB::Libcall LC;
+  switch (VT.getSimpleVT()) {
+  default:
+    assert(false && "Unsupported MUL!");
+  case MVT::i64:
+    LC = RTLIB::MUL_I64;
+    break;
+  }
+
   SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
-  SplitInteger(MakeLibCall(RTLIB::MUL_I64, VT, Ops, 2, true/*sign irrelevant*/),
-               Lo, Hi);
+  SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*sign irrelevant*/), Lo, Hi);
 }
 
 void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
@@ -1860,8 +1877,8 @@ void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
 }
 
 SDOperand DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
-  if (ISD::isNON_TRUNCStore(N))
-    return ExpandOp_NON_TRUNCStore(N, OpNo);
+  if (ISD::isNormalStore(N))
+    return ExpandOp_NormalStore(N, OpNo);
 
   assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
   assert(OpNo == 1 && "Can only expand the stored value so far");
@@ -1875,7 +1892,7 @@ SDOperand DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
   bool isVolatile = N->isVolatile();
   SDOperand Lo, Hi;
 
-  assert(!(NVT.getSizeInBits() & 7) && "Expanded type not byte sized!");
+  assert(NVT.isByteSized() && "Expanded type not byte sized!");
 
   if (N->getMemoryVT().bitsLE(NVT)) {
     GetExpandedInteger(N->getValue(), Lo, Hi);