Add new ISD nodes: ISD::FMINNAN and ISD::FMAXNAN

The intention of these is to be a corollary to ISD::FMINNUM/FMAXNUM,
differing only on how NaNs are treated. FMINNUM returns the non-NaN
input (when given one NaN and one non-NaN), FMINNAN returns the NaN
input instead.

This patch includes support for scalarizing, widening and splitting
vectors, but not expansion or softening. The reason is that these
should never be needed - FMINNAN nodes are only going to be created
in one place (SDAGBuilder::visitSelect) and there we'll check if the
node is legal or custom. I could preemptively add expand and soften
code, but I'm fairly opposed to adding code I can't test. It's bad
enough I can't create tests with this patch, but at least this code
will be exercised by the ARM and AArch64 backends fairly shortly.

llvm-svn: 244581
This commit is contained in:
James Molloy 2015-08-11 09:13:05 +00:00
parent ecd6525b24
commit cf490f8ffc
7 changed files with 24 additions and 0 deletions

View File

@ -514,7 +514,15 @@ namespace ISD {
FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
FLOG, FLOG2, FLOG10, FEXP, FEXP2, FLOG, FLOG2, FLOG10, FEXP, FEXP2,
FCEIL, FTRUNC, FRINT, FNEARBYINT, FROUND, FFLOOR, FCEIL, FTRUNC, FRINT, FNEARBYINT, FROUND, FFLOOR,
/// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
/// values.
/// In the case where a single input is NaN, the non-NaN input is returned.
///
/// The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
FMINNUM, FMAXNUM, FMINNUM, FMAXNUM,
/// FMINNAN/FMAXNAN - Behave identically to FMINNUM/FMAXNUM, except that
/// when a single input is NaN, NaN is returned.
FMINNAN, FMAXNAN,
/// FSINCOS - Compute both fsin and fcos as a single operation. /// FSINCOS - Compute both fsin and fcos as a single operation.
FSINCOS, FSINCOS,

View File

@ -1088,6 +1088,8 @@ public:
case ISD::ADDE: case ISD::ADDE:
case ISD::FMINNUM: case ISD::FMINNUM:
case ISD::FMAXNUM: case ISD::FMAXNUM:
case ISD::FMINNAN:
case ISD::FMAXNAN:
return true; return true;
default: return false; default: return false;
} }

View File

@ -414,6 +414,8 @@ def fmad : SDNode<"ISD::FMAD" , SDTFPTernaryOp>;
def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>;
def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp>; def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp>;
def fmaxnum : SDNode<"ISD::FMAXNUM" , SDTFPBinOp>; def fmaxnum : SDNode<"ISD::FMAXNUM" , SDTFPBinOp>;
def fminnan : SDNode<"ISD::FMINNAN" , SDTFPBinOp>;
def fmaxnan : SDNode<"ISD::FMAXNAN" , SDTFPBinOp>;
def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>; def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>;
def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>;
def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>;

View File

@ -299,6 +299,8 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
case ISD::FABS: case ISD::FABS:
case ISD::FMINNUM: case ISD::FMINNUM:
case ISD::FMAXNUM: case ISD::FMAXNUM:
case ISD::FMINNAN:
case ISD::FMAXNAN:
case ISD::FCOPYSIGN: case ISD::FCOPYSIGN:
case ISD::FSQRT: case ISD::FSQRT:
case ISD::FSIN: case ISD::FSIN:

View File

@ -108,6 +108,8 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
case ISD::FMUL: case ISD::FMUL:
case ISD::FMINNUM: case ISD::FMINNUM:
case ISD::FMAXNUM: case ISD::FMAXNUM:
case ISD::FMINNAN:
case ISD::FMAXNAN:
case ISD::FPOW: case ISD::FPOW:
case ISD::FREM: case ISD::FREM:
@ -661,6 +663,8 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
case ISD::FMUL: case ISD::FMUL:
case ISD::FMINNUM: case ISD::FMINNUM:
case ISD::FMAXNUM: case ISD::FMAXNUM:
case ISD::FMINNAN:
case ISD::FMAXNAN:
case ISD::SDIV: case ISD::SDIV:
case ISD::UDIV: case ISD::UDIV:
case ISD::FDIV: case ISD::FDIV:
@ -1960,6 +1964,8 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
case ISD::XOR: case ISD::XOR:
case ISD::FMINNUM: case ISD::FMINNUM:
case ISD::FMAXNUM: case ISD::FMAXNUM:
case ISD::FMINNAN:
case ISD::FMAXNAN:
Res = WidenVecRes_Binary(N); Res = WidenVecRes_Binary(N);
break; break;

View File

@ -146,6 +146,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::FABS: return "fabs"; case ISD::FABS: return "fabs";
case ISD::FMINNUM: return "fminnum"; case ISD::FMINNUM: return "fminnum";
case ISD::FMAXNUM: return "fmaxnum"; case ISD::FMAXNUM: return "fmaxnum";
case ISD::FMINNAN: return "fminnan";
case ISD::FMAXNAN: return "fmaxnan";
case ISD::FNEG: return "fneg"; case ISD::FNEG: return "fneg";
case ISD::FSQRT: return "fsqrt"; case ISD::FSQRT: return "fsqrt";
case ISD::FSIN: return "fsin"; case ISD::FSIN: return "fsin";

View File

@ -814,6 +814,8 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::CONCAT_VECTORS, VT, Expand); setOperationAction(ISD::CONCAT_VECTORS, VT, Expand);
setOperationAction(ISD::FMINNUM, VT, Expand); setOperationAction(ISD::FMINNUM, VT, Expand);
setOperationAction(ISD::FMAXNUM, VT, Expand); setOperationAction(ISD::FMAXNUM, VT, Expand);
setOperationAction(ISD::FMINNAN, VT, Expand);
setOperationAction(ISD::FMAXNAN, VT, Expand);
setOperationAction(ISD::FMAD, VT, Expand); setOperationAction(ISD::FMAD, VT, Expand);
setOperationAction(ISD::SMIN, VT, Expand); setOperationAction(ISD::SMIN, VT, Expand);
setOperationAction(ISD::SMAX, VT, Expand); setOperationAction(ISD::SMAX, VT, Expand);