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?

Reply via email to