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>
* config/cris/cris.c (cris_rtx_costs): Blockify dangling else.
......
......@@ -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:
......
......@@ -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;
{
......
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.
......
/* 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));
......
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