summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r--gcc/tree-ssa-ccp.c50
1 files changed, 10 insertions, 40 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 3b275babf66..0ea8675ae6b 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -1853,8 +1853,8 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
if (t)
return t;
- /* Add in any offset from a PLUS_EXPR. */
- if (TREE_CODE (base) == PLUS_EXPR)
+ /* Add in any offset from a POINTER_PLUS_EXPR. */
+ if (TREE_CODE (base) == POINTER_PLUS_EXPR)
{
tree offset2;
@@ -1863,7 +1863,8 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
return NULL_TREE;
base = TREE_OPERAND (base, 0);
- offset = int_const_binop (PLUS_EXPR, offset, offset2, 1);
+ offset = fold_convert (sizetype,
+ int_const_binop (PLUS_EXPR, offset, offset2, 1));
}
if (TREE_CODE (base) == ADDR_EXPR)
@@ -1923,7 +1924,7 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
}
-/* A subroutine of fold_stmt_r. EXPR is a PLUS_EXPR.
+/* A subroutine of fold_stmt_r. EXPR is a POINTER_PLUS_EXPR.
A quaint feature extant in our address arithmetic is that there
can be hidden type changes here. The type of the result need
@@ -1932,7 +1933,7 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
What we're after here is an expression of the form
(T *)(&array + const)
where the cast doesn't actually exist, but is implicit in the
- type of the PLUS_EXPR. We'd like to turn this into
+ type of the POINTER_PLUS_EXPR. We'd like to turn this into
&array[x]
which may be able to propagate further. */
@@ -1944,18 +1945,9 @@ maybe_fold_stmt_addition (tree expr)
tree ptr_type = TREE_TYPE (expr);
tree ptd_type;
tree t;
- bool subtract = (TREE_CODE (expr) == MINUS_EXPR);
- /* We're only interested in pointer arithmetic. */
- if (!POINTER_TYPE_P (ptr_type))
- return NULL_TREE;
- /* Canonicalize the integral operand to op1. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (op0)))
- {
- if (subtract)
- return NULL_TREE;
- t = op0, op0 = op1, op1 = t;
- }
+ gcc_assert (TREE_CODE (expr) == POINTER_PLUS_EXPR);
+
/* It had better be a constant. */
if (TREE_CODE (op1) != INTEGER_CST)
return NULL_TREE;
@@ -2001,32 +1993,11 @@ maybe_fold_stmt_addition (tree expr)
array_idx = int_const_binop (MULT_EXPR, array_idx, elt_size, 0);
/* Update the operands for the next round, or for folding. */
- /* If we're manipulating unsigned types, then folding into negative
- values can produce incorrect results. Particularly if the type
- is smaller than the width of the pointer. */
- if (subtract
- && TYPE_UNSIGNED (TREE_TYPE (op1))
- && tree_int_cst_lt (array_idx, op1))
- return NULL;
- op1 = int_const_binop (subtract ? MINUS_EXPR : PLUS_EXPR,
+ op1 = int_const_binop (PLUS_EXPR,
array_idx, op1, 0);
- subtract = false;
op0 = array_obj;
}
- /* If we weren't able to fold the subtraction into another array reference,
- canonicalize the integer for passing to the array and component ref
- simplification functions. */
- if (subtract)
- {
- if (TYPE_UNSIGNED (TREE_TYPE (op1)))
- return NULL;
- op1 = fold_unary (NEGATE_EXPR, TREE_TYPE (op1), op1);
- /* ??? In theory fold should always produce another integer. */
- if (op1 == NULL || TREE_CODE (op1) != INTEGER_CST)
- return NULL;
- }
-
ptd_type = TREE_TYPE (ptr_type);
/* At which point we can try some of the same things as for indirects. */
@@ -2116,8 +2087,7 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
recompute_tree_invariant_for_addr_expr (expr);
return NULL_TREE;
- case PLUS_EXPR:
- case MINUS_EXPR:
+ case POINTER_PLUS_EXPR:
t = walk_tree (&TREE_OPERAND (expr, 0), fold_stmt_r, data, NULL);
if (t)
return t;