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.

Reply via email to