On Fri, 8 May 2026, Richard Biener wrote:
> On Wed, 29 Apr 2026, Richard Biener wrote:
>
> > On Wed, 29 Apr 2026, Jakub Jelinek wrote:
> >
> > > On Wed, Apr 29, 2026 at 11:03:36AM +0200, Richard Biener wrote:
> > > > The following avoids (large) string duplication which can happen
> > > > when folding aggregate reads to STRING_CSTs. There's unlikely
> > > > to be followup optimization opportunities.
> > > >
> > > > Bootstrapped and tested on x86-64-unknown-linuyx-gnu (I was surprised
> > > > there's no diagnostic testcase fallout).
> > > >
> > > > OK for trunk?
> > > >
> > > > Thanks,
> > > > Richard.
> > > >
> > > > PR tree-optimization/120702
> > > > * gimple-fold.cc (maybe_fold_reference): Only fold
> > > > register type reads.
> > > >
> > > > * gcc.dg/tree-ssa/pr120702.c: New testcase.
> > >
> > > Are we then still able to constant fold memcmp (orig, new) where
> > > there are two different const unsigned char [10] vars with the same
> > > content?
> >
> > That's not affected by the patch which only changes folding of
> > gassign aggregate copy RHS and debug bind vals (but I think it doesn't
> > do anything there given there's no aggregate debug temps).
> >
> > > Don't we want to fold at least small aggregates etc.? So, actually decide
> > > based on size rather than on is_gimple_reg_type (or is_gimple_reg_type
> > > or reasonably small size)?
> >
> > I'm not sure why we should. I believe the appropriate place to
> > do that should be aggregate copy RTL expansion (emit_block_move).
> >
> > That said, there's other fold_const_aggregate_ref users left that
> > I didn't look at or adjusted.
>
> Any objection to the patch as-is? For example we still fold
>
> unsigned int foo ()
> {
> static const unsigned char s[4] = "ABCD";
> unsigned int res;
> __builtin_memcpy (&res, s, 4);
> return res;
> }
>
> because memcpy folding transforms this to
>
> _1 = MEM <unsigned int> [(char * {ref-all})&s];
> MEM <unsigned int> [(char * {ref-all})&res] = _1;
>
> so we get the reg-type inlining at CCP time.
Even
struct S { unsigned long a; unsigned long b; };
struct S foo ()
{
static const unsigned char s[16] = "ABCDEFGHIJKLMNOP";
struct S res;
__builtin_memcpy (&res, s, 16);
return res;
}
by means of memcpy folding using __int128 for the copy.
Richard.