Commit c0a47a61 by Roger Sayle Committed by Roger Sayle

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
parent 5b296d93
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> 2003-02-22 Hans-Peter Nilsson <hp@axis.com>
* config/cris/cris.c (cris_rtx_costs): Blockify dangling else. * config/cris/cris.c (cris_rtx_costs): Blockify dangling else.
......
...@@ -4515,10 +4515,30 @@ builtin_mathfn_code (t) ...@@ -4515,10 +4515,30 @@ builtin_mathfn_code (t)
arglist = TREE_OPERAND (t, 1); arglist = TREE_OPERAND (t, 1);
if (! arglist if (! arglist
|| TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
|| TREE_CHAIN (arglist))
return END_BUILTINS; 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); return DECL_FUNCTION_CODE (fndecl);
} }
...@@ -4653,6 +4673,7 @@ fold_builtin (exp) ...@@ -4653,6 +4673,7 @@ fold_builtin (exp)
{ {
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1); tree arglist = TREE_OPERAND (exp, 1);
tree type = TREE_TYPE (TREE_TYPE (fndecl));
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
...@@ -4696,10 +4717,10 @@ fold_builtin (exp) ...@@ -4696,10 +4717,10 @@ fold_builtin (exp)
REAL_VALUE_TYPE r, x; REAL_VALUE_TYPE r, x;
x = TREE_REAL_CST (arg); x = TREE_REAL_CST (arg);
mode = TYPE_MODE (TREE_TYPE (arg)); mode = TYPE_MODE (type);
if (real_sqrt (&r, mode, &x) if (real_sqrt (&r, mode, &x)
|| (!flag_trapping_math && !flag_errno_math)) || (!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). */ /* Optimize sqrt(exp(x)) = exp(x/2.0). */
...@@ -4710,9 +4731,9 @@ fold_builtin (exp) ...@@ -4710,9 +4731,9 @@ fold_builtin (exp)
|| fcode == BUILT_IN_EXPL)) || fcode == BUILT_IN_EXPL))
{ {
tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); 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)), TREE_VALUE (TREE_OPERAND (arg, 1)),
build_real (TREE_TYPE (arg), dconst2)); build_real (type, dconst2));
arglist = build_tree_list (NULL_TREE, arg); arglist = build_tree_list (NULL_TREE, arg);
return build_function_call_expr (expfn, arglist); return build_function_call_expr (expfn, arglist);
} }
...@@ -4729,7 +4750,7 @@ fold_builtin (exp) ...@@ -4729,7 +4750,7 @@ fold_builtin (exp)
/* Optimize exp(0.0) = 1.0. */ /* Optimize exp(0.0) = 1.0. */
if (real_zerop (arg)) if (real_zerop (arg))
return build_real (TREE_TYPE (arg), dconst1); return build_real (type, dconst1);
/* Optimize exp(log(x)) = x. */ /* Optimize exp(log(x)) = x. */
fcode = builtin_mathfn_code (arg); fcode = builtin_mathfn_code (arg);
...@@ -4751,7 +4772,7 @@ fold_builtin (exp) ...@@ -4751,7 +4772,7 @@ fold_builtin (exp)
/* Optimize log(1.0) = 0.0. */ /* Optimize log(1.0) = 0.0. */
if (real_onep (arg)) if (real_onep (arg))
return build_real (TREE_TYPE (arg), dconst0); return build_real (type, dconst0);
/* Optimize log(exp(x)) = x. */ /* Optimize log(exp(x)) = x. */
fcode = builtin_mathfn_code (arg); fcode = builtin_mathfn_code (arg);
...@@ -4769,31 +4790,49 @@ fold_builtin (exp) ...@@ -4769,31 +4790,49 @@ fold_builtin (exp)
{ {
tree logfn = build_function_call_expr (fndecl, tree logfn = build_function_call_expr (fndecl,
TREE_OPERAND (arg, 1)); TREE_OPERAND (arg, 1));
return fold (build (RDIV_EXPR, TREE_TYPE (arg), logfn, return fold (build (RDIV_EXPR, type, logfn,
build_real (TREE_TYPE (arg), dconst2))); build_real (type, dconst2)));
} }
} }
break; 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_INF:
case BUILT_IN_INFF: case BUILT_IN_INFF:
case BUILT_IN_INFL: 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_VAL:
case BUILT_IN_HUGE_VALF: case BUILT_IN_HUGE_VALF:
case BUILT_IN_HUGE_VALL: 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_NAN:
case BUILT_IN_NANF: case BUILT_IN_NANF:
case BUILT_IN_NANL: 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_NANS:
case BUILT_IN_NANSF: case BUILT_IN_NANSF:
case BUILT_IN_NANSL: 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_FLOOR:
case BUILT_IN_FLOORF: case BUILT_IN_FLOORF:
......
...@@ -81,7 +81,6 @@ static int truth_value_p PARAMS ((enum tree_code)); ...@@ -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 operand_equal_for_comparison_p PARAMS ((tree, tree, tree));
static int twoval_comparison_p PARAMS ((tree, tree *, tree *, int *)); static int twoval_comparison_p PARAMS ((tree, tree *, tree *, int *));
static tree eval_subst PARAMS ((tree, tree, tree, tree, tree)); 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 pedantic_omit_one_operand PARAMS ((tree, tree, tree));
static tree distribute_bit_expr PARAMS ((enum tree_code, 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)); static tree make_bit_field_ref PARAMS ((tree, tree, int, int, int));
...@@ -2256,7 +2255,7 @@ eval_subst (arg, old0, new0, old1, new1) ...@@ -2256,7 +2255,7 @@ eval_subst (arg, old0, new0, old1, new1)
If OMITTED has side effects, we must evaluate it. Otherwise, just do If OMITTED has side effects, we must evaluate it. Otherwise, just do
the conversion of RESULT to TYPE. */ the conversion of RESULT to TYPE. */
static tree tree
omit_one_operand (type, result, omitted) omit_one_operand (type, result, omitted)
tree type, result, omitted; tree type, result, omitted;
{ {
......
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> 2003-02-22 Hans-Peter Nilsson <hp@axis.com>
* gcc.dg/asmreg-1.c: New test. * gcc.dg/asmreg-1.c: New test.
......
/* 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, ...@@ -2902,7 +2902,19 @@ extern void rrotate_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
HOST_WIDE_INT, unsigned int, HOST_WIDE_INT, unsigned int,
unsigned HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
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 int operand_equal_p PARAMS ((tree, tree, int));
extern tree omit_one_operand PARAMS ((tree, tree, tree));
extern tree invert_truthvalue PARAMS ((tree)); extern tree invert_truthvalue PARAMS ((tree));
/* In builtins.c */ /* In builtins.c */
...@@ -3050,17 +3062,6 @@ extern void variable_section PARAMS ((tree, int)); ...@@ -3050,17 +3062,6 @@ extern void variable_section PARAMS ((tree, int));
enum tls_model decl_tls_model PARAMS ((tree)); enum tls_model decl_tls_model PARAMS ((tree));
enum symbol_visibility decl_visibility 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 */ /* In stmt.c */
extern void emit_nop PARAMS ((void)); extern void emit_nop PARAMS ((void));
extern void expand_computed_goto PARAMS ((tree)); extern void expand_computed_goto PARAMS ((tree));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment