https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117512
--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> --- And the change is in between TARGET_EXPR <D.2894, <<< Unknown tree: aggr_init_expr 4 foo D.2894 NON_LVALUE_EXPR <0> >>>> from cp_build_fold_indirect_ref and *&TARGET_EXPR <D.2894, <<< Unknown tree: aggr_init_expr 4 foo D.2894 NON_LVALUE_EXPR <0> >>>> from what we used to get before. That actually changed behavior even on #c4 variant with 1 * instead of 2 *, but with 1 * the original dump difference is: @@ -12,15 +12,15 @@ { struct A d; <<cleanup_point <<< Unknown tree: expr_stmt - (void) (d = *(*SAVE_EXPR <&TARGET_EXPR <D.2894, <<< Unknown tree: aggr_init_expr + (void) (d = *(TARGET_EXPR <D.2894, <<< Unknown tree: aggr_init_expr 4 foo D.2894 - 0 >>>>> = *(const struct A &) &e, (const struct A &) SAVE_EXPR <&TARGET_EXPR <D.2894, <<< Unknown tree: aggr_init_expr + 0 >>>> = *(const struct A &) &e, (const struct A &) &TARGET_EXPR <D.2894, <<< Unknown tree: aggr_init_expr 4 foo D.2894 - 0 >>>>>)) >>>>>; + 0 >>>>)) >>>>>; try { and it doesn't ICE, while with the extra alignment there is a MEM_REF involved: @@ -12,15 +12,15 @@ { struct A d; <<cleanup_point <<< Unknown tree: expr_stmt - (void) (d = MEM <unsigned char[4]> [(struct A *)SAVE_EXPR <&TARGET_EXPR <D.2894, <<< Unknown tree: aggr_init_expr + (void) (d = MEM <unsigned char[4]> [(struct A *)&TARGET_EXPR <D.2894, <<< Unknown tree: aggr_init_expr 4 foo D.2894 - 0 >>>>>] = MEM <unsigned char[4]> [(struct A *)(const struct A &) &e], TARGET_EXPR <D.2898, *(const struct A &) SAVE_EXPR <&TARGET_EXPR <D.2894, <<< Unknown tree: aggr_init_expr + 0 >>>>] = MEM <unsigned char[4]> [(struct A *)(const struct A &) &e], TARGET_EXPR <D.2894, <<< Unknown tree: aggr_init_expr 4 foo D.2894 - 0 >>>>>>) >>>>>; + 0 >>>>) >>>>>; try { and it does ICE.