summaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-17 11:35:00 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-17 11:35:00 +0000
commit148ad152f2f6dad3160819dc6f471080d801d313 (patch)
treefa01127a0e850334616461c97e66569538042b89 /gcc/fold-const.c
parent3eef7b639006d074108fa13492583e7d40e4b909 (diff)
downloadgcc-148ad152f2f6dad3160819dc6f471080d801d313.tar.gz
2005-11-16 Richard Guenther <rguenther@suse.de>
PR middle-end/24851 * fold-const.c (extract_array_ref): Return byte offset in all cases. (fold_binary): Fold &x[a] CMP &x[b] to a*sizeof(*x) CMP b*sizeof(*x) to get correct overflow behavior. * gcc.c-torture/execute/pr24851.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107117 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0e74391fe51..343cfae6903 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -5537,7 +5537,8 @@ constant_boolean_node (int value, tree type)
offset to the appropriate trees. If there is no offset,
offset is set to NULL_TREE. Base will be canonicalized to
something you can get the element type from using
- TREE_TYPE (TREE_TYPE (base)). */
+ TREE_TYPE (TREE_TYPE (base)). Offset will be the offset
+ in bytes to the base. */
static bool
extract_array_ref (tree expr, tree *base, tree *offset)
@@ -5573,8 +5574,10 @@ extract_array_ref (tree expr, tree *base, tree *offset)
tree op0 = TREE_OPERAND (expr, 0);
if (TREE_CODE (op0) == ARRAY_REF)
{
+ tree idx = TREE_OPERAND (op0, 1);
*base = TREE_OPERAND (op0, 0);
- *offset = TREE_OPERAND (op0, 1);
+ *offset = fold_build2 (MULT_EXPR, TREE_TYPE (idx), idx,
+ array_ref_element_size (op0));
}
else
{
@@ -8888,25 +8891,21 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
&& extract_array_ref (arg1, &base1, &offset1)
&& operand_equal_p (base0, base1, 0))
{
- if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base0)))
- && integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base0)))))
- offset0 = NULL_TREE;
- if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base1)))
- && integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base1)))))
- offset1 = NULL_TREE;
+ /* Handle no offsets on both sides specially. */
if (offset0 == NULL_TREE
&& offset1 == NULL_TREE)
+ return fold_build2 (code, type, integer_zero_node,
+ integer_zero_node);
+
+ if (!offset0 || !offset1
+ || TREE_TYPE (offset0) == TREE_TYPE (offset1))
{
- offset0 = integer_zero_node;
- offset1 = integer_zero_node;
+ if (offset0 == NULL_TREE)
+ offset0 = build_int_cst (TREE_TYPE (offset1), 0);
+ if (offset1 == NULL_TREE)
+ offset1 = build_int_cst (TREE_TYPE (offset0), 0);
+ return fold_build2 (code, type, offset0, offset1);
}
- else if (offset0 == NULL_TREE)
- offset0 = build_int_cst (TREE_TYPE (offset1), 0);
- else if (offset1 == NULL_TREE)
- offset1 = build_int_cst (TREE_TYPE (offset0), 0);
-
- if (TREE_TYPE (offset0) == TREE_TYPE (offset1))
- return fold_build2 (code, type, offset0, offset1);
}
}