https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104529
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |needs-bisection Status|UNCONFIRMED |NEW Last reconfirmed| |2022-02-15 CC| |jamborm at gcc dot gnu.org, | |jason at redhat dot com, | |rguenth at gcc dot gnu.org Target Milestone|--- |12.0 Ever confirmed|0 |1 --- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- I think this is SRA no longer forwarding the constant init to the aggregate copy. In GCC 11: --- t.C.121t.cplxlower1 2022-02-15 08:41:16.572229246 +0100 +++ t.C.122t.sra 2022-02-15 08:41 @@ -1,8 +1,31 @@ ;; Function foo (_Z3foov, funcdef_no=883, decl_uid=19435, cgraph_uid=172, symbol_order=181) +No longer having address taken: D.19477 +No longer having address taken: test +Created a replacement for D.19477 offset: 0, size: 8: SR.62D.21182 +Created a replacement for D.19477 offset: 8, size: 8: SR.63D.21183 +Created a replacement for D.19477 offset: 16, size: 8: SR.64D.21184 +Created a replacement for D.19477 offset: 24, size: 8: SR.65D.21185 +Created a replacement for D.19477 offset: 32, size: 8: SR.66D.21186 +Created a replacement for D.19477 offset: 40, size: 8: SR.67D.21187 +Removing load: MEM <unsigned char[6]> [(char * {ref-all})_41] = MEM <unsigned char[6]> [(char * {ref-all})&D.19477]; + +Symbols to be put in SSA form +{ D.20917 D.21182 D.21183 D.21184 D.21185 D.21186 D.21187 } +Incremental SSA update started at block: 0 +Number of blocks in CFG: 5 +Number of blocks to update: 4 ( 80%) + + size_t foo () { + unsigned char SR.67; + unsigned char SR.66; + unsigned char SR.65; + unsigned char SR.64; + unsigned char SR.63; + unsigned char SR.62; unsigned char * D.21173; const size_type __n; const unsigned char * const __l$_M_array; @@ -15,12 +38,12 @@ <bb 2> [local count: 536870913]: MEM[(struct param *)&test].k = 48; - D.19477[0] = 255; - D.19477[1] = 0; - D.19477[2] = 0; - D.19477[3] = 0; - D.19477[4] = 0; - D.19477[5] = 0; + SR.62_42 = 255; + SR.63_11 = 0; + SR.64_12 = 0; + SR.65_61 = 0; + SR.66_55 = 0; + SR.67_57 = 0; MEM[(struct _Vector_impl_data *)&test + 8B] ={v} {CLOBBER}; MEM[(struct _Vector_impl_data *)&test + 8B]._M_start = 0B; MEM[(struct _Vector_impl_data *)&test + 8B]._M_finish = 0B; @@ -31,14 +54,18 @@ MEM[(struct vector *)&test + 8B].D.19426._M_impl.D.18739._M_start = _41; _36 = _41 + 6; MEM[(struct vector *)&test + 8B].D.19426._M_impl.D.18739._M_end_of_storage = _36; - MEM <unsigned char[6]> [(char * {ref-all})_41] = MEM <unsigned char[6]> [(char * {ref-all})&D.19477]; + MEM <unsigned char[6]> [(char * {ref-all})_41][0] = SR.62_42; + MEM <unsigned char[6]> [(char * {ref-all})_41][1] = SR.63_11; + MEM <unsigned char[6]> [(char * {ref-all})_41][2] = SR.64_12; + MEM <unsigned char[6]> [(char * {ref-all})_41][3] = SR.65_61; + MEM <unsigned char[6]> [(char * {ref-all})_41][4] = SR.66_55; + MEM <unsigned char[6]> [(char * {ref-all})_41][5] = SR.67_57; while GCC 12 has: --- t.C.126t.cplxlower1 2022-02-15 08:44:29.602672246 +0100 +++ t.C.127t.sra 2022-02-15 08:44:29.602672246 +0100 @@ -1,6 +1,8 @@ ;; Function foo (_Z3foov, funcdef_no=1040, decl_uid=23047, cgraph_uid=176, symbol_order=189) +No longer having address taken: D.23106 +No longer having address taken: test size_t foo () { struct param test[1]; and the SRA IL is const unsigned char D.23106[6]; struct vector * _1; unsigned char * _43; <bb 2> [local count: 536870913]: MEM[(struct param *)&test] = {}; MEM[(struct param *)&test].k = 48; D.23106[0] = 255; D.23106[1] = 0; D.23106[2] = 0; D.23106[3] = 0; D.23106[4] = 0; D.23106[5] = 0; MEM[(struct _Vector_impl_data *)&test + 8B] ={v} {CLOBBER}; MEM[(struct _Vector_impl_data *)&test + 8B]._M_start = 0B; MEM[(struct _Vector_impl_data *)&test + 8B]._M_finish = 0B; MEM[(struct _Vector_impl_data *)&test + 8B]._M_end_of_storage = 0B; _43 = operator new (6); <bb 3> [local count: 498553576]: MEM <unsigned char[6]> [(char * {ref-all})_43] = MEM <unsigned char[6]> [(char * {ref-all})&D.23106]; The dump says Candidate (23106): D.23106 ! Disqualifying D.23106 - Encountered a store to a read-only decl. it looks like D.23106 is TREE_READONLY contrary to the IL. The decl is originally from TARGET_EXPR <D.23107, {._M_array=(const unsigned char *) &TARGET_EXPR <D.23106, {255, 0, 0, 0, 0, 0}>, ._M_len=6}> here the target is already readonly. In other places in the gimplifier we clear TREE_READONLY but in this case we fail to. We also fail to promote the variable to a static const, possibly because of heuristics or -fmerge-constants != 2 and the var being TREE_ADDRESSABLE. diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index f570daa015a..de58bdebbc7 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -5110,6 +5110,10 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_ p, gimple_seq *post_p, break; } + if (VAR_P (object) + && TREE_READONLY (object)) + TREE_READONLY (object) = 0; + /* If there are "lots" of initialized elements, even discounting those that are not address constants (and thus *must* be computed at runtime), then partition the constructor into "fixes" this, but I guess we need to maybe re-visit the decision to punt on TREE_READONLY decls in SRA? Jason, anything the C++ FE can improve here? Thoughts about the gimplifier retaining TREE_READONLY?