diff options
author | Roger Sayle <roger@eyesopen.com> | 2003-02-22 04:16:18 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2003-02-22 04:16:18 +0000 |
commit | c0a47a612627d49755b9ef8225924c6df97eed43 (patch) | |
tree | b5839d7e929ffb3f98fcd9a26632868768f973ae /gcc | |
parent | 5b296d934079373d33f531b4384224e4023695ca (diff) | |
download | gcc-c0a47a612627d49755b9ef8225924c6df97eed43.zip gcc-c0a47a612627d49755b9ef8225924c6df97eed43.tar.gz gcc-c0a47a612627d49755b9ef8225924c6df97eed43.tar.bz2 |
fold-const.c (omit_one_operand): No longer static.
* fold-const.c (omit_one_operand): No longer static.
* tree.h (omit_one_operand): Prototype here.
(div_and_round_double): Keep fold-const.c prototypes together.
* builtins.c (builtin_mathfn_code): Handle binary built-in
funtions, such as "pow" and "atan2".
(fold_builtin): Optimize both pow(x,0.0) and pow(1.0,y) to 1.0.
Simplify optimizations using "type" the builtin's return type.
* gcc.dg/builtins-5.c: New test case.
From-SVN: r63273
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/builtins.c | 67 | ||||
-rw-r--r-- | gcc/fold-const.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtins-5.c | 45 | ||||
-rw-r--r-- | gcc/tree.h | 23 |
6 files changed, 125 insertions, 27 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6d6a6fb..5ddc7da 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2003-02-21 Roger Sayle <roger@eyesopen.com> + + * fold-const.c (omit_one_operand): No longer static. + * tree.h (omit_one_operand): Prototype here. + (div_and_round_double): Keep fold-const.c prototypes together. + * builtins.c (builtin_mathfn_code): Handle binary built-in + funtions, such as "pow" and "atan2". + (fold_builtin): Optimize both pow(x,0.0) and pow(1.0,y) to 1.0. + Simplify optimizations using "type" the builtin's return type. + 2003-02-22 Hans-Peter Nilsson <hp@axis.com> * config/cris/cris.c (cris_rtx_costs): Blockify dangling else. diff --git a/gcc/builtins.c b/gcc/builtins.c index ebb9835..81e38db 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -4515,10 +4515,30 @@ builtin_mathfn_code (t) arglist = TREE_OPERAND (t, 1); if (! arglist - || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE - || TREE_CHAIN (arglist)) + || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE) return END_BUILTINS; + arglist = TREE_CHAIN (arglist); + switch (DECL_FUNCTION_CODE (fndecl)) + { + case BUILT_IN_POW: + case BUILT_IN_POWF: + case BUILT_IN_POWL: + case BUILT_IN_ATAN2: + case BUILT_IN_ATAN2F: + case BUILT_IN_ATAN2L: + if (! arglist + || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE + || TREE_CHAIN (arglist)) + return END_BUILTINS; + break; + + default: + if (arglist) + return END_BUILTINS; + break; + } + return DECL_FUNCTION_CODE (fndecl); } @@ -4653,6 +4673,7 @@ fold_builtin (exp) { tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); tree arglist = TREE_OPERAND (exp, 1); + tree type = TREE_TYPE (TREE_TYPE (fndecl)); enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) @@ -4696,10 +4717,10 @@ fold_builtin (exp) REAL_VALUE_TYPE r, x; x = TREE_REAL_CST (arg); - mode = TYPE_MODE (TREE_TYPE (arg)); + mode = TYPE_MODE (type); if (real_sqrt (&r, mode, &x) || (!flag_trapping_math && !flag_errno_math)) - return build_real (TREE_TYPE (arg), r); + return build_real (type, r); } /* Optimize sqrt(exp(x)) = exp(x/2.0). */ @@ -4710,9 +4731,9 @@ fold_builtin (exp) || fcode == BUILT_IN_EXPL)) { tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); - arg = build (RDIV_EXPR, TREE_TYPE (arg), + arg = build (RDIV_EXPR, type, TREE_VALUE (TREE_OPERAND (arg, 1)), - build_real (TREE_TYPE (arg), dconst2)); + build_real (type, dconst2)); arglist = build_tree_list (NULL_TREE, arg); return build_function_call_expr (expfn, arglist); } @@ -4729,7 +4750,7 @@ fold_builtin (exp) /* Optimize exp(0.0) = 1.0. */ if (real_zerop (arg)) - return build_real (TREE_TYPE (arg), dconst1); + return build_real (type, dconst1); /* Optimize exp(log(x)) = x. */ fcode = builtin_mathfn_code (arg); @@ -4751,7 +4772,7 @@ fold_builtin (exp) /* Optimize log(1.0) = 0.0. */ if (real_onep (arg)) - return build_real (TREE_TYPE (arg), dconst0); + return build_real (type, dconst0); /* Optimize log(exp(x)) = x. */ fcode = builtin_mathfn_code (arg); @@ -4769,31 +4790,49 @@ fold_builtin (exp) { tree logfn = build_function_call_expr (fndecl, TREE_OPERAND (arg, 1)); - return fold (build (RDIV_EXPR, TREE_TYPE (arg), logfn, - build_real (TREE_TYPE (arg), dconst2))); + return fold (build (RDIV_EXPR, type, logfn, + build_real (type, dconst2))); } } break; + case BUILT_IN_POW: + case BUILT_IN_POWF: + case BUILT_IN_POWL: + if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) + { + tree arg0 = TREE_VALUE (arglist); + tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); + + /* Optimize pow(x,0.0) = 1.0. */ + if (real_zerop (arg1)) + return omit_one_operand (type, build_real (type, dconst1), arg0); + + /* Optimize pow(1.0,y) = 1.0. */ + if (real_onep (arg0)) + return omit_one_operand (type, build_real (type, dconst1), arg1); + } + break; + case BUILT_IN_INF: case BUILT_IN_INFF: case BUILT_IN_INFL: - return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl)), true); + return fold_builtin_inf (type, true); case BUILT_IN_HUGE_VAL: case BUILT_IN_HUGE_VALF: case BUILT_IN_HUGE_VALL: - return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl)), false); + return fold_builtin_inf (type, false); case BUILT_IN_NAN: case BUILT_IN_NANF: case BUILT_IN_NANL: - return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), true); + return fold_builtin_nan (arglist, type, true); case BUILT_IN_NANS: case BUILT_IN_NANSF: case BUILT_IN_NANSL: - return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), false); + return fold_builtin_nan (arglist, type, false); case BUILT_IN_FLOOR: case BUILT_IN_FLOORF: diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 6b50a86..48c3683 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -81,7 +81,6 @@ static int truth_value_p PARAMS ((enum tree_code)); static int operand_equal_for_comparison_p PARAMS ((tree, tree, tree)); static int twoval_comparison_p PARAMS ((tree, tree *, tree *, int *)); static tree eval_subst PARAMS ((tree, tree, tree, tree, tree)); -static tree omit_one_operand PARAMS ((tree, tree, tree)); static tree pedantic_omit_one_operand PARAMS ((tree, tree, tree)); static tree distribute_bit_expr PARAMS ((enum tree_code, tree, tree, tree)); static tree make_bit_field_ref PARAMS ((tree, tree, int, int, int)); @@ -2256,7 +2255,7 @@ eval_subst (arg, old0, new0, old1, new1) If OMITTED has side effects, we must evaluate it. Otherwise, just do the conversion of RESULT to TYPE. */ -static tree +tree omit_one_operand (type, result, omitted) tree type, result, omitted; { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7251223..f68ad3a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-02-21 Roger Sayle <roger@eyesopen.com> + + * gcc.dg/builtins-5.c: New test case. + 2003-02-22 Hans-Peter Nilsson <hp@axis.com> * gcc.dg/asmreg-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/builtins-5.c b/gcc/testsuite/gcc.dg/builtins-5.c new file mode 100644 index 0000000..a056812 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtins-5.c @@ -0,0 +1,45 @@ +/* Copyright (C) 2003 Free Software Foundation. + + Verify that built-in math function constant folding of constant + arguments is correctly performed by the by the compiler. + + Written by Roger Sayle, 20th February 2003. */ + +/* { dg-do link } */ +/* { dg-options "-O2" } */ + +extern void link_error(void); + +void test(double x) +{ + if (pow (x, 0.0) != 1.0) + link_error (); + if (pow (1.0, x) != 1.0) + link_error (); +} + +void testf(float x) +{ + if (powf (x, 0.0f) != 1.0f) + link_error (); + if (powf (1.0f, x) != 1.0f) + link_error (); +} + +void testl(long double x) +{ + if (powl (x, 0.0l) != 1.0l) + link_error (); + if (powl (1.0l, x) != 1.0l) + link_error (); +} + +int main() +{ + test (0.0); + testf (0.0f); + testl (0.0l); + + return 0; +} + @@ -2902,7 +2902,19 @@ extern void rrotate_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT, unsigned int, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *)); + +extern int div_and_round_double PARAMS ((enum tree_code, int, + unsigned HOST_WIDE_INT, + HOST_WIDE_INT, + unsigned HOST_WIDE_INT, + HOST_WIDE_INT, + unsigned HOST_WIDE_INT *, + HOST_WIDE_INT *, + unsigned HOST_WIDE_INT *, + HOST_WIDE_INT *)); + extern int operand_equal_p PARAMS ((tree, tree, int)); +extern tree omit_one_operand PARAMS ((tree, tree, tree)); extern tree invert_truthvalue PARAMS ((tree)); /* In builtins.c */ @@ -3050,17 +3062,6 @@ extern void variable_section PARAMS ((tree, int)); enum tls_model decl_tls_model PARAMS ((tree)); enum symbol_visibility decl_visibility PARAMS ((tree)); -/* In fold-const.c */ -extern int div_and_round_double PARAMS ((enum tree_code, int, - unsigned HOST_WIDE_INT, - HOST_WIDE_INT, - unsigned HOST_WIDE_INT, - HOST_WIDE_INT, - unsigned HOST_WIDE_INT *, - HOST_WIDE_INT *, - unsigned HOST_WIDE_INT *, - HOST_WIDE_INT *)); - /* In stmt.c */ extern void emit_nop PARAMS ((void)); extern void expand_computed_goto PARAMS ((tree)); |