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

--- Comment #16 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Eric Botcazou from comment #15)
> But I agree that the origin seems to be in the SRA pass.

In particular SRA does scalarize A50b:



-  MEM[(struct c391002_3__electronics_module & {ref-all})&A50b].the_command =
0;
+  SR.50_111 = 0;
...

this replacement has no use

   VIEW_CONVERT_EXPR<struct p__B51b__T52b>(A50b) = A53b;
+  SR.49_126 = MEM <void (*ada__tags__prim_ptr) (void)[1:1] * {ref-all}>
[(struct p__T48b * {ref-all})&A50b];
+  SR.50_127 = MEM <unsigned char> [(struct p__T48b * {ref-all})&A50b + 48B];
+  SR.51_128 = MEM <integer> [(struct p__T48b * {ref-all})&A50b + 52B];

we re-load SR.50

+  MEM <unsigned char> [(struct p__T43b * {ref-all})&A50b + 48B] = SR.50_127;
+  MEM <integer> [(struct p__T43b * {ref-all})&A50b + 52B] = SR.51_133;
   VIEW_CONVERT_EXPR<struct p__T43b>(A63b) = MEM[(struct p__T43b *
{ref-all})&A50b];

and for the next aggregate copy we restore it.  But this store does not
survive, DOM removes the redundant store:

Optimizing statement MEM <unsigned char> [(struct p__T43b * {ref-all})&A50b +
48B] = SR.50_127;
LKUP STMT MEM <unsigned char> [(struct p__T43b * {ref-all})&A50b + 48B] =
SR.50_127 with .MEM_135
LKUP STMT SR.50_127 = MEM <unsigned char> [(struct p__T43b * {ref-all})&A50b +
48B] with .MEM_135
FIND: SR.50_127

In particular I cannot find an access for the aggregate accesses in
VIEW_CONVERT_EXPR<struct p__B51b__T52b>(A50b) = A53b; - note that
the size of A53b is just 48 bytes, so that's not a def for .the_command,
but we reload that field to SR.50 here, but the earlier replacement
SR.50 = 0 should be still live!  But SSA rewrite then breaks this.

So SRA may not re-load replacements after a non-definition of a replacement.
It seems it assumes that all aggregate assignments are full defs?
In particular this VIEW_CONVERT_EXPR is size-changing (a thing that we
allow - unfortunately).

Reply via email to