Commit a1a6e271 by Rafael Avila de Espindola Committed by Rafael Espindola

fold-canst.c (tree_call_nonnegative_warnv_p): New.

2008-04-08  Rafael Espindola  <espindola@google.com>

	* fold-canst.c (tree_call_nonnegative_warnv_p): New.
	(tree_invalid_nonnegative_warnv_p): Use tree_call_nonnegative_warnv_p.
	* tree.h (tree_call_nonnegative_warnv_p): New.

From-SVN: r134102
parent 581edf92
2008-04-08 Rafael Espindola <espindola@google.com>
* fold-canst.c (tree_call_nonnegative_warnv_p): New.
(tree_invalid_nonnegative_warnv_p): Use tree_call_nonnegative_warnv_p.
* tree.h (tree_call_nonnegative_warnv_p): New.
2008-04-08 Jan Hubicka <jh@suse.cz>
* function.c (free_after_compilation): Clear out regno_reg_rtx
......
......@@ -14002,50 +14002,9 @@ tree_single_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
*STRICT_OVERFLOW_P. */
bool
tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
tree_call_nonnegative_warnv_p (enum tree_code code, tree type, tree fndecl,
tree arg0, tree arg1, bool *strict_overflow_p)
{
enum tree_code code = TREE_CODE (t);
if (TYPE_UNSIGNED (TREE_TYPE (t)))
return true;
switch (code)
{
case TARGET_EXPR:
{
tree temp = TARGET_EXPR_SLOT (t);
t = TARGET_EXPR_INITIAL (t);
/* If the initializer is non-void, then it's a normal expression
that will be assigned to the slot. */
if (!VOID_TYPE_P (t))
return tree_expr_nonnegative_warnv_p (t, strict_overflow_p);
/* Otherwise, the initializer sets the slot in some way. One common
way is an assignment statement at the end of the initializer. */
while (1)
{
if (TREE_CODE (t) == BIND_EXPR)
t = expr_last (BIND_EXPR_BODY (t));
else if (TREE_CODE (t) == TRY_FINALLY_EXPR
|| TREE_CODE (t) == TRY_CATCH_EXPR)
t = expr_last (TREE_OPERAND (t, 0));
else if (TREE_CODE (t) == STATEMENT_LIST)
t = expr_last (t);
else
break;
}
if ((TREE_CODE (t) == MODIFY_EXPR
|| TREE_CODE (t) == GIMPLE_MODIFY_STMT)
&& GENERIC_TREE_OPERAND (t, 0) == temp)
return tree_expr_nonnegative_warnv_p (GENERIC_TREE_OPERAND (t, 1),
strict_overflow_p);
return false;
}
case CALL_EXPR:
{
tree fndecl = get_callee_fndecl (t);
if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
switch (DECL_FUNCTION_CODE (fndecl))
{
......@@ -14071,9 +14030,9 @@ tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
CASE_FLT_FN (BUILT_IN_SQRT):
/* sqrt(-0.0) is -0.0. */
if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (t))))
if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
return true;
return tree_expr_nonnegative_warnv_p (CALL_EXPR_ARG (t, 0),
return tree_expr_nonnegative_warnv_p (arg0,
strict_overflow_p);
CASE_FLT_FN (BUILT_IN_ASINH):
......@@ -14108,49 +14067,49 @@ tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
CASE_FLT_FN (BUILT_IN_TANH):
CASE_FLT_FN (BUILT_IN_TRUNC):
/* True if the 1st argument is nonnegative. */
return tree_expr_nonnegative_warnv_p (CALL_EXPR_ARG (t, 0),
return tree_expr_nonnegative_warnv_p (arg0,
strict_overflow_p);
CASE_FLT_FN (BUILT_IN_FMAX):
/* True if the 1st OR 2nd arguments are nonnegative. */
return (tree_expr_nonnegative_warnv_p (CALL_EXPR_ARG (t, 0),
return (tree_expr_nonnegative_warnv_p (arg0,
strict_overflow_p)
|| (tree_expr_nonnegative_warnv_p (CALL_EXPR_ARG (t, 1),
|| (tree_expr_nonnegative_warnv_p (arg1,
strict_overflow_p)));
CASE_FLT_FN (BUILT_IN_FMIN):
/* True if the 1st AND 2nd arguments are nonnegative. */
return (tree_expr_nonnegative_warnv_p (CALL_EXPR_ARG (t, 0),
return (tree_expr_nonnegative_warnv_p (arg0,
strict_overflow_p)
&& (tree_expr_nonnegative_warnv_p (CALL_EXPR_ARG (t, 1),
&& (tree_expr_nonnegative_warnv_p (arg1,
strict_overflow_p)));
CASE_FLT_FN (BUILT_IN_COPYSIGN):
/* True if the 2nd argument is nonnegative. */
return tree_expr_nonnegative_warnv_p (CALL_EXPR_ARG (t, 1),
return tree_expr_nonnegative_warnv_p (arg1,
strict_overflow_p);
CASE_FLT_FN (BUILT_IN_POWI):
/* True if the 1st argument is nonnegative or the second
argument is an even integer. */
if (TREE_CODE (CALL_EXPR_ARG (t, 1)) == INTEGER_CST)
if (TREE_CODE (arg1) == INTEGER_CST)
{
tree arg1 = CALL_EXPR_ARG (t, 1);
tree arg1 = arg1;
if ((TREE_INT_CST_LOW (arg1) & 1) == 0)
return true;
}
return tree_expr_nonnegative_warnv_p (CALL_EXPR_ARG (t, 0),
return tree_expr_nonnegative_warnv_p (arg0,
strict_overflow_p);
CASE_FLT_FN (BUILT_IN_POW):
/* True if the 1st argument is nonnegative or the second
argument is an even integer valued real. */
if (TREE_CODE (CALL_EXPR_ARG (t, 1)) == REAL_CST)
if (TREE_CODE (arg1) == REAL_CST)
{
REAL_VALUE_TYPE c;
HOST_WIDE_INT n;
c = TREE_REAL_CST (CALL_EXPR_ARG (t, 1));
c = TREE_REAL_CST (arg1);
n = real_to_integer (&c);
if ((n & 1) == 0)
{
......@@ -14161,17 +14120,75 @@ tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
return true;
}
}
return tree_expr_nonnegative_warnv_p (CALL_EXPR_ARG (t, 0),
return tree_expr_nonnegative_warnv_p (arg0,
strict_overflow_p);
default:
break;
}
return tree_simple_nonnegative_warnv_p (TREE_CODE (t),
TREE_TYPE (t));
}
return tree_simple_nonnegative_warnv_p (code,
type);
}
/* Return true if T is known to be non-negative. If the return
value is based on the assumption that signed overflow is undefined,
set *STRICT_OVERFLOW_P to true; otherwise, don't change
*STRICT_OVERFLOW_P. */
bool
tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
{
enum tree_code code = TREE_CODE (t);
if (TYPE_UNSIGNED (TREE_TYPE (t)))
return true;
switch (code)
{
case TARGET_EXPR:
{
tree temp = TARGET_EXPR_SLOT (t);
t = TARGET_EXPR_INITIAL (t);
/* If the initializer is non-void, then it's a normal expression
that will be assigned to the slot. */
if (!VOID_TYPE_P (t))
return tree_expr_nonnegative_warnv_p (t, strict_overflow_p);
/* Otherwise, the initializer sets the slot in some way. One common
way is an assignment statement at the end of the initializer. */
while (1)
{
if (TREE_CODE (t) == BIND_EXPR)
t = expr_last (BIND_EXPR_BODY (t));
else if (TREE_CODE (t) == TRY_FINALLY_EXPR
|| TREE_CODE (t) == TRY_CATCH_EXPR)
t = expr_last (TREE_OPERAND (t, 0));
else if (TREE_CODE (t) == STATEMENT_LIST)
t = expr_last (t);
else
break;
}
if ((TREE_CODE (t) == MODIFY_EXPR
|| TREE_CODE (t) == GIMPLE_MODIFY_STMT)
&& GENERIC_TREE_OPERAND (t, 0) == temp)
return tree_expr_nonnegative_warnv_p (GENERIC_TREE_OPERAND (t, 1),
strict_overflow_p);
return false;
}
case CALL_EXPR:
{
tree arg0 = call_expr_nargs (t) > 0 ? CALL_EXPR_ARG (t, 0) : NULL_TREE;
tree arg1 = call_expr_nargs (t) > 1 ? CALL_EXPR_ARG (t, 1) : NULL_TREE;
return tree_call_nonnegative_warnv_p (TREE_CODE (t),
TREE_TYPE (t),
get_callee_fndecl (t),
arg0,
arg1,
strict_overflow_p);
}
case COMPOUND_EXPR:
case MODIFY_EXPR:
case GIMPLE_MODIFY_STMT:
......
......@@ -4846,6 +4846,9 @@ extern bool tree_binary_nonnegative_warnv_p (enum tree_code, tree, tree, tree,
bool *);
extern bool tree_single_nonnegative_warnv_p (tree t, bool *strict_overflow_p);
extern bool tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p);
extern bool tree_call_nonnegative_warnv_p (enum tree_code code, tree, tree,
tree, tree, bool *);
extern bool tree_expr_nonzero_warnv_p (tree, bool *);
extern bool fold_real_zero_addition_p (const_tree, const_tree, int);
......
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