================================================== How To Add A Constrained Floating-Point Intrinsic ================================================== .. contents:: :local: .. warning:: This is a work in progress. Add the intrinsic ================= Multiple files need to be updated when adding a new constrained intrinsic. Add the new intrinsic to the table of intrinsics:: include/llvm/IR/Intrinsics.td Add SelectionDAG node types =========================== Add the new ``STRICT`` version of the node type to the ``ISD::NodeType`` enum:: include/llvm/CodeGen/ISDOpcodes.h Strict version name must be a concatenation of prefix ``STRICT_`` and the name of the corresponding non-strict node name. For instance, strict version of the node ``FADD`` must be ``STRICT_FADD``. Update mappings =============== Add new record to the mapping of instructions to constrained intrinsic and DAG nodes:: include/llvm/IR/ConstrainedOps.def Follow instructions provided in this file. Update IR components ==================== Update the IR verifier:: lib/IR/Verifier.cpp Update Selector components ========================== Building the SelectionDAG ------------------------- The ``SelectionDAGBuilder::visitConstrainedFPIntrinsic`` function builds DAG nodes using mappings specified in ``ConstrainedOps.def``. If however this default build is not sufficient, the build can be modified, see how it is implemented for ``STRICT_FP_ROUND``. The new ``STRICT`` node will eventually be converted to the matching non-``STRICT`` node. For this reason it should have the same operands and values as the non-``STRICT`` version but should also use the chain. This makes subsequent sharing of code for ``STRICT`` and non-``STRICT`` code paths easier:: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Most of the ``STRICT`` nodes get legalized the same as their matching non-``STRICT`` counterparts. A new ``STRICT`` node with this property must get added to the switch in ``SelectionDAGLegalize::LegalizeOp()``:: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Other parts of the legalizer may need to be updated as well. Look for places where the non-``STRICT`` counterpart is legalized and update as needed. Be careful of the chain since ``STRICT`` nodes use it but their counterparts often don't. The conversion or mutation of the ``STRICT`` node to a non-``STRICT`` version of the node happens in ``SelectionDAG::mutateStrictFPToFP()``. In most cases the function can do the conversion using information from ConstrainedOps.def. Be careful updating this function since some nodes have the same return type as their input operand, but some are different. Both of these cases must be properly handled:: lib/CodeGen/SelectionDAG/SelectionDAG.cpp Whether the mutation happens or not depends on how the new node has been registered in ``TargetLoweringBase::initActions()``. By default, all strict nodes are registered with Expand action:: lib/CodeGen/TargetLoweringBase.cpp To make debug logs readable, it is helpful to update the SelectionDAG's debug logger::: lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp Add documentation and tests =========================== :: docs/LangRef.rst