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
This commit is contained in:
Mon P Wang 2008-11-10 20:54:11 +00:00
parent cf1f23f6e3
commit 77cdf30742
10 changed files with 367 additions and 2 deletions

View File

@ -343,6 +343,11 @@ public:
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);

View File

@ -431,6 +431,18 @@ namespace ISD {
// 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 @@ namespace ISD {
/// 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 @@ public:
}
};
/// 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:

View File

@ -362,6 +362,29 @@ def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
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
//===----------------------------------------------------------------------===//

View File

@ -3816,7 +3816,49 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
}
}
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 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
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 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
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 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) {
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 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
}
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:

View File

@ -610,7 +610,8 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
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 @@ SDValue DAGTypeLegalizer::PromoteIntOp_INT_TO_FP(SDNode *N) {
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);

View File

@ -259,6 +259,7 @@ private:
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 @@ private:
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 @@ private:
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);

View File

@ -43,6 +43,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
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 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_BIT_CONVERT(SDNode *N) {
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 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
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 @@ void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo,
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;

View File

@ -1137,6 +1137,21 @@ SDValue SelectionDAG::getCondCode(ISD::CondCode Cond) {
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 StoreSDNode::ANCHOR() {}
void AtomicSDNode::ANCHOR() {}
void MemIntrinsicSDNode::ANCHOR() {}
void CallSDNode::ANCHOR() {}
void CvtRndSatSDNode::ANCHOR() {}
HandleSDNode::~HandleSDNode() {
DropOperands();
@ -5160,6 +5176,21 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
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";

View File

@ -3859,6 +3859,38 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
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(),

View File

@ -200,6 +200,10 @@ def STDAtomic2 : SDTypeProfile<1, 2, [
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_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
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
@ -788,6 +794,54 @@ def setle : PatFrag<(ops node:$lhs, node:$rhs),
def setne : PatFrag<(ops node:$lhs, node:$rhs),
(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.
//