Jeff Law <l...@redhat.com> writes:
> On 04/16/14 07:37, Jakub Jelinek wrote:
>>
>> Creating a (mem (scratch)) too early may pessimize code too much,
>> perhaps it can be used during say sched1 etc. for alias analysis, (mem
>> (scratch)) is considered to alias everything,.
>> Plus, I think at least so far we have not been doing different decisions
>> based on whether some operand has been referenced in the template or not,
>> not sure if it is desirable to introduce it.
>>
>> Anyway, others can have different opinion on what "X" should mean,
>> CCing Jeff and Eric.
> My recollection is that "X" was supposed to be used in cases where we 
> conditionally needed a scratch operand.  The "X" constraint was used to 
> identify alternatives where the scratch operand wasn't actually needed.
>
> Conceptually that meant that literally anything could go in there, it 
> need not be valid or reloadable.

My understanding was that this use of "X" was usually done using
scratch_operands, usually indirectly via match_scratch.  And
scratch_operand only accepts (scratch) and (reg ...):

int
scratch_operand (rtx op, enum machine_mode mode)
{
  if (GET_MODE (op) != mode && mode != VOIDmode)
    return 0;

  return (GET_CODE (op) == SCRATCH
          || (REG_P (op)
              && (lra_in_progress || REGNO (op) < FIRST_PSEUDO_REGISTER)));
}

That reg could be replaced by a MEM or equivalent constant during reloading,
but I don't think it's fully general.  You wouldn't get the kind of
nested MEMs and division operations seen in the testcase.

> I'm a bit surprised to see it showing up outside MD files.

Yeah, but it was documented in the asm section too, as
"Any operand whatsoever is allowed."

I'm not sure where to go from here.  It sounds like there are three
separate suggestions:

1. what the patch did

2. continue to allow the rtl optimisers to do any propagation, etc.
   If this causes the operand to become invalid, report an error to
   the user.

   My objection to this is that the user can't really control what
   propagation the compiler does. If the operand in the source asm
   was correct then IMO the compiler should make sure it stays correct.

3. continue to allow the rtl optimisers to do any propagation, etc.
   If this causes the operand to become invalid, replace parts of it
   with a scratch.

   This is not something we do for any other operand and might cause
   confusion for matching operands.  It also means that the operand
   can't be printed.

   I assume that if we end up with nested MEMs, we would only want
   to replace the innermost addresses with scratches, since otherwise
   we'd be removing a memory read.  So even with the scratches,
   we could end up with some odd-looking rtl.

As evidence that "X" operands are being printed, a version of linux's
arch/s390/include/asm/jump_label.h that I have lying around has:

static __always_inline bool arch_static_branch(struct static_key *key)
{
        asm goto("0:    brcl 0,0\n"
                ".pushsection __jump_table, \"aw\"\n"
                ASM_ALIGN "\n"
                ASM_PTR " 0b, %l[label], %0\n"
                ".popsection\n"
                : : "X" (key) : : label);
        return false;
label:
        return true;
}

This one wouldn't be affected by (3), but it does seem dangerous
to assume that noone cares whether "X" operands are printable.

Thanks,
Richard

Reply via email to