Remove custom expansion from LegalizeTypes when doing
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeFloatTypes.cpp
index b2580f5fa70e8e59ac1892b83de0f339efd64d8e..520924d14e7839d186cd7bbe5a24f6a7b281b21d 100644 (file)
@@ -48,28 +48,13 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
         cerr << "\n");
   SDOperand R = SDOperand();
 
-  // FIXME: Custom lowering for float-to-int?
-#if 0
-  // See if the target wants to custom convert this node to an integer.
-  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
-      TargetLowering::Custom) {
-    // If the target wants to, allow it to lower this itself.
-    if (SDNode *P = TLI.FloatToIntOperationResult(N, DAG)) {
-      // Everything that once used N now uses P.  We are guaranteed that the
-      // result value types of N and the result value types of P match.
-      ReplaceNodeWith(N, P);
-      return;
-    }
-  }
-#endif
-
   switch (N->getOpcode()) {
   default:
 #ifndef NDEBUG
     cerr << "SoftenFloatResult #" << ResNo << ": ";
     N->dump(&DAG); cerr << "\n";
 #endif
-    assert(0 && "Do not know how to convert the result of this operator!");
+    assert(0 && "Do not know how to soften the result of this operator!");
     abort();
 
     case ISD::BIT_CONVERT: R = SoftenFloatRes_BIT_CONVERT(N); break;
@@ -78,7 +63,11 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
       R = SoftenFloatRes_ConstantFP(cast<ConstantFPSDNode>(N));
       break;
     case ISD::FCOPYSIGN:   R = SoftenFloatRes_FCOPYSIGN(N); break;
+    case ISD::FP_EXTEND:   R = SoftenFloatRes_FP_EXTEND(N); break;
+    case ISD::FP_ROUND:    R = SoftenFloatRes_FP_ROUND(N); break;
     case ISD::LOAD:        R = SoftenFloatRes_LOAD(N); break;
+    case ISD::SELECT:      R = SoftenFloatRes_SELECT(N); break;
+    case ISD::SELECT_CC:   R = SoftenFloatRes_SELECT_CC(N); break;
     case ISD::SINT_TO_FP:
     case ISD::UINT_TO_FP:  R = SoftenFloatRes_XINT_TO_FP(N); break;
 
@@ -172,6 +161,46 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) {
                      NVT, Ops, 2, false);
 }
 
+SDOperand DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  SDOperand Op = N->getOperand(0);
+
+  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
+  switch (Op.getValueType().getSimpleVT()) {
+  default:
+    assert(false && "Unsupported FP_EXTEND!");
+  case MVT::f32:
+    switch (N->getValueType(0).getSimpleVT()) {
+    default:
+      assert(false && "Unsupported FP_EXTEND!");
+    case MVT::f64:
+      LC = RTLIB::FPEXT_F32_F64;
+    }
+  }
+
+  return MakeLibCall(LC, NVT, &Op, 1, false);
+}
+
+SDOperand DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  SDOperand Op = N->getOperand(0);
+
+  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
+  switch (Op.getValueType().getSimpleVT()) {
+  default:
+    assert(false && "Unsupported FP_ROUND!");
+  case MVT::f64:
+    switch (N->getValueType(0).getSimpleVT()) {
+    default:
+      assert(false && "Unsupported FP_ROUND!");
+    case MVT::f32:
+      LC = RTLIB::FPROUND_F64_F32;
+    }
+  }
+
+  return MakeLibCall(LC, NVT, &Op, 1, false);
+}
+
 SDOperand DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) {
   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
   SDOperand Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
@@ -205,6 +234,19 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
   return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, VT, NL));
 }
 
+SDOperand DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) {
+  SDOperand LHS = GetSoftenedFloat(N->getOperand(1));
+  SDOperand RHS = GetSoftenedFloat(N->getOperand(2));
+  return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS);
+}
+
+SDOperand DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) {
+  SDOperand LHS = GetSoftenedFloat(N->getOperand(2));
+  SDOperand RHS = GetSoftenedFloat(N->getOperand(3));
+  return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0),
+                     N->getOperand(1), LHS, RHS, N->getOperand(4));
+}
+
 SDOperand DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) {
   bool isSigned = N->getOpcode() == ISD::SINT_TO_FP;
   MVT DestVT = N->getValueType(0);
@@ -313,31 +355,23 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) {
 bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
   DEBUG(cerr << "Soften float operand " << OpNo << ": "; N->dump(&DAG);
         cerr << "\n");
-  SDOperand Res(0, 0);
+  SDOperand Res = SDOperand();
 
-  // FIXME: Custom lowering for float-to-int?
-#if 0
-  if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
-      == TargetLowering::Custom)
-    Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
-#endif
-
-  if (Res.Val == 0) {
-    switch (N->getOpcode()) {
-    default:
+  switch (N->getOpcode()) {
+  default:
 #ifndef NDEBUG
-      cerr << "SoftenFloatOperand Op #" << OpNo << ": ";
-      N->dump(&DAG); cerr << "\n";
+    cerr << "SoftenFloatOperand Op #" << OpNo << ": ";
+    N->dump(&DAG); cerr << "\n";
 #endif
-      assert(0 && "Do not know how to convert this operator's operand!");
-      abort();
+    assert(0 && "Do not know how to soften this operator's operand!");
+    abort();
 
-    case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break;
+  case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break;
 
-    case ISD::BR_CC:     Res = SoftenFloatOp_BR_CC(N); break;
-    case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break;
-    case ISD::SETCC:     Res = SoftenFloatOp_SETCC(N); break;
-    }
+  case ISD::BR_CC:     Res = SoftenFloatOp_BR_CC(N); break;
+  case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break;
+  case ISD::SETCC:     Res = SoftenFloatOp_SETCC(N); break;
+  case ISD::STORE:     Res = SoftenFloatOp_STORE(N, OpNo); break;
   }
 
   // If the result is null, the sub-method took care of registering results etc.
@@ -366,8 +400,7 @@ void DAGTypeLegalizer::SoftenSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
                                            ISD::CondCode &CCCode) {
   SDOperand LHSInt = GetSoftenedFloat(NewLHS);
   SDOperand RHSInt = GetSoftenedFloat(NewRHS);
-  MVT VT  = NewLHS.getValueType();
-  MVT NVT = LHSInt.getValueType();
+  MVT VT = NewLHS.getValueType();
 
   assert((VT == MVT::f32 || VT == MVT::f64) && "Unsupported setcc type!");
 
@@ -402,6 +435,7 @@ void DAGTypeLegalizer::SoftenSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
     LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
     break;
   case ISD::SETO:
+    LC1 = (VT == MVT::f32) ? RTLIB::O_F32 : RTLIB::O_F64;
     break;
   default:
     LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
@@ -430,13 +464,13 @@ void DAGTypeLegalizer::SoftenSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
   }
 
   SDOperand Ops[2] = { LHSInt, RHSInt };
-  NewLHS = MakeLibCall(LC1, NVT, Ops, 2, false/*sign irrelevant*/);
-  NewRHS = DAG.getConstant(0, NVT);
+  NewLHS = MakeLibCall(LC1, MVT::i32, Ops, 2, false/*sign irrelevant*/);
+  NewRHS = DAG.getConstant(0, MVT::i32);
+  CCCode = TLI.getCmpLibcallCC(LC1);
   if (LC2 != RTLIB::UNKNOWN_LIBCALL) {
     SDOperand Tmp = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(NewLHS),
-                                NewLHS, NewRHS,
-                                DAG.getCondCode(TLI.getCmpLibcallCC(LC1)));
-    NewLHS = MakeLibCall(LC2, NVT, Ops, 2, false/*sign irrelevant*/);
+                                NewLHS, NewRHS, DAG.getCondCode(CCCode));
+    NewLHS = MakeLibCall(LC2, MVT::i32, Ops, 2, false/*sign irrelevant*/);
     NewLHS = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(NewLHS), NewLHS,
                          NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2)));
     NewLHS = DAG.getNode(ISD::OR, Tmp.getValueType(), Tmp, NewLHS);
@@ -502,6 +536,24 @@ SDOperand DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) {
                                 DAG.getCondCode(CCCode));
 }
 
+SDOperand DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) {
+  assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
+  assert(OpNo == 1 && "Can only soften the stored value!");
+  StoreSDNode *ST = cast<StoreSDNode>(N);
+  SDOperand Val = ST->getValue();
+
+  if (ST->isTruncatingStore())
+    // Do an FP_ROUND followed by a non-truncating store.
+    Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, ST->getMemoryVT(),
+                                          Val, DAG.getIntPtrConstant(0)));
+  else
+    Val = GetSoftenedFloat(Val);
+
+  return DAG.getStore(ST->getChain(), Val, ST->getBasePtr(),
+                      ST->getSrcValue(), ST->getSrcValueOffset(),
+                      ST->isVolatile(), ST->getAlignment());
+}
+
 
 //===----------------------------------------------------------------------===//
 //  Float Result Expansion
@@ -517,10 +569,10 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
   Lo = Hi = SDOperand();
 
   // See if the target wants to custom expand this node.
-  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
-          TargetLowering::Custom) {
+  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) ==
+      TargetLowering::Custom) {
     // If the target wants to, allow it to lower this itself.
-    if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
+    if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) {
       // Everything that once used N now uses P.  We are guaranteed that the
       // result value types of N and the result value types of P match.
       ReplaceNodeWith(N, P);
@@ -738,11 +790,11 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDOperand &Lo,
 /// need promotion or expansion as well as the specified one.
 bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
   DEBUG(cerr << "Expand float operand: "; N->dump(&DAG); cerr << "\n");
-  SDOperand Res(0, 0);
+  SDOperand Res = SDOperand();
 
   if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
       == TargetLowering::Custom)
-    Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
+    Res = TLI.LowerOperation(SDOperand(N, OpNo), DAG);
 
   if (Res.Val == 0) {
     switch (N->getOpcode()) {