aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/builtins.c31
-rw-r--r--gcc/real.c35
-rw-r--r--gcc/real.h16
4 files changed, 48 insertions, 45 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index db6f1b6..fdef683 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2015-10-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * 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.
+
2015-10-06 Jeff Law <law@redhat.com>
PR tree-optimization/67816
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 89bea60..8fa3927 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -7742,20 +7742,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);
}
}
@@ -7815,11 +7805,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);
}
}
@@ -7834,12 +7820,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 49d6739..f633ffd 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -2395,21 +2395,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 1497279..706859b 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -409,15 +409,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);