On Wed, Feb 20, 2019 at 06:29:06PM +0000, Joseph Myers wrote:
> On Wed, 20 Feb 2019, Jakub Jelinek wrote:
> 
> > +      /* 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.  */
> 
> Note that I think such issues are pervasive in MPC; it's not just that one 
> function.  MPFR is generally careful about using a larger exponent range 
> internally (there might still be issues with very big exponents where they 
> aren't handled specially to avoid internal overflow, but the maximum MPFR 
> exponent range is very large); MPC doesn't generally try to handle 
> restricted exponent ranges.

I've added E.g. to the comment, is that sufficient, or are you aware of some
mpc computation that will misbehave even with those 2 * max_exp + 2 etc.
ranges?

Bootstrapped/regtested now on x86_64-linux and i686-linux successfully and
various people tested it on other targets, ok for trunk?

2019-02-20  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/88074
        PR middle-end/89415
        * toplev.c (do_compile): Double the emin/emax exponents to workaround
        buggy mpc_norm.

        * gcc.dg/pr88074-2.c: New test.

--- gcc/toplev.c.jj     2019-02-20 10:00:49.290492694 +0100
+++ gcc/toplev.c        2019-02-20 14:04:27.037769362 +0100
@@ -2173,8 +2173,12 @@ do_compile ()
                  max_exp = fmt->emax;
              }
          }
-      if (mpfr_set_emin (min_exp)
-         || mpfr_set_emax (max_exp))
+      /* 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.  */
--- gcc/testsuite/gcc.dg/pr88074-2.c.jj 2019-02-20 14:10:07.109140297 +0100
+++ gcc/testsuite/gcc.dg/pr88074-2.c    2019-02-20 14:09:46.696478179 +0100
@@ -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;
+}


        Jakub

Reply via email to