[llvm-dev] Should rint and nearbyint be always constrained?

Ulrich Weigand via llvm-dev llvm-dev at lists.llvm.org
Thu Mar 5 04:18:06 PST 2020

Serge Pavlov <sepavloff at gmail.com> wrote on 05.03.2020 06:57:08:

> Actually it is hard to rely on default FP environment in many cases.
> We know that a program starts with default FP state installed. But
> in other cases we generally cannot assume this. For example, can we
> assume default FP environment in this case?
> float qqq(float x) {
>   return nearbyint(x);
> }

I'm not sure what problem you see here.  In default mode, i.e.
when there is no "#pragma STDC FENV_ACCESS on" in effect,
then the compiler can always assume that the default rounding
mode is in effect.

> Depending on the answer compiler either generates non-constrained
> intrinsic or constrained. Result of `nearbyint` depends on current
> rounding mode, so this function accesses FP environment - it
> implicitly reads rounding mode. Shall user use `#pragma STDC
> FENV_ACCESS on` here? Actually no.

Well, if #pragma STDC FENV_ACCESS on is not in effect, that means
that the user has promised that at this point during execution,
we will *always* have the default FP environment.  As you quote:

> C standard (n2454):

> 7.6.1p2
> The FENV_ACCESS pragma provides a means to inform the implementation
> when a program might access the floating-point environment to test
> floating-point status flags or run under non-default
> floating-point control modes.

Note the last clause "*run under* non-default floating-point
control modes".  Every bit of code that can possibly ever run
while non-default FP modes are in effect *must* be compiled
with #pragma STDC FENV_ACCESS in effect, or else the whole
program has undefined behavior.

> 7.6p1
> A floating-point status flag is a
> system variable whose value is set (but never cleared) when a
> floating-point exception is raised, which
> occurs as a side effect of exceptional floating-point arithmetic to
> provide auxiliary information.

True but irrelevant, since 7.6.1p2 also talks about floating-point
*control modes*, which are collectively defined as:

A floating-point control mode is a system variable whose value may
be set by the user to affect the subsequent behavior of
floating-point arithmetic.

And this includes the rounding-mode controls.

> Not every access to FP environment requires `#pragma STDC
> FENV_ACCESS on`, only that which reads FP exception status or sets
> control modes. None occurs in the example above.
> So, even if `#pragma STDC FENV_ACCESS on` is absent we should not
> assume default FP environment in the case of functions that read
> control modes, including nearbyint and rint. They cannot assume
> default rounding mode and must be ordered relative to other
> instructions that may access FP environment. The scope of non-
> constrained intrinsics would be only initialization code, which
> seems to be marginal case.

This all seems to be based on a misreading of the standard.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200305/6bcbc008/attachment.html>

More information about the llvm-dev mailing list