summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-05 13:37:15 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-05 13:37:15 +0000
commit4c9156537c50c4de823aa9d4d1c8f611abf01782 (patch)
tree1e4a42eb36f306f1da5a94e136fcbde03c213296
parentf7e1363cd20b685d73a5437cc19fb38cbf291069 (diff)
downloadgcc-4c9156537c50c4de823aa9d4d1c8f611abf01782.tar.gz
Add a build_real_truncate helper function
...which simplifies the match.pd patterns I'm about to add. Bootstrapped & regression-tested on x86_64-linux-gnu. gcc/ * real.h (build_real_truncate): Declare. * tree.c (build_real_truncate): New function. (strip_float_extensions): Use it. * builtins.c (fold_builtin_cabs, fold_builtin_sqrt, fold_builtin_cbrt) (fold_builtin_hypot, fold_builtin_pow): Likewise. * match.pd: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@228483 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/builtins.c43
-rw-r--r--gcc/match.pd6
-rw-r--r--gcc/real.h3
-rw-r--r--gcc/tree.c10
5 files changed, 37 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bd7626f5998..5c782900fd3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2015-10-05 Richard Sandiford <richard.sandiford@arm.com>
+
+ * real.h (build_real_truncate): Declare.
+ * tree.c (build_real_truncate): New function.
+ (strip_float_extensions): Use it.
+ * builtins.c (fold_builtin_cabs, fold_builtin_sqrt, fold_builtin_cbrt)
+ (fold_builtin_hypot, fold_builtin_pow): Likewise.
+ * match.pd: Likewise.
+
2015-10-05 James Greenhalgh <james.greenhalgh@arm.com>
Jiong Wang <jiong.wang@arm.com>
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 9a81a182de4..89bea60a09d 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -7592,12 +7592,10 @@ fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
if (flag_unsafe_math_optimizations
&& operand_equal_p (real, imag, OEP_PURE_SAME))
{
- const REAL_VALUE_TYPE sqrt2_trunc
- = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
STRIP_NOPS (real);
return fold_build2_loc (loc, MULT_EXPR, type,
- fold_build1_loc (loc, ABS_EXPR, type, real),
- build_real (type, sqrt2_trunc));
+ fold_build1_loc (loc, ABS_EXPR, type, real),
+ build_real_truncate (type, dconst_sqrt2 ()));
}
}
@@ -7756,8 +7754,7 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type)
/* Adjust for the outer root. */
SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
- dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
- tree_root = build_real (type, dconstroot);
+ tree_root = build_real_truncate (type, dconstroot);
return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
}
}
@@ -7804,11 +7801,9 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
if (BUILTIN_EXPONENT_P (fcode))
{
tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
- const REAL_VALUE_TYPE third_trunc =
- real_value_truncate (TYPE_MODE (type), dconst_third ());
arg = fold_build2_loc (loc, MULT_EXPR, type,
- CALL_EXPR_ARG (arg, 0),
- build_real (type, third_trunc));
+ CALL_EXPR_ARG (arg, 0),
+ build_real_truncate (type, dconst_third ()));
return build_call_expr_loc (loc, expfn, 1, arg);
}
@@ -7824,8 +7819,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
REAL_VALUE_TYPE dconstroot = dconst_third ();
SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
- dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
- tree_root = build_real (type, dconstroot);
+ tree_root = build_real_truncate (type, dconstroot);
return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
}
}
@@ -7845,8 +7839,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
real_arithmetic (&dconstroot, MULT_EXPR,
dconst_third_ptr (), dconst_third_ptr ());
- dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
- tree_root = build_real (type, dconstroot);
+ tree_root = build_real_truncate (type, dconstroot);
return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
}
}
@@ -7862,10 +7855,8 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
if (tree_expr_nonnegative_p (arg00))
{
tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
- const REAL_VALUE_TYPE dconstroot
- = real_value_truncate (TYPE_MODE (type), dconst_third ());
- tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01,
- build_real (type, dconstroot));
+ tree c = build_real_truncate (type, dconst_third ());
+ tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01, c);
return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
}
}
@@ -8391,13 +8382,9 @@ fold_builtin_hypot (location_t loc, tree fndecl,
/* hypot(x,x) -> fabs(x)*sqrt(2). */
if (flag_unsafe_math_optimizations
&& operand_equal_p (arg0, arg1, OEP_PURE_SAME))
- {
- const REAL_VALUE_TYPE sqrt2_trunc
- = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
- return fold_build2_loc (loc, MULT_EXPR, type,
- fold_build1_loc (loc, ABS_EXPR, type, arg0),
- build_real (type, sqrt2_trunc));
- }
+ return fold_build2_loc (loc, MULT_EXPR, type,
+ fold_build1_loc (loc, ABS_EXPR, type, arg0),
+ build_real_truncate (type, dconst_sqrt2 ()));
return NULL_TREE;
}
@@ -8529,10 +8516,8 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
tree arg = CALL_EXPR_ARG (arg0, 0);
if (tree_expr_nonnegative_p (arg))
{
- const REAL_VALUE_TYPE dconstroot
- = real_value_truncate (TYPE_MODE (type), dconst_third ());
- tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
- build_real (type, dconstroot));
+ tree c = build_real_truncate (type, dconst_third ());
+ tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, c);
return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
}
}
diff --git a/gcc/match.pd b/gcc/match.pd
index 8842e047d50..9962b0ae355 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2189,8 +2189,7 @@ along with GCC; see the file COPYING3. If not see
{
CASE_FLT_FN (BUILT_IN_EXP):
/* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
- x = build_real (type, real_value_truncate (TYPE_MODE (type),
- dconst_e ()));
+ x = build_real_truncate (type, dconst_e ());
break;
CASE_FLT_FN (BUILT_IN_EXP2):
/* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
@@ -2226,8 +2225,7 @@ along with GCC; see the file COPYING3. If not see
break;
CASE_FLT_FN (BUILT_IN_CBRT):
/* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
- x = build_real (type, real_value_truncate (TYPE_MODE (type),
- dconst_third ()));
+ x = build_real_truncate (type, dconst_third ());
break;
default:
gcc_unreachable ();
diff --git a/gcc/real.h b/gcc/real.h
index ecbe563abd6..149727953de 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -440,6 +440,9 @@ bool real_can_shorten_arithmetic (machine_mode, machine_mode);
/* In tree.c: wrap up a REAL_VALUE_TYPE in a tree node. */
extern tree build_real (tree, REAL_VALUE_TYPE);
+/* Likewise, but first truncate the value to the type. */
+extern tree build_real_truncate (tree, REAL_VALUE_TYPE);
+
/* Calculate R as X raised to the integer exponent N in mode MODE. */
extern bool real_powi (REAL_VALUE_TYPE *, machine_mode,
const REAL_VALUE_TYPE *, HOST_WIDE_INT);
diff --git a/gcc/tree.c b/gcc/tree.c
index bfcf3746da2..f78a2c26cd7 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1877,6 +1877,14 @@ build_real (tree type, REAL_VALUE_TYPE d)
return v;
}
+/* Like build_real, but first truncate D to the type. */
+
+tree
+build_real_truncate (tree type, REAL_VALUE_TYPE d)
+{
+ return build_real (type, real_value_truncate (TYPE_MODE (type), d));
+}
+
/* Return a new REAL_CST node whose type is TYPE
and whose value is the integer value of the INTEGER_CST node I. */
@@ -12093,7 +12101,7 @@ strip_float_extensions (tree exp)
&& exact_real_truncate (TYPE_MODE (double_type_node), &orig))
type = double_type_node;
if (type)
- return build_real (type, real_value_truncate (TYPE_MODE (type), orig));
+ return build_real_truncate (type, orig);
}
if (!CONVERT_EXPR_P (exp))