aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-02-18 14:34:59 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-02-18 14:34:59 +0000
commitf003579e9cdd2f28f7a5b0985d541c2f375bbf11 (patch)
tree9b569cfccff7bab4a18c307b6ab2aca8d8a3955f /gcc/fold-const.c
parentcc7ab8a232b31a8e1edf7c3b3bd586798fa583ba (diff)
downloadgcc-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.c29
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