How To Add A Constrained Floating-Point Intrinsic
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 nameof corresponding non-strict node name. For instance, strict version of thenode FADD must be STRICT_FADD.
Update mappings
Add new record to the mapping of instructions to constrained intrinsic andDAG 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 function SelectionDAGBuilder::visitConstrainedFPIntrinsic builds DAG nodesusing mappings specified in ConstrainedOps.def. If however this default build isnot sufficient, the build can be modified, see how it is implemented forSTRICT_FP_ROUND. The new STRICT node will eventually be convertedto the matching non-STRICT node. For this reason it should have the sameoperands 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 pathseasier:
- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Most of the STRICT nodes get legalized the same as their matching non-STRICTcounterparts. A new STRICT node with this property must get added to theswitch in SelectionDAGLegalize::LegalizeOp().:
- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Other parts of the legalizer may need to be updated as well. Look forplaces where the non-STRICT counterpart is legalized and update as needed.Be careful of the chain since STRICT nodes use it but their counterpartsoften don’t.
The code to do the conversion or mutation of the STRICT node to a non-STRICTversion of the node happens in SelectionDAG::mutateStrictFPToFP(). In most casesthe function can do the conversion using information from ConstrainedOps.def. Becareful updating this function since some nodes have the same return typeas their input operand, but some are different. Both of these cases mustbe properly handled:
- lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Whether the mutation may happens or not, depends on how the new node has beenregistered in TargetLoweringBase::initActions(). By default all strict nodes areregistered with Expand action:
- lib/CodeGen/TargetLoweringBase.cpp
To make debug logs readable it is helpful to update the SelectionDAG’sdebug logger::
- lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
Add documentation and tests
- docs/LangRef.rst