re PR tree-optimization/88074 (g++ hangs on math expression)
authorRichard Biener <rguenther@suse.de>
Tue, 19 Feb 2019 12:46:48 +0000 (12:46 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 19 Feb 2019 12:46:48 +0000 (12:46 +0000)
2019-02-19  Richard Biener  <rguenther@suse.de>

        PR middle-end/88074
* toplev.c (do_compile): Initialize mpfr's exponent range
based on available float modes.

* gcc.dg/pr88074.c: New testcase.

From-SVN: r269015

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr88074.c [new file with mode: 0644]
gcc/toplev.c

index 7c4dbd2d56c65b82eb7bd9e0a7242a3e929f3ab8..3c9e17a5a97b04e560003ec769d7d02c7c77406c 100644 (file)
@@ -1,3 +1,9 @@
+2019-02-19  Richard Biener  <rguenther@suse.de>
+
+        PR middle-end/88074
+       * toplev.c (do_compile): Initialize mpfr's exponent range
+       based on available float modes.
+
 2019-02-19  Eric Botcazou  <ebotcazou@adacore.com>
 
        * rtlanal.c (get_initial_register_offset): Fall back to the estimate
index ab23500edd8cb9bb4bb49c2566f7156fabfc3ded..9e34716496a72000cb02b48ccb1c86ffebd034cf 100644 (file)
@@ -1,3 +1,8 @@
+2019-02-19  Richard Biener  <rguenther@suse.de>
+
+        PR middle-end/88074
+       * gcc.dg/pr88074.c: New testcase.
+
 2019-02-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/89303
diff --git a/gcc/testsuite/gcc.dg/pr88074.c b/gcc/testsuite/gcc.dg/pr88074.c
new file mode 100644 (file)
index 0000000..9f64cc1
--- /dev/null
@@ -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;
+}
index 0acfaaed3f731bfafdb9ae4e039cc740559f8b20..d8096ced677e8dc709fdd47dabfb5c8ab72e97f7 100644 (file)
@@ -2153,6 +2153,30 @@ 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;
+             }
+         }
+      if (mpfr_set_emin (min_exp)
+         || mpfr_set_emax (max_exp))
+       sorry ("mpfr not configured to handle all float modes");
+
       /* Set up the back-end if requested.  */
       if (!no_backend)
        backend_init ();