Serge Pavlov via llvm-dev
2020-Mar-02 13:38 UTC
[llvm-dev] Should rint and nearbyint be always constrained?
Hi everyone, 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? Thanks, --Serge -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200302/3a8007ed/attachment.html>
Ulrich Weigand via llvm-dev
2020-Mar-02 13:57 UTC
[llvm-dev] Should rint and nearbyint be always constrained?
Serge Pavlov <sepavloff at gmail.com> wrote on 02.03.2020 14:38:48:> 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 intrinsicsrepresent. I'm not sure why this is an issue. Yes, these two intrinsics depend on the current rounding mode according to the C standard, and yes, LLVM in default mode assumes that the current rounding mode is the default rounding mode. But the same holds true for many other intrinsics and even the arithmetic IR operations like add. If you want to stop clang from making the default rounding mode assumption, you need to use the -frounding-math option (or one of its equivalents), which will cause clang to emit the corresponding constrained intrinsics instead, for those two as well all other affected intrinsics. I don't see why it would make sense to add another special case just for those two intrinsics ... Bye, Ulrich -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200302/5b63070f/attachment-0001.html>
Serge Pavlov via llvm-dev
2020-Mar-02 16:10 UTC
[llvm-dev] Should rint and nearbyint be always constrained?
> > I'm not sure why this is an issue. Yes, these two intrinsics depend > on the current rounding mode according to the C standard, and yes, > LLVM in default mode assumes that the current rounding mode is the > default rounding mode. But the same holds true for many other > intrinsics and even the arithmetic IR operations like add.Any other intrinsic, like `floor`, `round` etc has meaning at default rounding mode. But use of `rint` or `nearbyint` in default FP environment is strange, `roundeven` can be used instead. We could use more general intrinsics in all cases, as the special case of default environment is not of practical interest. There is another reason for special handling. Set of intrinsics includes things like `x86_sse_cvtss2si`. It is unlikely that all of them eventually get constrained counterpart. It looks more natural that such intrinsics are defined as accessing FP environment and can be optimized if the latter is default. These two intrinsics could be a good model for such cases. IIUC, splitting entities into constrained or non-constrained is a temporary solution, ideally they will merge into one entity. We could do it for some intrinsics now. Thanks, --Serge On Mon, Mar 2, 2020 at 8:58 PM Ulrich Weigand <Ulrich.Weigand at de.ibm.com> wrote:> Serge Pavlov <sepavloff at gmail.com> wrote on 02.03.2020 14:38:48: > > > 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. > > I'm not sure why this is an issue. Yes, these two intrinsics depend > on the current rounding mode according to the C standard, and yes, > LLVM in default mode assumes that the current rounding mode is the > default rounding mode. But the same holds true for many other > intrinsics and even the arithmetic IR operations like add. > > If you want to stop clang from making the default rounding mode > assumption, you need to use the -frounding-math option (or one > of its equivalents), which will cause clang to emit the corresponding > constrained intrinsics instead, for those two as well all other > affected intrinsics. > > I don't see why it would make sense to add another special case > just for those two intrinsics ... > > > Bye, > Ulrich > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200302/6fef3cf6/attachment.html>