https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111916
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jamborm at gcc dot gnu.org --- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- ESRA does int main () { + unsigned char g; struct A g; unsigned char _1; unsigned char _2; <bb 2> : g = *.LC0; + g_6 = BIT_FIELD_REF <*.LC0, 8, 0>; goto <bb 4>; [INV] <bb 3> : + BIT_FIELD_REF <g, 8, 0> = g_6; f = g; <bb 4> : - _1 = BIT_FIELD_REF <g, 8, 0>; + _1 = g_6; _2 = _1 & 15; if (_2 == 0) goto <bb 3>; [INV] which looks OK, but then SRA does + unsigned char SR.5; + unsigned char g; unsigned char g; struct A g; unsigned char _1; unsigned char _11; <bb 2> [local count: 118111600]: + SR.5_10 = SR.5_2(D); g = *.LC0; - g_5 = BIT_FIELD_REF <*.LC0, 8, 0>; + g_14 = SR.5_10; + g_5 = SR.5_10; _11 = g_5 & 15; if (_11 == 0) goto <bb 3>; [0.00%] @@ -19,6 +33,8 @@ <bb 3> [local count: 955630224]: BIT_FIELD_REF <g, 8, 0> = g_5; + g_16 = MEM <unsigned char> [(struct A *)&g]; + MEM <unsigned char> [(struct A *)&g] = g_16; f = g; _1 = g_5 & 15; goto <bb 3>; [100.00%] which looks weird. First initialize_constant_pool_replacements inserts SR.5 = BIT_FIELD_REF <*.LC0, 8, 0>; which loosk OK, but then sra_modify_assign wrecks this, replacing the RHS with 'SR.5', yielding SR.5 = SR.5 this happens before the /* Avoid modifying initializations of constant-pool replacements. */ if (racc && (racc->replacement_decl == lhs)) return SRA_AM_NONE; code. I can paper over with the following, but I wonder if sra_modify_expr needs that very same check for constant-pool replacements? diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc index f8dff8b27d7..efb52453250 100644 --- a/gcc/tree-sra.cc +++ b/gcc/tree-sra.cc @@ -4275,7 +4275,8 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi) if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR - || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF) + || (TREE_CODE (rhs) == BIT_FIELD_REF && !sra_handled_bf_read_p (rhs)) + || TREE_CODE (lhs) == BIT_FIELD_REF) { modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt), gsi, false); I will test this now.