Skip to content

Commit

Permalink
[FPEnv] [FPEnv] Add constrained intrinsics for MAXNUM and MINNUM
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D53216

llvm-svn: 345650
  • Loading branch information
mcinally committed Oct 30, 2018
1 parent f6e3d14 commit 2ad870e
Show file tree
Hide file tree
Showing 14 changed files with 638 additions and 1 deletion.
74 changes: 74 additions & 0 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14485,6 +14485,80 @@ mode is determined by the runtime floating-point environment. The rounding
mode argument is only intended as information to the compiler.


'``llvm.experimental.constrained.maxnum``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Syntax:
"""""""

::

declare <type>
@llvm.experimental.constrained.maxnum(<type> <op1>, <type> <op2>
metadata <rounding mode>,
metadata <exception behavior>)

Overview:
"""""""""

The '``llvm.experimental.constrained.maxnum``' intrinsic returns the maximum
of the two arguments.

Arguments:
""""""""""

The first two arguments and the return value are floating-point numbers
of the same type.

The third and forth arguments specify the rounding mode and exception
behavior as described above.

Semantics:
""""""""""

This function follows the IEEE-754 semantics for maxNum. The rounding mode is
described, not determined, by the rounding mode argument. The actual rounding
mode is determined by the runtime floating-point environment. The rounding
mode argument is only intended as information to the compiler.


'``llvm.experimental.constrained.minnum``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Syntax:
"""""""

::

declare <type>
@llvm.experimental.constrained.minnum(<type> <op1>, <type> <op2>
metadata <rounding mode>,
metadata <exception behavior>)

Overview:
"""""""""

The '``llvm.experimental.constrained.minnum``' intrinsic returns the minimum
of the two arguments.

Arguments:
""""""""""

The first two arguments and the return value are floating-point numbers
of the same type.

The third and forth arguments specify the rounding mode and exception
behavior as described above.

Semantics:
""""""""""

This function follows the IEEE-754 semantics for minNum. The rounding mode is
described, not determined, by the rounding mode argument. The actual rounding
mode is determined by the runtime floating-point environment. The rounding
mode argument is only intended as information to the compiler.


General Intrinsics
------------------

Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/ISDOpcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ namespace ISD {
/// They are used to limit optimizations while the DAG is being optimized.
STRICT_FSQRT, STRICT_FPOW, STRICT_FPOWI, STRICT_FSIN, STRICT_FCOS,
STRICT_FEXP, STRICT_FEXP2, STRICT_FLOG, STRICT_FLOG10, STRICT_FLOG2,
STRICT_FRINT, STRICT_FNEARBYINT,
STRICT_FRINT, STRICT_FNEARBYINT, STRICT_FMAXNUM, STRICT_FMINNUM,

/// FMA - Perform a * b + c with no intermediate rounding step.
FMA,
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/SelectionDAGNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,8 @@ class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
case ISD::STRICT_FLOG2:
case ISD::STRICT_FRINT:
case ISD::STRICT_FNEARBYINT:
case ISD::STRICT_FMAXNUM:
case ISD::STRICT_FMINNUM:
return true;
}
}
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,8 @@ class TargetLoweringBase {
case ISD::STRICT_FLOG2: EqOpc = ISD::FLOG2; break;
case ISD::STRICT_FRINT: EqOpc = ISD::FRINT; break;
case ISD::STRICT_FNEARBYINT: EqOpc = ISD::FNEARBYINT; break;
case ISD::STRICT_FMAXNUM: EqOpc = ISD::FMAXNUM; break;
case ISD::STRICT_FMINNUM: EqOpc = ISD::FMINNUM; break;
}

auto Action = getOperationAction(EqOpc, VT);
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/IR/IntrinsicInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ namespace llvm {
case Intrinsic::experimental_constrained_log2:
case Intrinsic::experimental_constrained_rint:
case Intrinsic::experimental_constrained_nearbyint:
case Intrinsic::experimental_constrained_maxnum:
case Intrinsic::experimental_constrained_minnum:
return true;
default: return false;
}
Expand Down
10 changes: 10 additions & 0 deletions llvm/include/llvm/IR/Intrinsics.td
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,16 @@ let IntrProperties = [IntrInaccessibleMemOnly] in {
[ LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
def int_experimental_constrained_maxnum : Intrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
def int_experimental_constrained_minnum : Intrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
}
// FIXME: Add intrinsics for fcmp, fptrunc, fpext, fptoui and fptosi.
// FIXME: Add intrinsics for fabs, copysign, floor, ceil, trunc and round?
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,8 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
case ISD::STRICT_FLOG2:
case ISD::STRICT_FRINT:
case ISD::STRICT_FNEARBYINT:
case ISD::STRICT_FMAXNUM:
case ISD::STRICT_FMINNUM:
// These pseudo-ops get legalized as if they were their non-strict
// equivalent. For instance, if ISD::FSQRT is legal then ISD::STRICT_FSQRT
// is also legal, but if ISD::FSQRT requires expansion then so does
Expand Down Expand Up @@ -3833,11 +3835,13 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
break;
}
case ISD::FMINNUM:
case ISD::STRICT_FMINNUM:
Results.push_back(ExpandFPLibCall(Node, RTLIB::FMIN_F32, RTLIB::FMIN_F64,
RTLIB::FMIN_F80, RTLIB::FMIN_F128,
RTLIB::FMIN_PPCF128));
break;
case ISD::FMAXNUM:
case ISD::STRICT_FMAXNUM:
Results.push_back(ExpandFPLibCall(Node, RTLIB::FMAX_F32, RTLIB::FMAX_F64,
RTLIB::FMAX_F80, RTLIB::FMAX_F128,
RTLIB::FMAX_PPCF128));
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
case ISD::STRICT_FLOG2:
case ISD::STRICT_FRINT:
case ISD::STRICT_FNEARBYINT:
case ISD::STRICT_FMAXNUM:
case ISD::STRICT_FMINNUM:
// These pseudo-ops get legalized as if they were their non-strict
// equivalent. For instance, if ISD::FSQRT is legal then ISD::STRICT_FSQRT
// is also legal, but if ISD::FSQRT requires expansion then so does
Expand Down Expand Up @@ -751,6 +753,8 @@ SDValue VectorLegalizer::Expand(SDValue Op) {
case ISD::STRICT_FLOG2:
case ISD::STRICT_FRINT:
case ISD::STRICT_FNEARBYINT:
case ISD::STRICT_FMAXNUM:
case ISD::STRICT_FMINNUM:
return ExpandStrictFPOp(Op);
default:
return DAG.UnrollVectorOp(Op.getNode());
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
case ISD::STRICT_FLOG2:
case ISD::STRICT_FRINT:
case ISD::STRICT_FNEARBYINT:
case ISD::STRICT_FMAXNUM:
case ISD::STRICT_FMINNUM:
R = ScalarizeVecRes_StrictFPOp(N);
break;
}
Expand Down Expand Up @@ -834,6 +836,8 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
case ISD::STRICT_FLOG2:
case ISD::STRICT_FRINT:
case ISD::STRICT_FNEARBYINT:
case ISD::STRICT_FMAXNUM:
case ISD::STRICT_FMINNUM:
SplitVecRes_StrictFPOp(N, Lo, Hi);
break;
}
Expand Down Expand Up @@ -2400,6 +2404,8 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
case ISD::STRICT_FLOG2:
case ISD::STRICT_FRINT:
case ISD::STRICT_FNEARBYINT:
case ISD::STRICT_FMAXNUM:
case ISD::STRICT_FMINNUM:
Res = WidenVecRes_StrictFP(N);
break;

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7404,6 +7404,8 @@ SDNode* SelectionDAG::mutateStrictFPToFP(SDNode *Node) {
NewOpc = ISD::FNEARBYINT;
IsUnary = true;
break;
case ISD::STRICT_FMAXNUM: NewOpc = ISD::FMAXNUM; break;
case ISD::STRICT_FMINNUM: NewOpc = ISD::FMINNUM; break;
}

// We're taking this node out of the chain, so we need to re-link things.
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5627,6 +5627,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
case Intrinsic::experimental_constrained_log2:
case Intrinsic::experimental_constrained_rint:
case Intrinsic::experimental_constrained_nearbyint:
case Intrinsic::experimental_constrained_maxnum:
case Intrinsic::experimental_constrained_minnum:
visitConstrainedFPIntrinsic(cast<ConstrainedFPIntrinsic>(I));
return nullptr;
case Intrinsic::fmuladd: {
Expand Down Expand Up @@ -6374,6 +6376,12 @@ void SelectionDAGBuilder::visitConstrainedFPIntrinsic(
case Intrinsic::experimental_constrained_nearbyint:
Opcode = ISD::STRICT_FNEARBYINT;
break;
case Intrinsic::experimental_constrained_maxnum:
Opcode = ISD::STRICT_FMAXNUM;
break;
case Intrinsic::experimental_constrained_minnum:
Opcode = ISD::STRICT_FMINNUM;
break;
}
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
SDValue Chain = getRoot();
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,9 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
// Unary operators
case ISD::FABS: return "fabs";
case ISD::FMINNUM: return "fminnum";
case ISD::STRICT_FMINNUM: return "strict_fminnum";
case ISD::FMAXNUM: return "fmaxnum";
case ISD::STRICT_FMAXNUM: return "strict_fmaxnum";
case ISD::FMINNUM_IEEE: return "fminnum_ieee";
case ISD::FMAXNUM_IEEE: return "fmaxnum_ieee";
case ISD::FMINIMUM: return "fminimum";
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4104,6 +4104,8 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
case Intrinsic::experimental_constrained_log2:
case Intrinsic::experimental_constrained_rint:
case Intrinsic::experimental_constrained_nearbyint:
case Intrinsic::experimental_constrained_maxnum:
case Intrinsic::experimental_constrained_minnum:
visitConstrainedFPIntrinsic(
cast<ConstrainedFPIntrinsic>(*CS.getInstruction()));
break;
Expand Down
Loading

0 comments on commit 2ad870e

Please sign in to comment.