[llvm-dev] Should rint and nearbyint be always constrained?
Serge Pavlov via llvm-dev
llvm-dev at lists.llvm.org
Mon Mar 2 05:38:48 PST 2020
According to the current design an intrinsic call that depends on current
floating point environment (for example, rounding mode) or change it (for
example by raising FP exceptions) is represented by constrained intrinsics.
The latter have attached metadata that provide info about current FP
environment and have attribute `IntrInaccessibleMemOnly` that helps keeping
order of operations that access FP environment. Non-constrained intrinsics
are considered as working solely in default FP environment.
This approach has issues when applied to the intrinsics `rint` and
`nearbyint`. Value returned by either of these intrinsics depends on
current rounding mode. If they are considered as operation in default
environment, they would round only to nearest. It is by far not the meaning
of the standard C functions that these intrinsics represent.
So the unconstrained intrinsics `rint` and `nearbyint` seem to have little
use. The corresponding C functions are designed to work in non-default FP
environment. IEEE-754 counterpart of `rint` is `roundToIntegralExact`, it
also assumes dependency on current rounding mode. If these intrinsics are
used, FP environment most likely is not default.
We have at least two variants how to cope with this issue:
1. Add attribute `IntrInaccessibleMemOnly` to non-constrained `rint` and
`nearbyint`. It would allow correct ordering of the intrinsics with other
operations that access FP environment. In this case existing use of these
intrinsics in IR would be preserved but lowering should be changed anyway,
because corresponding nodes require chain argument.
2. Change declaration of `rint` and `nearbyint` so that they be the same as
their constrained versions are now. Availability of additional information
in metadata operands facilitate optimization of these intrinsics. These
intrinsics do not need separate constrained variants in this case. It would
change existing use of these intrinsics in IR.
The variant 2 seems to be better, as it does not introduce intrinsics that
are almost duplicates of existing ones and simplifies optimization. Changes
in IR should not be a big deal, as additional metadata operands are added
at the end of operand list, access to the existing operand should work.
Lowering should be changed in any case.
Does such change make sense? Are there any thoughts about implementation of
these two intrinsics?
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the llvm-dev