[Bug tree-optimization/92152] [10 Regression] Wrong code (Resurrection of PR53663)

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Jan 21 12:56:00 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92152

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
In particular this testcase seems to be exactly what is tested in
gcc.dg/tree-ssa/alias-access-path-4.c:

struct a {int v1;
          int v2;};
struct b {struct a a[0];};
union c {struct b b;};

int
test2 (struct b *bptr1, union c *cptr, int i, int j)
{
  bptr1->a[i].v1=124;
  cptr->b.a[j].v1=1;
  return bptr1->a[i].v1;
}
/* { dg-final { scan-tree-dump-not "return 124" "optimized"} } */

and with my fix which looks like the following, this case breaks somehow...

diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 670676f20c3..55c28514d0b 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -1043,7 +1043,9 @@ aliasing_component_refs_p (tree ref1,
           end_struct_ref1 = base1;
        }
       if (TREE_CODE (base1) == VIEW_CONVERT_EXPR
-         || TREE_CODE (base1) == BIT_FIELD_REF)
+         || TREE_CODE (base1) == BIT_FIELD_REF
+         || (TREE_CODE (base1) == COMPONENT_REF
+             && TREE_CODE (TREE_TYPE (TREE_OPERAND (base1, 0))) ==
UNION_TYPE))
        ref1 = TREE_OPERAND (base1, 0);
       base1 = TREE_OPERAND (base1, 0);
     }
@@ -1057,7 +1059,9 @@ aliasing_component_refs_p (tree ref1,
          end_struct_ref2 = base2;
        }
       if (TREE_CODE (base2) == VIEW_CONVERT_EXPR
-         || TREE_CODE (base2) == BIT_FIELD_REF)
+         || TREE_CODE (base2) == BIT_FIELD_REF
+         || (TREE_CODE (base2) == COMPONENT_REF
+             && TREE_CODE (TREE_TYPE (TREE_OPERAND (base2, 0))) ==
UNION_TYPE))
        ref2 = TREE_OPERAND (base2, 0);
       base2 = TREE_OPERAND (base2, 0);
     }

this is because we later check

  if (compare_type_sizes (TREE_TYPE (ref2), type1) >= 0
      && (!end_struct_ref1
          || compare_type_sizes (TREE_TYPE (ref2),
                                 TREE_TYPE (end_struct_ref1)) >= 0)

and the union type is of size zero while the size of the array decays
to the size of struct a.  That looks like another latent issue to me.
Guess we may not really strip access paths this way if we rely on
sizes being those of the actual access (and the appearant size _shrinking_
when dropping part of the access path...).

IIRC we need to use the original ref for type size compares.  Even then
we end up comparing an integer against an aggregate and never enter
this check.

The code is really somewhat weird given the zero type sizes involved here
(both bases have zero size).

Honza?


More information about the Gcc-bugs mailing list