We have a global 1/2 and a cached 1/3, but recalculate 1/4, 1/6 and 1/9
each time we need them.  That seems a bit arbitrary and makes the folding
code more noisy (especially once it's moved to match.pd).

This patch caches the other three constants too.  Bootstrapped &
regression-tested on x86_64-linux-gnu.  OK to install?

Thanks,
Richard

gcc/
        * real.h (dconst_quarter, dconst_sixth, dconst_ninth): New macros.
        (dconst_quarter_ptr, dconst_sixth_ptr, dconst_ninth_ptr): Declare.
        * real.c (CACHED_FRACTION(: New helper macro.
        (dconst_third_ptr): Use it.
        (dconst_quarter_ptr, dconst_sixth_ptr, dconst_ninth_ptr): New.
        * builtins.c (fold_builtin_sqrt): Use dconst_quarter and
        dconst_sixth.
        (fold_builtin_cbrt): Use dconst_sixth and dconst_ninth.

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 1751b37..63724b9 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -7743,20 +7743,10 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type)
       if (powfn)
        {
          tree arg0 = CALL_EXPR_ARG (arg, 0);
-         tree tree_root;
-         /* The inner root was either sqrt or cbrt.  */
-         /* This was a conditional expression but it triggered a bug
-            in Sun C 5.5.  */
-         REAL_VALUE_TYPE dconstroot;
-         if (BUILTIN_SQRT_P (fcode))
-           dconstroot = dconsthalf;
-         else
-           dconstroot = dconst_third ();
-
-         /* Adjust for the outer root.  */
-         SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
-         tree_root = build_real_truncate (type, dconstroot);
-         return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
+         tree arg1 = (BUILTIN_SQRT_P (fcode)
+                      ? build_real (type, dconst_quarter ())
+                      : build_real_truncate (type, dconst_sixth ()));
+         return build_call_expr_loc (loc, powfn, 2, arg0, arg1);
        }
     }
 
@@ -7816,11 +7806,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
          if (powfn)
            {
              tree arg0 = CALL_EXPR_ARG (arg, 0);
-             tree tree_root;
-             REAL_VALUE_TYPE dconstroot = dconst_third ();
-
-             SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
-             tree_root = build_real_truncate (type, dconstroot);
+             tree tree_root = build_real_truncate (type, dconst_sixth ());
              return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
            }
        }
@@ -7835,12 +7821,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
 
              if (powfn)
                {
-                 tree tree_root;
-                 REAL_VALUE_TYPE dconstroot;
-
-                 real_arithmetic (&dconstroot, MULT_EXPR,
-                                   dconst_third_ptr (), dconst_third_ptr ());
-                 tree_root = build_real_truncate (type, dconstroot);
+                 tree tree_root = build_real_truncate (type, dconst_ninth ());
                  return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
                }
            }
diff --git a/gcc/real.c b/gcc/real.c
index c1ff78d..78f3623 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -2379,21 +2379,26 @@ dconst_e_ptr (void)
   return &value;
 }
 
-/* Returns the special REAL_VALUE_TYPE corresponding to 1/3.  */
-
-const REAL_VALUE_TYPE *
-dconst_third_ptr (void)
-{
-  static REAL_VALUE_TYPE value;
-
-  /* Initialize mathematical constants for constant folding builtins.
-     These constants need to be given to at least 160 bits precision.  */
-  if (value.cl == rvc_zero)
-    {
-      real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (3));
-    }
-  return &value;
-}
+/* Returns a cached REAL_VALUE_TYPE corresponding to 1/n, for various n.  */
+
+#define CACHED_FRACTION(NAME, N)                                       \
+  const REAL_VALUE_TYPE *                                              \
+  NAME (void)                                                          \
+  {                                                                    \
+    static REAL_VALUE_TYPE value;                                      \
+                                                                       \
+    /* Initialize mathematical constants for constant folding builtins.        
\
+       These constants need to be given to at least 160 bits           \
+       precision.  */                                                  \
+    if (value.cl == rvc_zero)                                          \
+      real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (N));   \
+    return &value;                                                     \
+  }
+
+CACHED_FRACTION (dconst_third_ptr, 3)
+CACHED_FRACTION (dconst_quarter_ptr, 4)
+CACHED_FRACTION (dconst_sixth_ptr, 6)
+CACHED_FRACTION (dconst_ninth_ptr, 9)
 
 /* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2).  */
 
diff --git a/gcc/real.h b/gcc/real.h
index 455d853..5d8c92c 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -414,15 +414,21 @@ extern REAL_VALUE_TYPE dconst2;
 extern REAL_VALUE_TYPE dconstm1;
 extern REAL_VALUE_TYPE dconsthalf;
 
-#define dconst_e()  (*dconst_e_ptr ())
-#define dconst_third()  (*dconst_third_ptr ())
-#define dconst_sqrt2()  (*dconst_sqrt2_ptr ())
+#define dconst_e() (*dconst_e_ptr ())
+#define dconst_third() (*dconst_third_ptr ())
+#define dconst_quarter() (*dconst_quarter_ptr ())
+#define dconst_sixth() (*dconst_sixth_ptr ())
+#define dconst_ninth() (*dconst_ninth_ptr ())
+#define dconst_sqrt2() (*dconst_sqrt2_ptr ())
 
 /* Function to return the real value special constant 'e'.  */
 extern const REAL_VALUE_TYPE * dconst_e_ptr (void);
 
-/* Returns the special REAL_VALUE_TYPE corresponding to 1/3.  */
-extern const REAL_VALUE_TYPE * dconst_third_ptr (void);
+/* Returns a cached REAL_VALUE_TYPE corresponding to 1/n, for various n.  */
+extern const REAL_VALUE_TYPE *dconst_third_ptr (void);
+extern const REAL_VALUE_TYPE *dconst_quarter_ptr (void);
+extern const REAL_VALUE_TYPE *dconst_sixth_ptr (void);
+extern const REAL_VALUE_TYPE *dconst_ninth_ptr (void);
 
 /* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2).  */
 extern const REAL_VALUE_TYPE * dconst_sqrt2_ptr (void);

Reply via email to