aboutsummaryrefslogtreecommitdiff
path: root/gcc/toplev.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/toplev.c')
-rw-r--r--gcc/toplev.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/gcc/toplev.c b/gcc/toplev.c
index b066bcc7229..bdf021e828a 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -2110,6 +2110,34 @@ do_compile ()
else
int_n_enabled_p[i] = false;
+ /* Initialize mpfrs exponent range. This is important to get
+ underflow/overflow in a reasonable timeframe. */
+ machine_mode mode;
+ int min_exp = -1;
+ int max_exp = 1;
+ FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
+ if (SCALAR_FLOAT_MODE_P (mode))
+ {
+ const real_format *fmt = REAL_MODE_FORMAT (mode);
+ if (fmt)
+ {
+ /* fmt->emin - fmt->p + 1 should be enough but the
+ back-and-forth dance in real_to_decimal_for_mode we
+ do for checking fails due to rounding effects then. */
+ if ((fmt->emin - fmt->p) < min_exp)
+ min_exp = fmt->emin - fmt->p;
+ if (fmt->emax > max_exp)
+ max_exp = fmt->emax;
+ }
+ }
+ /* E.g. mpc_norm assumes it can square a number without bothering with
+ with range scaling, so until that is fixed, double the minimum
+ and maximum exponents, plus add some buffer for arithmetics
+ on the squared numbers. */
+ if (mpfr_set_emin (2 * (min_exp - 1))
+ || mpfr_set_emax (2 * (max_exp + 1)))
+ sorry ("mpfr not configured to handle all float modes");
+
/* Set up the back-end if requested. */
if (!no_backend)
backend_init ();