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).