[Bug tree-optimization/93586] [10 Regression] wrong code at -O1 on x86_64-linux-gnu
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Feb 5 09:29:00 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93586
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |ASSIGNED
CC| |hubicka at gcc dot gnu.org
Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
DSE also happily removes the initializer parts for
int
main ()
{
char c[1][4][1] = { { { 7 }, { 0 }, { 5 }, { 5 } } };
for (int b = 0; b <= 3; b++)
if (c[0][b][0])
__builtin_abort ();
return 0;
}
the code contains commentary explicitely noting this situation:
/* If index is non-zero we need to check whether the reference
does not break the main invariant that bases are either
disjoint or equal. Consider the example:
unsigned char out[][1];
out[1]="a";
out[i][0];
Here bases out and out are same, but after removing the
[i] index, this invariant no longer holds, because
out[i] points to the middle of array out.
TODO: If size of type of the skipped reference is an integer
multiply of the size of type of the other reference this
invariant can be verified, but even then it is not completely
safe with !flag_strict_aliasing if the other reference
contains
unbounded array accesses.
See */
but it gets defeated by the accesses having c[0] in the base (but not in
the next dimension). Then we end up asking nonoverlapping_array_refs_p
for c[0] vs. c[0][b_2] which are not matching dimensions thus -1 is
returned. The next query is then for c[0][3] vs. c[0][b_2][0]
which returns 1(!? why's that not a mismatch)
and since there's no partial overlap we immeditately return success
(but seen_unmatched_ref_p is true)
/* Try to disambiguate matched arrays. */
for (unsigned int i = 0; i < narray_refs1; i++)
{
int cmp = nonoverlapping_array_refs_p (component_refs1.pop (),
component_refs2.pop ());
if (cmp == 1 && !partial_overlap)
{
++alias_stats
.nonoverlapping_refs_since_match_p_no_alias;
return 1;
}
partial_overlap = false;
if (cmp == -1)
seen_unmatched_ref_p = true;
}
The mismatch doesn't happen because sizeof(char[1]) == sizeof(char).
@@ -1291,6 +1292,11 @@ nonoverlapping_array_refs_p (tree ref1, tree ref2)
tree elmt_type1 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref1, 0)));
tree elmt_type2 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref2, 0)));
+ /* If one element is an array but not the other there's an obvious
+ mismatch in dimensionality. */
+ if ((TREE_CODE (elmt_type1) == ARRAY_TYPE)
+ != (TREE_CODE (elmt_type2) == ARRAY_TYPE))
+ return -1;
if (TREE_OPERAND (ref1, 3))
{
fixes that. But maybe we're not even supposed to call the function
with such cases? Honza?
More information about the Gcc-bugs
mailing list