/* Fold a constant sub-tree into a single node for C-compiler
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
/* If both types don't have the same signedness, then we can't consider
them equal. We must check this before the STRIP_NOPS calls
- because they may change the signedness of the arguments. */
- if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1)))
+ because they may change the signedness of the arguments. As pointers
+ strictly don't have a signedness, require either two pointers or
+ two non-pointers as well. */
+ if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1))
+ || POINTER_TYPE_P (TREE_TYPE (arg0)) != POINTER_TYPE_P (TREE_TYPE (arg1)))
return 0;
/* If both types don't have the same precision, then it is not safe
/* Two conversions are equal only if signedness and modes match. */
switch (TREE_CODE (arg0))
{
- case NOP_EXPR:
- case CONVERT_EXPR:
+ CASE_CONVERT:
case FIX_TRUNC_EXPR:
if (TYPE_UNSIGNED (TREE_TYPE (arg0))
!= TYPE_UNSIGNED (TREE_TYPE (arg1)))
&& operand_equal_p (TREE_OPERAND (arg0, 1),
TREE_OPERAND (arg1, 0), flags));
+ case COND_EXPR:
+ return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
+
default:
return 0;
}
/* We are interested in the bare arrangement of bits, so strip everything
that doesn't affect the machine mode. However, record the type of the
outermost expression if it may matter below. */
- if (TREE_CODE (exp) == NOP_EXPR
- || TREE_CODE (exp) == CONVERT_EXPR
+ if (CONVERT_EXPR_P (exp)
|| TREE_CODE (exp) == NON_LVALUE_EXPR)
outer_type = TREE_TYPE (exp);
STRIP_NOPS (exp);
exp = arg0;
continue;
- case NOP_EXPR: case NON_LVALUE_EXPR: case CONVERT_EXPR:
+ CASE_CONVERT: case NON_LVALUE_EXPR:
if (TYPE_PRECISION (arg0_type) > TYPE_PRECISION (exp_type))
break;
fold_convert (ctype, c), 0);
break;
- case CONVERT_EXPR: case NON_LVALUE_EXPR: case NOP_EXPR:
+ CASE_CONVERT: case NON_LVALUE_EXPR:
/* If op0 is an expression ... */
if ((COMPARISON_CLASS_P (op0)
|| UNARY_CLASS_P (op0)
|| BINARY_CLASS_P (op0)
|| VL_EXP_CLASS_P (op0)
|| EXPRESSION_CLASS_P (op0))
- /* ... and is unsigned, and its type is smaller than ctype,
- then we cannot pass through as widening. */
- && ((TYPE_UNSIGNED (TREE_TYPE (op0))
+ /* ... and has wrapping overflow, and its type is smaller
+ than ctype, then we cannot pass through as widening. */
+ && ((TYPE_OVERFLOW_WRAPS (TREE_TYPE (op0))
&& ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
&& TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
- && (GET_MODE_SIZE (TYPE_MODE (ctype))
- > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
+ && (TYPE_PRECISION (ctype)
+ > TYPE_PRECISION (TREE_TYPE (op0))))
/* ... or this is a truncation (t is narrower than op0),
then we cannot pass through this narrowing. */
- || (GET_MODE_SIZE (TYPE_MODE (type))
- < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))
+ || (TYPE_PRECISION (type)
+ < TYPE_PRECISION (TREE_TYPE (op0)))
/* ... or signedness changes for division or modulus,
then we cannot pass through this conversion. */
|| (code != MULT_EXPR
tree arg0_inner;
tree inner_type, outer_type;
- if (TREE_CODE (arg0) != NOP_EXPR
- && TREE_CODE (arg0) != CONVERT_EXPR)
+ if (!CONVERT_EXPR_P (arg0))
return NULL_TREE;
outer_type = TREE_TYPE (arg0);
return NULL_TREE;
if (TREE_CODE (arg1) != INTEGER_CST
- && !((TREE_CODE (arg1) == NOP_EXPR
- || TREE_CODE (arg1) == CONVERT_EXPR)
+ && !(CONVERT_EXPR_P (arg1)
&& TREE_TYPE (TREE_OPERAND (arg1, 0)) == inner_type))
return NULL_TREE;
- if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
+ if ((TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
+ || POINTER_TYPE_P (inner_type) != POINTER_TYPE_P (outer_type))
&& code != NE_EXPR
&& code != EQ_EXPR)
return NULL_TREE;
return fold_convert (type, op0);
return NULL_TREE;
- case NOP_EXPR:
+ CASE_CONVERT:
case FLOAT_EXPR:
- case CONVERT_EXPR:
case FIX_TRUNC_EXPR:
if (TREE_TYPE (op0) == type)
return op0;
TREE_OPERAND (op0, 1));
/* Handle cases of two conversions in a row. */
- if (TREE_CODE (op0) == NOP_EXPR
- || TREE_CODE (op0) == CONVERT_EXPR)
+ if (CONVERT_EXPR_P (op0))
{
tree inside_type = TREE_TYPE (TREE_OPERAND (op0, 0));
tree inter_type = TREE_TYPE (op0);
/* Convert (T)(x & c) into (T)x & (T)c, if c is an integer
constants (if x has signed type, the sign bit cannot be set
- in c). This folds extension into the BIT_AND_EXPR. */
- if (INTEGRAL_TYPE_P (type)
- && TREE_CODE (type) != BOOLEAN_TYPE
+ in c). This folds extension into the BIT_AND_EXPR.
+ ??? We don't do it for BOOLEAN_TYPE or ENUMERAL_TYPE because they
+ very likely don't have maximal range for their precision and this
+ transformation effectively doesn't preserve non-maximal ranges. */
+ if (TREE_CODE (type) == INTEGER_TYPE
&& TREE_CODE (op0) == BIT_AND_EXPR
&& TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
{
if (INTEGRAL_TYPE_P (type)
&& TREE_CODE (op0) == BIT_NOT_EXPR
&& INTEGRAL_TYPE_P (TREE_TYPE (op0))
- && (TREE_CODE (TREE_OPERAND (op0, 0)) == NOP_EXPR
- || TREE_CODE (TREE_OPERAND (op0, 0)) == CONVERT_EXPR)
+ && CONVERT_EXPR_P (TREE_OPERAND (op0, 0))
&& TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op0)))
{
tem = TREE_OPERAND (TREE_OPERAND (op0, 0), 0);
return fold_convert (type, op0);
/* Strip inner integral conversions that do not change the precision. */
- if ((TREE_CODE (op0) == NOP_EXPR
- || TREE_CODE (op0) == CONVERT_EXPR)
+ if (CONVERT_EXPR_P (op0)
&& (INTEGRAL_TYPE_P (TREE_TYPE (op0))
|| POINTER_TYPE_P (TREE_TYPE (op0)))
&& (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))
}
if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
- && (TREE_CODE (arg0) == NOP_EXPR
- || TREE_CODE (arg0) == CONVERT_EXPR))
+ && CONVERT_EXPR_P (arg0))
{
/* If we are widening one operand of an integer comparison,
see if the other operand is similarly being widened. Perhaps we
safe for every expression, except for a comparison expression
because its signedness is derived from its operands. So, in
the latter case, only strip conversions that don't change the
- signedness.
+ signedness. MIN_EXPR/MAX_EXPR also need signedness of arguments
+ preserved.
Note that this is done as an internal manipulation within the
constant folder, in order to find the simplest representation
cases, the appropriate type conversions should be put back in
the tree that will get out of the constant folder. */
- if (kind == tcc_comparison)
+ if (kind == tcc_comparison || code == MIN_EXPR || code == MAX_EXPR)
{
STRIP_SIGN_NOPS (arg0);
STRIP_SIGN_NOPS (arg1);
{
if (strict_overflow_p)
fold_overflow_warning (("assuming signed overflow does not occur "
- "when simplifying modulos"),
+ "when simplifying modulus"),
WARN_STRICT_OVERFLOW_MISC);
return fold_convert (type, tem);
}
if ((code == LT_EXPR || code == GE_EXPR)
&& TYPE_UNSIGNED (TREE_TYPE (arg0))
- && (TREE_CODE (arg1) == NOP_EXPR
- || TREE_CODE (arg1) == CONVERT_EXPR)
+ && CONVERT_EXPR_P (arg1)
&& TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
&& integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
return
switch (TREE_CODE (t))
{
- case SSA_NAME:
- /* Query VRP to see if it has recorded any information about
- the range of this object. */
- return ssa_name_nonnegative_p (t);
-
case INTEGER_CST:
return tree_int_cst_sgn (t) >= 0;
bool sub_strict_overflow_p;
switch (TREE_CODE (t))
{
- case SSA_NAME:
- /* Query VRP to see if it has recorded any information about
- the range of this object. */
- return ssa_name_nonzero_p (t);
-
case INTEGER_CST:
return !integer_zerop (t);
with constant folding. (E.g. suppose the lower bound is 1,
and its mode is QI. Without the conversion,l (ARRAY
+(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1))
- +INDEX), which becomes (ARRAY+255+INDEX). Opps!) */
+ +INDEX), which becomes (ARRAY+255+INDEX). Oops!) */
if (! integer_zerop (low_bound))
index = size_diffop (index, fold_convert (sizetype, low_bound));