How To Add A Constrained Floating-Point Intrinsic¶
This is a work in progress.
Multiple files need to be updated when adding a new constrained intrinsic.
Add the new intrinsic to the table of intrinsics:
Add the new STRICT version of the node type to the ISD::NodeType enum:
Strict version name must be a concatenation of prefix
STRICT_ and the name
of corresponding non-strict node name. For instance, strict version of the
node FADD must be STRICT_FADD.
Add new record to the mapping of instructions to constrained intrinsic and DAG nodes:
Follow instructions provided in this file.
Update the IR verifier:
The function SelectionDAGBuilder::visitConstrainedFPIntrinsic 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:
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().:
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 code to do 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:
Whether the mutation may 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:
To make debug logs readable it is helpful to update the SelectionDAG’s debug logger::