The ISD::STRICT_ nodes used to implement the constrained floating-point intrinsics are currently never passed to the target back-end, which makes it impossible to handle them correctly (e.g. mark instructions are depending on a floating-point status and control register, or mark instructions as possibly trapping).
This patch allows the target to use setOperationAction to switch the action on ISD::STRICT_ nodes to Legal. If this is done, the SelectionDAG common code will stop converting the STRICT nodes to regular floating-point nodes, but instead pass the STRICT nodes to the target using normal SelectionDAG matching rules.
To avoid having the back-end duplicate all the floating-point instruction patterns to handle both strict and non-strict variants, we implement the following mechanism to represent both using the same MI definition:
Floating-point instruction dependencies are represented at the MI level in two ways:
- All FP instructions (strict *and* non-strict) are modeled to use a platform-specifc floating-point control register. This models global state that FP operations depend on, e.g. current rounding mode and exception mask setting. (For non-strict instructions, the only difference this makes is that they cannot be scheduled across an instruction that changes the FPC register.)
- Strict FP instructions are modeled to carry an extra memory operand refering to a new PseudoSourceValue of class FPStatus. This represents the changes to global state that may be *caused* by the instruction, e.g. setting exception status bits or triggering a trap.
In order to allow the same MI definition to be used both for strict operations *with* FPStatus memory operand and non-strict operations without such an operand, we introduce a new flag mayAccessMemory. This implies that:
- If the instruction does not carry any memory operand, it is not actually considered to access memory.
- If the instruction *does* carry a memory operand, it is considered mayLoad and/or mayStore depending on that operand.
Common code provides a number of convenience multi-alternative pattern fragments like any_fadd that the target can use to match both strict and non-strict versions of a FP operation with a single DAG pattern. When matching the strict version, instruction selection code will copy over the FPStatus memory operand; when matching the non-strict version, there will be no such operand.
This patch implements the common-code changes as described above, and also converts the SystemZ target to make full use of them. There are test cases to verify that all the operations still match and generate the same set of instructions, as well as a test case to verify that strict operations are no longer scheduled inappropriately.