blob: 9e7151940320f13917c3a39eb72160451c6606e7 [file] [log] [blame]
Kevin P. Neal339594e2019-04-11 17:16:03 +00001==================================================
2How To Add A Constrained Floating-Point Intrinsic
3==================================================
4
5.. contents::
6 :local:
7
8.. warning::
9 This is a work in progress.
10
11Add the intrinsic
12=================
13
14Multiple files need to be updated when adding a new constrained intrinsic.
15
16Add the new intrinsic to the table of intrinsics.::
17
18 include/llvm/IR/Intrinsics.td
19
20Update class ConstrainedFPIntrinsic to know about the intrinsics.::
21
22 include/llvm/IR/IntrinsicInst.h
23
24Functions like ConstrainedFPIntrinsic::isUnaryOp() or
25ConstrainedFPIntrinsic::isTernaryOp() may need to know about the new
26intrinsic.::
27
28 lib/IR/IntrinsicInst.cpp
29
30Update the IR verifier::
31
32 lib/IR/Verifier.cpp
33
34Add SelectionDAG node types
35===========================
36
37Add the new STRICT version of the node type to the ISD::NodeType enum.::
38
39 include/llvm/CodeGen/ISDOpcodes.h
40
41In class SDNode update isStrictFPOpcode()::
42
43 include/llvm/CodeGen/SelectionDAGNodes.h
44
45A mapping from the STRICT SDnode type to the non-STRICT is done in
46TargetLoweringBase::getStrictFPOperationAction(). This allows STRICT
47nodes to be legalized similarly to the non-STRICT node type.::
48
49 include/llvm/CodeGen/TargetLowering.h
50
51Building the SelectionDAG
52-------------------------
53
54The switch statement in SelectionDAGBuilder::visitIntrinsicCall() needs
55to be updated to call SelectionDAGBuilder::visitConstrainedFPIntrinsic().
56That function, in turn, needs to be updated to know how to create the
57SDNode for the intrinsic. The new STRICT node will eventually be converted
58to the matching non-STRICT node. For this reason it should have the same
59operands and values as the non-STRICT version but should also use the chain.
60This makes subsequent sharing of code for STRICT and non-STRICT code paths
61easier.::
62
63 lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
64
65Most of the STRICT nodes get legalized the same as their matching non-STRICT
66counterparts. A new STRICT node with this property must get added to the
67switch in SelectionDAGLegalize::LegalizeOp().::
68
69 lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
70
71Other parts of the legalizer may need to be updated as well. Look for
72places where the non-STRICT counterpart is legalized and update as needed.
73Be careful of the chain since STRICT nodes use it but their counterparts
Zachary Turner528b01e2019-04-11 17:30:03 +000074often don't.
Kevin P. Neal339594e2019-04-11 17:16:03 +000075
76The code to do the conversion or mutation of the STRICT node to a non-STRICT
77version of the node happens in SelectionDAG::mutateStrictFPToFP(). Be
78careful updating this function since some nodes have the same return type
79as their input operand, but some are different. Both of these cases must
80be properly handled.::
81
82 lib/CodeGen/SelectionDAG/SelectionDAG.cpp
83
Kevin P. Neald0f96be2019-06-25 16:09:39 +000084However, the mutation may not happen if the new node has not been registered
85in TargetLoweringBase::initActions(). If the corresponding non-STRICT node
86is Legal but a target does not know about STRICT nodes then the STRICT
87node will default to Legal and mutation will be bypassed with a "Cannot
88select" error. Register the new STRICT node as Expand to avoid this bug.::
89
90 lib/CodeGen/TargetLoweringBase.cpp
91
Kevin P. Neal339594e2019-04-11 17:16:03 +000092To make debug logs readable it is helpful to update the SelectionDAG's
93debug logger:::
94
95 lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
96
97Add documentation and tests
98===========================
99
100::
101
102 docs/LangRef.rst