diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-17 11:35:00 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-17 11:35:00 +0000 |
commit | 148ad152f2f6dad3160819dc6f471080d801d313 (patch) | |
tree | fa01127a0e850334616461c97e66569538042b89 /gcc/fold-const.c | |
parent | 3eef7b639006d074108fa13492583e7d40e4b909 (diff) | |
download | gcc-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.c | 33 |
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); } } |