Alpha encodes the rounding mode in the instruction itself, so honoring a
rounding mode chosen at run time requires the /d qualifier, which takes the
mode from the FPCR.  alpha_fprm defaulted to ALPHA_FPRM_NORM and was only
ever changed by an explicit -mfp-rounding-mode, so -frounding-math emitted
statically rounded instructions and fesetround was silently ignored.

Default alpha_fprm to ALPHA_FPRM_DYN when -frounding-math is in effect and
-mfp-rounding-mode was not given, leaving both ordinary code generation and
an explicit -mfp-rounding-mode unaffected.  The VAX floating-point
instructions have no dynamic rounding qualifier, so -mfloat-vax keeps the
static default.

This fixes the execution failures of 
gcc.dg/torture/fp-uint64-convert-double-1.c,
fp-uint64-convert-double-2.c and fp-double-convert-float-1.c.

gcc/ChangeLog:

        * config/alpha/alpha.cc (alpha_option_override): Set alpha_fprm to
        ALPHA_FPRM_DYN when flag_rounding_math is set, -mfp-rounding-mode
        was not given explicitly and -mfloat-vax is not in effect.
        * doc/invoke.texi (Alpha Options): Document the default rounding
        mode and its interaction with -frounding-math.
---
 gcc/config/alpha/alpha.cc |  6 ++++++
 gcc/doc/invoke.texi       | 13 ++++++++++---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git ./gcc/config/alpha/alpha.cc ./gcc/config/alpha/alpha.cc
index 90e4c21dd11..43443f82bac 100644
--- ./gcc/config/alpha/alpha.cc
+++ ./gcc/config/alpha/alpha.cc
@@ -435,6 +435,12 @@ alpha_option_override (void)
        error ("bad value %qs for %<-mfp-rounding-mode%> switch",
               alpha_fprm_string);
     }
+  else if (flag_rounding_math && !TARGET_FLOAT_VAX)
+    /* Honoring a rounding mode chosen at run time requires instructions
+       that take their rounding mode from the FPCR.  Without this, code
+       built with -frounding-math silently ignores fesetround.  The VAX
+       floating-point instructions have no dynamic rounding qualifier.  */
+    alpha_fprm = ALPHA_FPRM_DYN;
 
   if (alpha_fptm_string)
     {
diff --git ./gcc/doc/invoke.texi ./gcc/doc/invoke.texi
index 7c65c924271..623242ff46e 100644
--- ./gcc/doc/invoke.texi
+++ ./gcc/doc/invoke.texi
@@ -26293,11 +26293,18 @@ Chopped rounding mode.  Floating-point numbers are 
rounded towards zero.
 @item d
 Dynamic rounding mode.  A field in the floating-point control register
 (@var{fpcr}, see Alpha architecture reference manual) controls the
-rounding mode in effect.  The C library initializes this register for
-rounding towards plus infinity.  Thus, unless your program modifies the
-@var{fpcr}, @samp{d} corresponds to round towards plus infinity.
+rounding mode in effect.  The C library initializes this register, so
+unless your program modifies the @var{fpcr}, for example through
+@code{fesetround}, @samp{d} corresponds to the rounding mode the C
+library selected.
 @end table
 
+The default is @samp{n}, except that @samp{d} is the default when
+@option{-frounding-math} is in effect, since only dynamic rounding can
+honor a rounding mode chosen at run time.  This does not apply to
+@option{-mfloat-vax}, whose instructions have no dynamic rounding
+qualifier.
+
 @opindex mtrap-precision
 @item -mtrap-precision=@var{trap-precision}
 In the Alpha architecture, floating-point traps are imprecise.  This
-- 
2.54.0

Reply via email to