Serge Pavlov via llvm-dev
2020-Mar-05 17:48 UTC
[llvm-dev] Should rint and nearbyint be always constrained?
+cfe-dev as the discussion is now biased toward C standard. 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.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. >This is a strong statement (no pragma == default mode), we need to confirm it with proper references to the standard. If it is true and the code: float qqq(float x) { return nearbyint(x); } is really equivalent to: float qqq(float x) { return roundeven(x); } (in absence of 'pragma STD FENV_ACCESS), it is a fact that would be surprise for many user. Thanks, --Serge -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200306/49ead284/attachment.html>
Stephen Canon via llvm-dev
2020-Mar-05 17:56 UTC
[llvm-dev] Should rint and nearbyint be always constrained?
> On Mar 5, 2020, at 12:48 PM, Serge Pavlov <sepavloff at gmail.com> wrote: > > +cfe-dev as the discussion is now biased toward C standard. > > 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. > > 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. > > This is a strong statement (no pragma == default mode), we need to confirm it with proper references to the standard. If it is true and the code: > > float qqq(float x) { > return nearbyint(x); > } > > is really equivalent to: > > float qqq(float x) { > return roundeven(x); > } > > (in absence of 'pragma STD FENV_ACCESS), it is a fact that would be surprise for many user. > > Thanks, > —SergeC standard: _The FENV_ACCESS pragma_> 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."When set appropriately, the implementation may assume the default rounding mode is in effect."> … The default state ("on" or "off") for the pragma is implementation-defined.“`Off` is allowed to be the default mode.” In the presence of the default rounding mode, if you cannot access flags, nearbyint and roundeven have identical observable behavior. – Steve
Ulrich Weigand via llvm-dev
2020-Mar-05 18:15 UTC
[llvm-dev] Should rint and nearbyint be always constrained?
Serge Pavlov <sepavloff at gmail.com> wrote on 05.03.2020 18:48:33:>> 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. > > 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. > > This is a strong statement (no pragma == default mode), we need to > confirm it with proper references to the standard.That statement is made explicitly (multiple times) in the standard. Most specifically, C11 7.6.1.2 says: "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. 213)" where the footnote clarifies: "213) The purpose of the FENV_ACCESS pragma is to allow certain optimizations that could subvert flag tests and mode changes (e.g., global common subexpression elimination, code motion, and constant folding). In general, if the state of FENV_ACCESS is ‘‘off’’, the translator can assume that default modes are in effect and the flags are not tested." This explicitly says the if FENV_ACCESS is off, the compiler can assume that default modes (including default rounding modes) are in effect. Later, C11 7.6.1.2 goes on to say: "If part of a program tests floating-point status flags, sets floating-point control modes, or runs under non-default mode settings, but was translated with the state for the FENV_ACCESS pragma ‘‘off’’, the behavior is undefined." This reiterates explicitly what I said in my earlier email, that whenever any code is run that was compiled with FENV_ACCESS off, then at run-time the default modes (including default rounding mode) must be in effect, or else the behavior of the whole program is undefined. The upcoming C2x standard complicates the logic a little bit since it also introduces a FENV_ROUND pragma which may be used even in the absence of FENV_ACCESS. Nevertheless, if code is compiled without either of FENV_ACCESS or FENV_ROUND in effect, the compiler may still assume default modes.>If it is true and the code: > > float qqq(float x) { > return nearbyint(x); > } > > is really equivalent to: > > float qqq(float x) { > return roundeven(x); > } > > (in absence of 'pragma STD FENV_ACCESS), it is a fact that would be > surprise for many user.In the absence of FENV_ACCESS, the compiler can assume "default" modes. But what exactly those default modes are is implementation-defined, so nearbyint *may* be equivalent to roundeven if that's the default, but it may also be something else. Bye, Ulrich -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200305/4298db5b/attachment.html>
Serge Pavlov via llvm-dev
2020-Mar-06 05:58 UTC
[llvm-dev] Should rint and nearbyint be always constrained?
Let's summarize. The view point that absence of `pragma STDC FENV_ACCESS` means default floating point modes is based on two statements in the standard: 1. Description of `pragma STDC FENV_ACCESS` (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. 2. Footnote in the same paragraph: The purpose of the FENV_ACCESS pragma is to allow certain optimizations that could subvert flag tests and mode changes (e.g., global common subexpression elimination, code motion, and constant folding). In general, if the state of FENV_ACCESS is "off", the translator can assume that the flags are not tested, and that default modes are in effect, except where specified otherwise by an FENV_ROUND pragma. As for the statement 1, it can be understood differently: to run under non-default floating-point control modes, one must change these modes, and the pragma informs compiler about the change not about using. This interpretation is supported by the following statement in the same paragraph: If part of a program tests floating-point status flags or establishes non-default floating-point mode settings using any means other than the FENV_ROUND pragmas, but was translated with the state for the FENV_ACCESS pragma "off", the behavior is undefined. Hence if a function only queries about current rounding mode (as in the above example with nearbyint), there is no undefined behavior. This is either a conforming code, or an error, which requires diagnostics. In the former case the function `nearbyint` must behave as prescribed by the standard, - perform rounding according to current rounding mode. As for the statement 2, yes, it almost clearly votes for implicit default FP modes. "In general" is a bit confusing. May be "in particular" cases compiler cannot make such assumptions? I think this question should be addressed to language lawyers. There is a concern that such interpretation can break compatibility with existing programs. Even without `pragma STD FENV_ACCESS` users could use non-default rounding modes, - library functions provided barriers that prevented from undesirable code movement and programs worked as expected. Changing rules may cause negative consequences. Thanks, --Serge On Fri, Mar 6, 2020 at 1:28 AM Ulrich Weigand <Ulrich.Weigand at de.ibm.com> wrote:> Serge Pavlov <sepavloff at gmail.com> wrote on 05.03.2020 18:48:33: > > >> 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. > > > > 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. > > > > This is a strong statement (no pragma == default mode), we need to > > confirm it with proper references to the standard. > > That statement is made explicitly (multiple times) in the standard. > > Most specifically, C11 7.6.1.2 says: > > "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. 213)" > > where the footnote clarifies: > > "213) The purpose of the FENV_ACCESS pragma is to allow certain > optimizations that could subvert flag > tests and mode changes (e.g., global common subexpression elimination, > code motion, and constant > folding). In general, if the state of FENV_ACCESS is ‘‘off’’, the > translator can assume that default > modes are in effect and the flags are not tested." > > This explicitly says the if FENV_ACCESS is off, the compiler can assume > that default modes (including default rounding modes) are in effect. > > Later, C11 7.6.1.2 goes on to say: > > "If part of a program tests floating-point status flags, sets > floating-point control > modes, or runs under non-default mode settings, but was translated with > the state for the > FENV_ACCESS pragma ‘‘off’’, the behavior is undefined." > > This reiterates explicitly what I said in my earlier email, that whenever > any code is run that was compiled with FENV_ACCESS off, then at run-time > the default modes (including default rounding mode) must be in effect, or > else the behavior of the whole program is undefined. > > The upcoming C2x standard complicates the logic a little bit since it > also introduces a FENV_ROUND pragma which may be used even in the > absence of FENV_ACCESS. Nevertheless, if code is compiled without > either of FENV_ACCESS or FENV_ROUND in effect, the compiler may still > assume default modes. > > >If it is true and the code: > > > > float qqq(float x) { > > return nearbyint(x); > > } > > > > is really equivalent to: > > > > float qqq(float x) { > > return roundeven(x); > > } > > > > (in absence of 'pragma STD FENV_ACCESS), it is a fact that would be > > surprise for many user. > > In the absence of FENV_ACCESS, the compiler can assume "default" modes. > But what exactly those default modes are is implementation-defined, > so nearbyint *may* be equivalent to roundeven if that's the default, > but it may also be something else. > > Bye, > Ulrich > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200306/7b9fa3c2/attachment.html>