https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97588
Martin Jambor <jamborm at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Status|UNCONFIRMED |NEW Last reconfirmed| |2021-01-22 --- Comment #2 from Martin Jambor <jamborm at gcc dot gnu.org> --- SRA only decides to create replacements for the single-bit flags, we don't do total scalarization when there are bit-fields. Part of the problem, is that SRA sees some accesses to the flags directly: flags.flag1 = 1; but others it does not really see because they are quite indirect: _13 = BIT_FIELD_REF <flags, 8, 8>; _14 = _13 & 8; if (_14 != 0) ...and it still decides to scalarize (more on that below), which means that it has to store the flag back to flags before the BIT_FIELD_REF, which leads to impression of the access being split into four parts. Having said that, scalarizing bit-fields, and even more so 1-bit flags, when there are not multiple reads from the bit-field itself, is probably not useful (in the case of non-bit fields it can lead to disappearance of the aggregate). So, would the following help the real code that you derived the testcase from? diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index d177f1ba11c..d3c3a4584a0 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2519,7 +2519,8 @@ analyze_access_subtree (struct access *root, struct access *parent, && (totally || !root->grp_total_scalarization) && (totally || root->grp_hint - || ((root->grp_scalar_read || root->grp_assignment_read) + || (root->size > 1 + && (root->grp_scalar_read || root->grp_assignment_read) && (root->grp_scalar_write || root->grp_assignment_write)))) { /* Always create access replacements that cover the whole access. @@ -2562,11 +2563,10 @@ analyze_access_subtree (struct access *root, struct access *parent, && scalar && !root->first_child && !root->grp_total_scalarization && (root->grp_scalar_write || root->grp_assignment_write) + && (!root->grp_scalar_read && !root->grp_assignment_read) && !bitmap_bit_p (cannot_scalarize_away_bitmap, DECL_UID (root->base))) { - gcc_checking_assert (!root->grp_scalar_read - && !root->grp_assignment_read); sth_created = true; if (MAY_HAVE_DEBUG_BIND_STMTS) {