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
This commit is contained in:
parent
cc7ab8a232
commit
f003579e9c
|
@ -1,3 +1,9 @@
|
|||
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.
|
||||
|
||||
2016-02-18 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR target/62254
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2016-02-18 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/69553
|
||||
* g++.dg/torture/pr69553.C: New testcase.
|
||||
|
||||
2016-02-18 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR target/62254
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// { dg-do run }
|
||||
template <typename _Tp, long _Nm> struct A {
|
||||
typedef _Tp _Type[_Nm];
|
||||
static _Tp &_S_ref(const _Type &p1, int p2) {
|
||||
return const_cast<_Tp &>(p1[p2]);
|
||||
}
|
||||
};
|
||||
template <typename _Tp, long _Nm> struct B {
|
||||
typedef A<_Tp, _Nm> _AT_Type;
|
||||
typename _AT_Type::_Type _M_elems;
|
||||
_Tp &operator[](long p1) const { return _AT_Type::_S_ref(_M_elems, p1); }
|
||||
};
|
||||
int t;
|
||||
void foo(int p1, int &p2) {
|
||||
if ((t & 1) == 0) {
|
||||
if (p1 != 1)
|
||||
__builtin_abort();
|
||||
if (p2 != 2)
|
||||
__builtin_abort();
|
||||
}
|
||||
t++;
|
||||
}
|
||||
__attribute__((noinline))
|
||||
void test1(const B<int, 2> &p1) { foo(p1[0], p1[1]); }
|
||||
void test(B<B<int, 2>, 2> &p1) {
|
||||
test1(p1[0]);
|
||||
test1(p1[1]);
|
||||
foo(p1[0][0], p1[0][1]);
|
||||
}
|
||||
int main() {
|
||||
B<B<int, 2>, 2> t;
|
||||
t[0][0] = 1;
|
||||
t[0][1] = 2;
|
||||
test(t);
|
||||
}
|
Loading…
Reference in New Issue