Added CONVERT_RNDSAT (conversion with rounding and saturation) SDNode to
support targets that support these conversions. Users should avoid using
this node as the current targets don't generating code for it.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59001 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 5ac7a80..f84e22b 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -3816,7 +3816,49 @@
       }
     }
     break;
-      
+  case ISD::CONVERT_RNDSAT: {
+    ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(Node)->getCvtCode();
+    switch (CvtCode) {
+    default: assert(0 && "Unknown cvt code!");
+    case ISD::CVT_SF:
+    case ISD::CVT_UF:
+      break;
+    case ISD::CVT_FF:
+    case ISD::CVT_FS:
+    case ISD::CVT_FU:
+    case ISD::CVT_SS:
+    case ISD::CVT_SU:
+    case ISD::CVT_US:
+    case ISD::CVT_UU: {
+      SDValue DTyOp = Node->getOperand(1);
+      SDValue STyOp = Node->getOperand(2);
+      SDValue RndOp = Node->getOperand(3);
+      SDValue SatOp = Node->getOperand(4);
+      switch (getTypeAction(Node->getOperand(0).getValueType())) {
+      case Expand: assert(0 && "Shouldn't need to expand other operators here!");
+      case Legal:
+        Tmp1 = LegalizeOp(Node->getOperand(0));
+        Result = DAG.UpdateNodeOperands(Result, Tmp1, DTyOp, STyOp,
+                                        RndOp, SatOp);
+        if (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)) ==
+            TargetLowering::Custom) {
+          Tmp1 = TLI.LowerOperation(Result, DAG);
+          if (Tmp1.getNode()) Result = Tmp1;
+        }
+        break;
+      case Promote:
+        Result = PromoteOp(Node->getOperand(0));
+        // For FP, make Op1 a i32
+        
+        Result = DAG.getConvertRndSat(Result.getValueType(), Result,
+                                      DTyOp, STyOp, RndOp, SatOp, CvtCode);
+        break;
+      }
+      break;
+    }
+    } // end switch CvtCode
+    break;
+  }
     // Conversion operators.  The source and destination have different types.
   case ISD::SINT_TO_FP:
   case ISD::UINT_TO_FP: {
@@ -4234,6 +4276,19 @@
       break;
     }
     break;
+  case ISD::CONVERT_RNDSAT: {
+    ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(Node)->getCvtCode();
+    assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
+             CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
+             CvtCode == ISD::CVT_SF || CvtCode == ISD::CVT_UF) &&
+            "can only promote integers");
+    Result = DAG.getConvertRndSat(NVT, Node->getOperand(0),
+                                  Node->getOperand(1), Node->getOperand(2),
+                                  Node->getOperand(3), Node->getOperand(4),
+                                  CvtCode);
+    break;
+
+  }
   case ISD::BIT_CONVERT:
     Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
                               Node->getValueType(0));
@@ -7344,6 +7399,24 @@
     Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H);
     break;
   }
+  case ISD::CONVERT_RNDSAT: {
+    ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(Node)->getCvtCode();
+    SDValue L, H;
+    SplitVectorOp(Node->getOperand(0), L, H);
+    SDValue DTyOpL =  DAG.getValueType(NewVT_Lo);
+    SDValue DTyOpH =  DAG.getValueType(NewVT_Hi);
+    SDValue STyOpL =  DAG.getValueType(L.getValueType());
+    SDValue STyOpH =  DAG.getValueType(H.getValueType());
+
+    SDValue RndOp = Node->getOperand(3);
+    SDValue SatOp = Node->getOperand(4);
+
+    Lo = DAG.getConvertRndSat(NewVT_Lo, L, DTyOpL, STyOpL,
+                              RndOp, SatOp, CvtCode);
+    Hi = DAG.getConvertRndSat(NewVT_Hi, H, DTyOpH, STyOpH,
+                              RndOp, SatOp, CvtCode);
+    break;
+  }
   case ISD::LOAD: {
     LoadSDNode *LD = cast<LoadSDNode>(Node);
     SDValue Ch = LD->getChain();
@@ -7482,6 +7555,16 @@
                          NewVT, 
                          ScalarizeVectorOp(Node->getOperand(0)));
     break;
+  case ISD::CONVERT_RNDSAT: {
+    SDValue Op0 = ScalarizeVectorOp(Node->getOperand(0));
+    Result = DAG.getConvertRndSat(NewVT, Op0,
+                                  DAG.getValueType(NewVT),
+                                  DAG.getValueType(Op0.getValueType()),
+                                  Node->getOperand(3),
+                                  Node->getOperand(4),
+                                  cast<CvtRndSatSDNode>(Node)->getCvtCode());
+    break;
+  }
   case ISD::FPOWI:
   case ISD::FP_ROUND:
     Result = DAG.getNode(Node->getOpcode(),
@@ -7781,6 +7864,44 @@
     }
     break;
   }
+  case ISD::CONVERT_RNDSAT: {
+    SDValue RndOp = Node->getOperand(3);
+    SDValue SatOp = Node->getOperand(4);
+
+    TargetLowering::LegalizeAction action =
+      TLI.getOperationAction(Node->getOpcode(), WidenVT);
+
+    SDValue SrcOp = Node->getOperand(0);
+
+    // Converts between two different types so we need to determine
+    // the correct widen type for the input operand.
+    MVT SVT = SrcOp.getValueType();
+    assert(SVT.isVector() && "can not widen non vector type");
+    MVT SEVT = SVT.getVectorElementType();
+    MVT SWidenVT =  MVT::getVectorVT(SEVT, NewNumElts);
+
+    SrcOp = WidenVectorOp(SrcOp, SWidenVT);
+    assert(SrcOp.getValueType() == WidenVT);
+    SDValue DTyOp = DAG.getValueType(WidenVT);
+    SDValue STyOp = DAG.getValueType(SrcOp.getValueType());
+    ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(Node)->getCvtCode();
+
+    Result = DAG.getConvertRndSat(WidenVT, SrcOp, DTyOp, STyOp,
+                                  RndOp, SatOp, CvtCode);
+    switch (action)  {
+    default: assert(0 && "action not supported");
+    case TargetLowering::Legal:
+      break;
+    case TargetLowering::Promote:
+      // We defer the promotion to when we legalize the op
+      break;
+    case TargetLowering::Expand:
+      // Expand the operation into a bunch of nasty scalar code.
+      Result = LegalizeOp(UnrollVectorOp(Result));
+      break;
+    }
+    break;
+  }
   case ISD::FPOW:
   case ISD::FPOWI: 
   case ISD::ADD:
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index b2c668b..0a579de 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -610,7 +610,8 @@
     case ISD::ZERO_EXTEND:  Res = PromoteIntOp_ZERO_EXTEND(N); break;
 
     case ISD::SINT_TO_FP:
-    case ISD::UINT_TO_FP: Res = PromoteIntOp_INT_TO_FP(N); break;
+    case ISD::UINT_TO_FP:      Res = PromoteIntOp_INT_TO_FP(N); break;
+    case ISD::CONVERT_RNDSAT:  Res = PromoteIntOp_CONVERT_RNDSAT(N); break;
     }
   }
 
@@ -813,6 +814,21 @@
   return DAG.UpdateNodeOperands(SDValue(N, 0), In);
 }
 
+SDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) {
+  MVT OutVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
+  assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
+           CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
+           CvtCode == ISD::CVT_SF || CvtCode == ISD::CVT_UF) &&
+          "can only promote integers");
+  SDValue In = DAG.getConvertRndSat(OutVT,N->getOperand(0),
+                                    N->getOperand(1), N->getOperand(2),
+                                    N->getOperand(3), N->getOperand(4), CvtCode);
+  return DAG.UpdateNodeOperands(SDValue(N, 0), In);
+}
+
+
+
 SDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) {
   SDValue NewOps[6];
   NewOps[0] = N->getOperand(0);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 17c76ed..a69302a 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -259,6 +259,7 @@
   SDValue PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo);
   SDValue PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo);
   SDValue PromoteIntOp_BUILD_VECTOR(SDNode *N);
+  SDValue PromoteIntOp_CONVERT_RNDSAT(SDNode *N);
   SDValue PromoteIntOp_FP_EXTEND(SDNode *N);
   SDValue PromoteIntOp_FP_ROUND(SDNode *N);
   SDValue PromoteIntOp_INT_TO_FP(SDNode *N);
@@ -442,6 +443,7 @@
   SDValue ScalarizeVecRes_UnaryOp(SDNode *N);
 
   SDValue ScalarizeVecRes_BIT_CONVERT(SDNode *N);
+  SDValue ScalarizeVecRes_CONVERT_RNDSAT(SDNode *N);
   SDValue ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N);
   SDValue ScalarizeVecRes_FPOWI(SDNode *N);
   SDValue ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N);
@@ -475,6 +477,7 @@
   void SplitVecRes_BUILD_PAIR(SDNode *N, SDValue &Lo, SDValue &Hi);
   void SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo, SDValue &Hi);
   void SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo, SDValue &Hi);
+  void SplitVecRes_CONVERT_RNDSAT(SDNode *N, SDValue &Lo, SDValue &Hi);
   void SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo, SDValue &Hi);
   void SplitVecRes_FPOWI(SDNode *N, SDValue &Lo, SDValue &Hi);
   void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index b22bf7f..bbc7c6a 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -43,6 +43,7 @@
 
   case ISD::BIT_CONVERT:    R = ScalarizeVecRes_BIT_CONVERT(N); break;
   case ISD::BUILD_VECTOR:   R = N->getOperand(0); break;
+  case ISD::CONVERT_RNDSAT: R = ScalarizeVecRes_CONVERT_RNDSAT(N); break;
   case ISD::EXTRACT_SUBVECTOR: R = ScalarizeVecRes_EXTRACT_SUBVECTOR(N); break;
   case ISD::FPOWI:          R = ScalarizeVecRes_FPOWI(N); break;
   case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break;
@@ -106,6 +107,16 @@
   return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0));
 }
 
+SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_RNDSAT(SDNode *N) {
+  MVT NewVT = N->getValueType(0).getVectorElementType();
+  SDValue Op0 = GetScalarizedVector(N->getOperand(0));
+  return DAG.getConvertRndSat(NewVT, Op0, DAG.getValueType(NewVT),
+                              DAG.getValueType(Op0.getValueType()),
+                              N->getOperand(3),
+                              N->getOperand(4),
+                              cast<CvtRndSatSDNode>(N)->getCvtCode());
+}
+
 SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
   return DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
                      N->getValueType(0).getVectorElementType(),
@@ -339,6 +350,7 @@
   case ISD::BIT_CONVERT:       SplitVecRes_BIT_CONVERT(N, Lo, Hi); break;
   case ISD::BUILD_VECTOR:      SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break;
   case ISD::CONCAT_VECTORS:    SplitVecRes_CONCAT_VECTORS(N, Lo, Hi); break;
+  case ISD::CONVERT_RNDSAT:    SplitVecRes_CONVERT_RNDSAT(N, Lo, Hi); break;
   case ISD::EXTRACT_SUBVECTOR: SplitVecRes_EXTRACT_SUBVECTOR(N, Lo, Hi); break;
   case ISD::FPOWI:             SplitVecRes_FPOWI(N, Lo, Hi); break;
   case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
@@ -487,6 +499,25 @@
   Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size());
 }
 
+void DAGTypeLegalizer::SplitVecRes_CONVERT_RNDSAT(SDNode *N, SDValue &Lo,
+                                                  SDValue &Hi) {
+  MVT LoVT, HiVT;
+  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+  SDValue VLo, VHi;
+  GetSplitVector(N->getOperand(0), VLo, VHi);
+  SDValue DTyOpLo =  DAG.getValueType(LoVT);
+  SDValue DTyOpHi =  DAG.getValueType(HiVT);
+  SDValue STyOpLo =  DAG.getValueType(VLo.getValueType());
+  SDValue STyOpHi =  DAG.getValueType(VHi.getValueType());
+
+  SDValue RndOp = N->getOperand(3);
+  SDValue SatOp = N->getOperand(4);
+  ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
+
+  Lo = DAG.getConvertRndSat(LoVT, VLo, DTyOpLo, STyOpLo, RndOp, SatOp, CvtCode);
+  Hi = DAG.getConvertRndSat(HiVT, VHi, DTyOpHi, STyOpHi, RndOp, SatOp, CvtCode);
+}
+
 void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo,
                                                      SDValue &Hi) {
   MVT LoVT, HiVT;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index fb8630f..61a04bf 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1137,6 +1137,21 @@
   return SDValue(CondCodeNodes[Cond], 0);
 }
 
+SDValue SelectionDAG::getConvertRndSat(MVT VT, SDValue Val, SDValue DTy,
+                                       SDValue STy, SDValue Rnd, SDValue Sat,
+                                       ISD::CvtCode Code) {
+  FoldingSetNodeID ID;
+  void* IP = 0;
+  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+    return SDValue(E, 0);
+  CvtRndSatSDNode *N = NodeAllocator.Allocate<CvtRndSatSDNode>();
+  SDValue Ops[] = { Val, DTy, STy, Rnd, Sat };
+  new (N) CvtRndSatSDNode(VT, Ops, 5, Code);
+  CSEMap.InsertNode(N, IP);
+  AllNodes.push_back(N);
+  return SDValue(N, 0);
+}
+
 SDValue SelectionDAG::getRegister(unsigned RegNo, MVT VT) {
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::Register, getVTList(VT), 0, 0);
@@ -4727,6 +4742,7 @@
 void AtomicSDNode::ANCHOR() {}
 void MemIntrinsicSDNode::ANCHOR() {}
 void CallSDNode::ANCHOR() {}
+void CvtRndSatSDNode::ANCHOR() {}
 
 HandleSDNode::~HandleSDNode() {
   DropOperands();
@@ -5160,6 +5176,21 @@
   case ISD::FP_TO_SINT:  return "fp_to_sint";
   case ISD::FP_TO_UINT:  return "fp_to_uint";
   case ISD::BIT_CONVERT: return "bit_convert";
+  
+  case ISD::CONVERT_RNDSAT: {
+    switch (cast<CvtRndSatSDNode>(this)->getCvtCode()) {
+    default: assert(0 && "Unknown cvt code!");
+    case ISD::CVT_FF:  return "cvt_ff";
+    case ISD::CVT_FS:  return "cvt_fs";
+    case ISD::CVT_FU:  return "cvt_fu";
+    case ISD::CVT_SF:  return "cvt_sf";
+    case ISD::CVT_UF:  return "cvt_uf";
+    case ISD::CVT_SS:  return "cvt_ss";
+    case ISD::CVT_SU:  return "cvt_su";
+    case ISD::CVT_US:  return "cvt_us";
+    case ISD::CVT_UU:  return "cvt_uu";
+    }
+  }
 
     // Control flow instructions
   case ISD::BR:      return "br";
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
index 032e8bf..436e5ff 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
@@ -3859,6 +3859,38 @@
     return 0;
   }
 
+  case Intrinsic::convertff:
+  case Intrinsic::convertfsi:
+  case Intrinsic::convertfui:
+  case Intrinsic::convertsif:
+  case Intrinsic::convertuif:
+  case Intrinsic::convertss:
+  case Intrinsic::convertsu:
+  case Intrinsic::convertus:
+  case Intrinsic::convertuu: {
+    ISD::CvtCode Code = ISD::CVT_INVALID;
+    switch (Intrinsic) {
+    case Intrinsic::convertff:  Code = ISD::CVT_FF; break;
+    case Intrinsic::convertfsi: Code = ISD::CVT_FS; break;
+    case Intrinsic::convertfui: Code = ISD::CVT_FU; break;
+    case Intrinsic::convertsif: Code = ISD::CVT_SF; break;
+    case Intrinsic::convertuif: Code = ISD::CVT_UF; break;
+    case Intrinsic::convertss:  Code = ISD::CVT_SS; break;
+    case Intrinsic::convertsu:  Code = ISD::CVT_SU; break;
+    case Intrinsic::convertus:  Code = ISD::CVT_US; break;
+    case Intrinsic::convertuu:  Code = ISD::CVT_UU; break;
+    }
+    MVT DestVT = TLI.getValueType(I.getType());
+    Value* Op1 = I.getOperand(1);
+    setValue(&I, DAG.getConvertRndSat(DestVT, getValue(Op1),
+                                DAG.getValueType(DestVT),
+                                DAG.getValueType(getValue(Op1).getValueType()),
+                                getValue(I.getOperand(2)),
+                                getValue(I.getOperand(3)),
+                                Code));
+    return 0;
+  }
+
   case Intrinsic::sqrt:
     setValue(&I, DAG.getNode(ISD::FSQRT,
                              getValue(I.getOperand(1)).getValueType(),
diff --git a/lib/Target/TargetSelectionDAG.td b/lib/Target/TargetSelectionDAG.td
index 4e38a5d..c936f7a 100644
--- a/lib/Target/TargetSelectionDAG.td
+++ b/lib/Target/TargetSelectionDAG.td
@@ -200,6 +200,10 @@
   SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1>
 ]>;
 
+def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su
+  SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5>
+]>;
+
 class SDCallSeqStart<list<SDTypeConstraint> constraints> :
         SDTypeProfile<0, 1, constraints>;
 class SDCallSeqEnd<list<SDTypeConstraint> constraints> :
@@ -490,6 +494,8 @@
 def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN", 
                                 SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>;
 
+// Do not use cvt directly. Use cvt forms below
+def cvt : SDNode<"ISD::CONVERT_RNDSAT", SDTConvertOp>;
 
 //===----------------------------------------------------------------------===//
 // Selection DAG Condition Codes
@@ -789,6 +795,54 @@
                      (setcc node:$lhs, node:$rhs, SETNE)>;
 
 //===----------------------------------------------------------------------===//
+// Selection DAG CONVERT_RNDSAT patterns
+
+def cvtff : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FF;
+    }]>;
+
+def cvtss : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SS;
+    }]>;
+
+def cvtsu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SU;
+    }]>;
+
+def cvtus : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_US;
+    }]>;
+
+def cvtuu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_UU;
+    }]>;
+
+def cvtsf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SF;
+    }]>;
+
+def cvtuf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_UF;
+    }]>;
+
+def cvtfs : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FS;
+    }]>;
+
+def cvtfu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FU;
+    }]>;
+
+//===----------------------------------------------------------------------===//
 // Selection DAG Pattern Support.
 //
 // Patterns are what are actually matched against the target-flavored