On Wed, 22 Nov 2017, Jakub Jelinek wrote:

> On Wed, Nov 22, 2017 at 11:41:24AM +0100, Richard Biener wrote:
> > 
> > I am testing the following (old) patch to value number call lhs
> > according to the ERF_RETURNS_ARG annotation.  This allows for
> > more expression simplification and also changes downstream
> > users of the argument to use the return value which should help
> > register allocation and register lifetime in general.
> 
> If the argument is an SSA_NAME then that is generally a win, but won't
> it also replace if the argument is say ADDR_EXPR of a VAR_DECL or similar?

Looks like it also confuses passes, for gcc.dg/tree-ssa/pr62112-1.c

char*g;
void h(){
  char*p=__builtin_malloc(42);
  g=__builtin_memset(p,3,10);
  __builtin_free(p);
}

we no longer DSE the memset because we end up with

  <bb 2> :
  p_4 = __builtin_malloc (42);
  _1 = __builtin_memset (p_4, 3, 10);
  g = _1;
  __builtin_free (_1);

and we no longer see that the free call clobbers the memset destination.

So I guess I'll try to do the reverse (always replace with the argument).
That will of course make DCE remove the LHS of such calls.

In theory it's easy to recover somewhere before RTL expansion ...

> If we only later (say some later forwprop) determine the argument is
> gimple_min_invariant, shouldn't we have something that will effectively
> undo this (i.e. replace the uses of the function result with whatever
> we've simplified the argument to)?

... of course not (easily) if we substituted a constant.

The question is whether for example a pointer in TLS is cheaper
to remat from the return value or via the TLS reg like in

__thread int x[4];

int *foo ()
{
  int *q = __builtin_memset (&x, 3, 4*4);
  return q;
}

of course if the user has written in that way we currently do not
change it.  And we have no easy way (currently) to replace equal
constants by a register where that is available.  So

__thread int x[4];
  
int *foo ()
{
  int *q = __builtin_memset (&x, 3, 4*4);
  return &x;
} 

wouldn't be optimized to return q.  Anyway, it seems the register
allocator can do the trick at least for memset.

Richard.

Reply via email to