https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69355

--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, without the tree-dfa.c change current trunk in esra transforms:
 G<I<K<Sz>, J>, Sz> div(U<Sz>&, double) [with int Sz = 3] (struct U & p1,
double p2)
 {
+  const double * SR.27;
+  const double * SR.26;
+  const double * SR.25;
+  const double * SR.24;
   struct ConstReference D.3593;
   struct ConstReference D.3592;
   struct ConstReference D.3172;
   const struct J D.3173;
   struct expr_type D.3174;
   const double * _11;
   long double _12;

   <bb 2>:
   MEM[(struct  &)&D.3173] ={v} {CLOBBER};
   _12 = (long double) p2_2(D);
   D.3173.m_data = _12;
   _11 = &MEM[(const struct U *)p1_4(D)].m_data;
-  MEM[(struct K *)&D.3593] = _11;
-  D.3592 = D.3593;
-  D.3172 = D.3592;
+  SR.27_3 = _11;
+  SR.26_5 = SR.27_3;
+  SR.24_6 = SR.26_5;
   MEM[(struct  &)&D.3174] ={v} {CLOBBER};
-  D.3174.m_lhs = D.3172;
+  SR.25_23 = SR.24_6;
   MEM[(struct J *)&D.3174 + 16B] = D.3173;
   MEM[(struct  &)&<retval>] ={v} {CLOBBER};
-  <retval>.m_expr = D.3174;
+  MEM[(struct G *)&<retval>] = SR.25_23;
   D.3174 ={v} {CLOBBER};
-  D.3172 ={v} {CLOBBER};
   D.3173 ={v} {CLOBBER};
   return <retval>;

 }

ConstReference (aka K<3>) contains a single const double *m_data member (thus
it is likely a DImode struct), J contains a single long double m_data member,
thus it is XFmode struct,
and expr_type is I, which contains two fields, one ConstReference aka K<3>
m_lhs and another one const J m_rhs.  Scalarization of the DImode struct is of
course just fine, and after scalarization the J store into D.3174 still
remains:
MEM[(struct J *)&D.3174 + 16B] = D.3173;
but what is lost is the read of that or store of D.3173 into MEM[(struct G
*)&<retval> + 16B].
Compared to this, with patched tree-dfa.c esra changes the same function:
 G<I<K<Sz>, J>, Sz> div(U<Sz>&, double) [with int Sz = 3] (struct U & p1,
double p2)
 {
+  const double * SR.29;
+  const double * SR.28;
+  long double SR.27;
+  const double * SR.26;
+  long double SR.25;
+  const double * SR.24;
   struct ConstReference D.3593;
   struct ConstReference D.3592;
   struct ConstReference D.3172;
   const struct J D.3173;
   struct expr_type D.3174;
   const double * _11;
   long double _12;

   <bb 2>:
-  MEM[(struct  &)&D.3173] ={v} {CLOBBER};
   _12 = (long double) p2_2(D);
-  D.3173.m_data = _12;
+  SR.25_5 = _12;
   _11 = &MEM[(const struct U *)p1_4(D)].m_data;
-  MEM[(struct K *)&D.3593] = _11;
-  D.3592 = D.3593;
-  D.3172 = D.3592;
-  MEM[(struct  &)&D.3174] ={v} {CLOBBER};
-  D.3174.m_lhs = D.3172;
-  MEM[(struct J *)&D.3174 + 16B] = D.3173;
+  SR.29_6 = _11;
+  SR.28_7 = SR.29_6;
+  SR.24_23 = SR.28_7;
+  SR.26_26 = SR.24_23;
+  SR.27_27 = SR.25_5;
   MEM[(struct  &)&<retval>] ={v} {CLOBBER};
-  <retval>.m_expr = D.3174;
-  D.3174 ={v} {CLOBBER};
-  D.3172 ={v} {CLOBBER};
-  D.3173 ={v} {CLOBBER};
+  MEM[(struct G *)&<retval>] = SR.26_26;
+  MEM[(struct G *)&<retval> + 16B] = SR.27_27;
   return <retval>;

 }

i.e. scalarizes also the long double stores and reads (thus, the proposed
tree-dfa.c change would improve it too), but the bug really is that the long
double assignment of
(80 or 96 or 128 bits from D.3174 starting from offset 16 bytes into the struct
into corresponding <retval> field is lost in vanilla trunk.

So, I think we want to change back tree-dfa.c plus fix the SRA bug that causes
this if tree-dfa.c is not changed.
Martin, can you please take over the SRA part?

Reply via email to