@@ -1981,6 +1981,36 @@ 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 (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ 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 ();
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+#include <complex.h>
+
+int main()
+{
+ _Complex double x;
+ __real x = 3.091e+8;
+ __imag x = -4.045e+8;
+ /* This used to spend huge amounts of compile-time inside mpc. */
+ volatile _Complex double y = ctan (x);
+ return 0;
+}
@@ -0,0 +1,17 @@
+/* PR middle-end/88074 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-add-options float128 } */
+/* { dg-require-effective-target float128 } */
+/* { dg-final { scan-tree-dump-not "link_error " "optimized" } } */
+
+extern void link_error (void);
+int
+main ()
+{
+ if (((__FLT128_MAX__ * 0.5 + __FLT128_MAX__ * 0.5i)
+ / (__FLT128_MAX__ * 0.25 + __FLT128_MAX__ * 0.25i))
+ != (_Complex _Float128) 2)
+ link_error ();
+ return 0;
+}