Commit 8322b607 by Richard Biener Committed by Richard Biener

re PR tree-optimization/81884 (Invalid code generation with zero size arrays or…

re PR tree-optimization/81884 (Invalid code generation with zero size arrays or flexible array members)

2017-08-21  Richard Biener  <rguenther@suse.de>

	PR middle-end/81884
	* tree-ssa-alias.c (stmt_kills_ref_p): Handle array accesses
	at struct end conservatively when comparing common bases.

	* g++.dg/torture/pr81884.C: New testcase.

From-SVN: r251217
parent 5164293a
2017-08-21 Richard Biener <rguenther@suse.de>
PR middle-end/81884
* tree-ssa-alias.c (stmt_kills_ref_p): Handle array accesses
at struct end conservatively when comparing common bases.
2017-08-21 Richard Biener <rguenther@suse.de>
* tree-ssa-loop-im.c (struct lim_aux_data): Add ref index member.
(mem_ref_in_stmt): Remove.
(determine_max_movement): Use ref index to get at the reference.
......
2017-08-21 Richard Biener <rguenther@suse.de>
PR middle-end/81884
* g++.dg/torture/pr81884.C: New testcase.
2017-08-20 John David Anglin <danglin@gcc.gnu.org>
PR ipa/77732
......
/* { dg-do run } */
typedef unsigned long uint64_t;
struct value_t {
uint64_t _count;
value_t(uint64_t c) : _count(c) {}
};
struct X {
value_t eventTime;
uint64_t arr[0];
};
X* x;
__attribute__((noclone, noinline))
void initialize()
{
x->arr[0] = 11;
x->arr[1] = 12;
x->eventTime = value_t(10);
x->arr[2] = 13;
x->arr[3] = 14;
}
int main()
{
char buffer[sizeof(X) + sizeof(uint64_t)*4];
x = (X*)buffer;
x->eventTime = value_t(999);
x->arr[0] = 1;
x->arr[1] = 2;
x->arr[2] = 3;
x->arr[3] = 4;
initialize();
if (x->arr[0] != 11 || x->arr[1] != 12 || x->arr[2] != 13 || x->arr[3] != 14)
__builtin_abort ();
}
......@@ -2416,6 +2416,7 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
if (ref->ref)
{
tree base = ref->ref;
tree innermost_dropped_array_ref = NULL_TREE;
if (handled_component_p (base))
{
tree saved_lhs0 = NULL_TREE;
......@@ -2435,6 +2436,11 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
TREE_OPERAND (base, 0) = saved_base0;
if (res)
break;
/* Remember if we drop an array-ref that we need to
double-check not being at struct end. */
if (TREE_CODE (base) == ARRAY_REF
|| TREE_CODE (base) == ARRAY_RANGE_REF)
innermost_dropped_array_ref = base;
/* Otherwise drop handled components of the access. */
base = saved_base0;
}
......@@ -2443,15 +2449,22 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
TREE_OPERAND (lhs, 0) = saved_lhs0;
}
/* Finally check if the lhs has the same address and size as the
base candidate of the access. */
if (lhs == base
|| (((TYPE_SIZE (TREE_TYPE (lhs))
== TYPE_SIZE (TREE_TYPE (base)))
|| (TYPE_SIZE (TREE_TYPE (lhs))
&& TYPE_SIZE (TREE_TYPE (base))
&& operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)),
TYPE_SIZE (TREE_TYPE (base)), 0)))
&& operand_equal_p (lhs, base, OEP_ADDRESS_OF)))
base candidate of the access. Watch out if we have dropped
an array-ref that was at struct end, this means ref->ref may
be outside of the TYPE_SIZE of its base. */
if ((! innermost_dropped_array_ref
|| ! array_at_struct_end_p (innermost_dropped_array_ref))
&& (lhs == base
|| (((TYPE_SIZE (TREE_TYPE (lhs))
== TYPE_SIZE (TREE_TYPE (base)))
|| (TYPE_SIZE (TREE_TYPE (lhs))
&& TYPE_SIZE (TREE_TYPE (base))
&& operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)),
TYPE_SIZE (TREE_TYPE (base)),
0)))
&& operand_equal_p (lhs, base,
OEP_ADDRESS_OF
| OEP_MATCH_SIDE_EFFECTS))))
return true;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment