diff options
author | Richard Biener <rguenther@suse.de> | 2016-02-18 14:34:59 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2016-02-18 14:34:59 +0000 |
commit | f003579e9cdd2f28f7a5b0985d541c2f375bbf11 (patch) | |
tree | 9b569cfccff7bab4a18c307b6ab2aca8d8a3955f /gcc/fold-const.c | |
parent | cc7ab8a232b31a8e1edf7c3b3bd586798fa583ba (diff) | |
download | gcc-f003579e9cdd2f28f7a5b0985d541c2f375bbf11.zip gcc-f003579e9cdd2f28f7a5b0985d541c2f375bbf11.tar.gz gcc-f003579e9cdd2f28f7a5b0985d541c2f375bbf11.tar.bz2 |
re PR middle-end/69553 (Optimizations O1/O2 makes std::array value incorrect when passed to function)
2016-02-18 Richard Biener <rguenther@suse.de>
PR middle-end/69553
* fold-const.c (operand_equal_p): Properly compare offsets for
IMAGPART_EXPR and ARRAY_REF.
* g++.dg/torture/pr69553.C: New testcase.
From-SVN: r233520
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 4992f4b..41c652e 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3008,8 +3008,15 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) flags &= ~OEP_ADDRESS_OF; return OP_SAME (0); - case REALPART_EXPR: case IMAGPART_EXPR: + /* Require the same offset. */ + if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)), + TYPE_SIZE (TREE_TYPE (arg1)), + flags & ~OEP_ADDRESS_OF)) + return 0; + + /* Fallthru. */ + case REALPART_EXPR: case VIEW_CONVERT_EXPR: return OP_SAME (0); @@ -3049,17 +3056,29 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) case ARRAY_REF: case ARRAY_RANGE_REF: - /* Operands 2 and 3 may be null. - Compare the array index by value if it is constant first as we - may have different types but same value here. */ if (!OP_SAME (0)) return 0; flags &= ~OEP_ADDRESS_OF; + /* Compare the array index by value if it is constant first as we + may have different types but same value here. */ return ((tree_int_cst_equal (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1)) || OP_SAME (1)) && OP_SAME_WITH_NULL (2) - && OP_SAME_WITH_NULL (3)); + && OP_SAME_WITH_NULL (3) + /* Compare low bound and element size as with OEP_ADDRESS_OF + we have to account for the offset of the ref. */ + && (TREE_TYPE (TREE_OPERAND (arg0, 0)) + == TREE_TYPE (TREE_OPERAND (arg1, 0)) + || (operand_equal_p (array_ref_low_bound + (CONST_CAST_TREE (arg0)), + array_ref_low_bound + (CONST_CAST_TREE (arg1)), flags) + && operand_equal_p (array_ref_element_size + (CONST_CAST_TREE (arg0)), + array_ref_element_size + (CONST_CAST_TREE (arg1)), + flags)))); case COMPONENT_REF: /* Handle operand 2 the same as for ARRAY_REF. Operand 0 |