On Wed, Mar 09, 2022 at 11:07:21AM +0100, Richard Biener wrote:
> The following fixes an ICE observed with a MEM_REF allows_mem asm
> operand.  There's code expecting INDIRECT_REFs that are now never
> going to appear.  The following simply treats all tcc_reference
> operands the same.

The INDIRECT_REF in there seems to be at least from 1995, but my limited
understanding of what it wants to catch is operands that provably must
live in memory.  INDIRECT_REF (assuming *&*& is folded already) is
such a case, MEM_REF could be but not always (there is the case of
MEM_REF on &decl without TREE_ADDRESSABLE) but usually is,
other handled_component_p depend on what their first operand is etc.

I think there are two cases, one is an optimization (the && allows_mem
case) where we don't want create a temporary (especially a huge one)
if it clearly has to live in memory.  Example where we mess this up:
struct T { char b[1024]; };
struct S { int a; struct T b; } s;

void
foo (void)
{
  asm volatile ("# %0" : : "rm" (s.b));
}
where we create 1024 bytes long temporary on the stack, copy s.b to it
and that is the operand live in memory.
So perhaps for the allows_mem && case we could handle that way
all BLKmode types (BLKmode must live in memory, no?) and otherwise
look through all handled_component_p's and determine if the base
will be in memory (addressable decl, MEM_REF except for ADDR of
non-addressable decl, INDIRECT_REF, what else?).

And another case is where it is not an optimization, where we
just can't ever create a temporary.
One of those examples is
                || TREE_ADDRESSABLE (type)
the if already has, I guess non-constant length (ok, SVE is ok)
would be another.
assign_temp tests !poly_int_tree_p (TYPE_SIZE_UNIT (type), &size),
so perhaps add || !tree_fits_poly_int64_p (TYPE_SIZE_UNIT (type)) ?

        Jakub

Reply via email to