[llvm-commits] [llvm] r59001 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h include/llvm/CodeGen/SelectionDAGNodes.h include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/Target/TargetSelectionDAG.td

Mon P Wang wangmp at apple.com
Mon Nov 10 12:54:11 PST 2008


Author: wangmp
Date: Mon Nov 10 14:54:11 2008
New Revision: 59001

URL: http://llvm.org/viewvc/llvm-project?rev=59001&view=rev
Log:
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.

Modified:
    llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
    llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
    llvm/trunk/include/llvm/Intrinsics.td
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
    llvm/trunk/lib/Target/TargetSelectionDAG.td

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=59001&r1=59000&r2=59001&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon Nov 10 14:54:11 2008
@@ -343,6 +343,11 @@
 
   SDValue getCondCode(ISD::CondCode Cond);
 
+  /// Returns the ConvertRndSat Note: Avoid using this node because it may
+  /// disappear in the future and most targets don't support it.
+  SDValue getConvertRndSat(MVT VT, SDValue Val, SDValue DTy, SDValue STy,
+                           SDValue Rnd, SDValue Sat, ISD::CvtCode Code);
+
   /// getZeroExtendInReg - Return the expression required to zero extend the Op
   /// value assuming it was the smaller SrcTy value.
   SDValue getZeroExtendInReg(SDValue Op, MVT SrcTy);

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=59001&r1=59000&r2=59001&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Mon Nov 10 14:54:11 2008
@@ -431,6 +431,18 @@
     // conversions, but that is a noop, deleted by getNode().
     BIT_CONVERT,
     
+    // CONVERT_RNDSAT - This operator is used to support various conversions
+    // between various types (float, signed, unsigned) with rounding and
+    // saturation. NOTE: Avoid using this operator as most target don't support
+    // it and they might be removed. It takes the following arguments:
+    //   0) value
+    //   1) dest type (type to convert to)
+    //   2) src type (type to convert from)
+    //   3) rounding imm
+    //   4) saturation imm
+    //   5) ISD::CvtCode indicating the type of conversion to do
+    CONVERT_RNDSAT,
+    
     // FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
     // FLOG, FLOG2, FLOG10, FEXP, FEXP2,
     // FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary floating
@@ -831,6 +843,22 @@
   /// function returns SETCC_INVALID if it is not possible to represent the
   /// resultant comparison.
   CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger);
+
+  //===--------------------------------------------------------------------===//
+  /// CvtCode enum - This enum defines the various converts CONVERT_RNDSAT 
+  /// supports.
+  enum CvtCode {
+    CVT_FF,     // Float from Float
+    CVT_FS,     // Float from Signed
+    CVT_FU,     // Float from Unsigned
+    CVT_SF,     // Signed from Float
+    CVT_UF,     // Unsigned from Float
+    CVT_SS,     // Signed from Signed
+    CVT_SU,     // Signed from Unsigned
+    CVT_US,     // Unsigned from Signed
+    CVT_UU,     // Unsigned from Unsigned
+    CVT_INVALID // Marker - Invalid opcode
+  };
 }  // end llvm::ISD namespace
 
 
@@ -2125,6 +2153,27 @@
   }
 };
 
+/// CvtRndSatSDNode - NOTE: avoid using this node as this may disappear in the
+/// future and most targets don't support it.
+class CvtRndSatSDNode : public SDNode {
+  ISD::CvtCode CvtCode;
+  virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
+protected:
+  friend class SelectionDAG;
+  explicit CvtRndSatSDNode(MVT VT, const SDValue *Ops, unsigned NumOps,
+                           ISD::CvtCode Code)
+    : SDNode(ISD::CONVERT_RNDSAT, getSDVTList(VT), Ops, NumOps), CvtCode(Code) {
+    assert(NumOps == 5 && "wrong number of operations");
+  }
+public:
+  ISD::CvtCode getCvtCode() const { return CvtCode; }
+
+  static bool classof(const CvtRndSatSDNode *) { return true; }
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::CONVERT_RNDSAT;
+  }
+};
+
 namespace ISD {
   struct ArgFlagsTy {
   private:

Modified: llvm/trunk/include/llvm/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=59001&r1=59000&r2=59001&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/Intrinsics.td Mon Nov 10 14:54:11 2008
@@ -362,6 +362,29 @@
 def int_trap : Intrinsic<[llvm_void_ty]>,
                GCCBuiltin<"__builtin_trap">;
 
+// These convert intrinsics are to support various conversions between
+// various types with rounding and saturation. NOTE: avoid using these
+// intrinsics as they might be removed sometime in the future and
+// most targets don't support them.
+def int_convertff  : Intrinsic<[llvm_anyfloat_ty, llvm_anyfloat_ty,
+                                llvm_i32_ty, llvm_i32_ty]>;
+def int_convertfsi : Intrinsic<[llvm_anyfloat_ty, llvm_anyint_ty,
+                                llvm_i32_ty, llvm_i32_ty]>;
+def int_convertfui : Intrinsic<[llvm_anyfloat_ty, llvm_anyint_ty,
+                                llvm_i32_ty, llvm_i32_ty]>;
+def int_convertsif : Intrinsic<[llvm_anyint_ty, llvm_anyfloat_ty,
+                                llvm_i32_ty, llvm_i32_ty]>;
+def int_convertuif : Intrinsic<[llvm_anyint_ty, llvm_anyfloat_ty,
+                                llvm_i32_ty, llvm_i32_ty]>;
+def int_convertss  : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
+                                llvm_i32_ty, llvm_i32_ty]>;
+def int_convertsu  : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
+                                llvm_i32_ty, llvm_i32_ty]>;
+def int_convertus  : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
+                                llvm_i32_ty, llvm_i32_ty]>;
+def int_convertuu  : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
+                                llvm_i32_ty, llvm_i32_ty]>;
+
 //===----------------------------------------------------------------------===//
 // Target-specific intrinsics
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=59001&r1=59000&r2=59001&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Nov 10 14:54:11 2008
@@ -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:

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=59001&r1=59000&r2=59001&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Mon Nov 10 14:54:11 2008
@@ -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);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=59001&r1=59000&r2=59001&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Mon Nov 10 14:54:11 2008
@@ -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);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp?rev=59001&r1=59000&r2=59001&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp Mon Nov 10 14:54:11 2008
@@ -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;

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=59001&r1=59000&r2=59001&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Nov 10 14:54:11 2008
@@ -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";

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59001&r1=59000&r2=59001&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Nov 10 14:54:11 2008
@@ -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(),

Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSelectionDAG.td?rev=59001&r1=59000&r2=59001&view=diff

==============================================================================
--- llvm/trunk/lib/Target/TargetSelectionDAG.td (original)
+++ llvm/trunk/lib/Target/TargetSelectionDAG.td Mon Nov 10 14:54:11 2008
@@ -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





More information about the llvm-commits mailing list