Jeff Law <jeffreya...@gmail.com> writes:
> On 6/3/25 11:11 AM, Richard Sandiford wrote:
>> Vineet Gupta <vine...@rivosinc.com> writes:
>>> On 6/3/25 08:24, Richard Sandiford wrote:
>>>> I think the issue is that:
>>>>
>>>> (insn 9 8 27 2 (parallel [
>>>>              (asm_operands/v ("fsrm %0") ("") 0 [
>>>>                      (reg:SI 15 a5 [139])
>>>>                  ]
>>>>                   [
>>>>                      (asm_input:SI ("r") frm-run-1.c:33)
>>>>                  ]
>>>>                   [] frm-run-1.c:33)
>>>>              (clobber (reg:V4096QI 69 frm))
>>>>          ]) "frm-run-1.c":33:3 -1
>>>>       (nil))
>>>>
>>>> is seen as invalidating FRM and so:
>>>>
>>>> (insn 27 9 28 2 (set (reg:SI 15 a5 [144])
>>>>          (reg:SI 69 frm)) "frm-run-1.c":43:1 2829 {frrmsi}
>>>>       (nil))
>>>>
>>>> is seen as an uninitialised read.  I suppose clobbers in inline asms
>>>> need to be treated as real definitions rather than just kills.
>>>
>>> In general or specifically inside of late_combine ?
>> 
>> We can start with the routines that rtl-ssa uses for its dataflow analysis.
>> Does the patch below help?
>> 
>> Jeff, Eric: any thoughts about this?
> The thing is it's a clobber.  So late-combine's behavior seems sensible 
> given the dataflow from insn 9.  I think we've always interpreted the 
> clobber list as precisely that -- any incoming value is potentially 
> destroyed and we have no knowledge of the outgoing value.
>
> That would in turn mean that insn 27 is (effectively) an uninitialized 
> read.

Yeah, that was also my concern.  The current semantics are at least
self-consistent, even if they're not always useful. :)

And the difference between "in operand_reg_set" and "not in operand_reg_set"
probably isn't clear to users.  Having the same syntax mean two different
things based on a subtle internal distinction might cause more confusion.

Maybe we need a new syntax here?

FWIW, the SME ACLE does specifically say that "za" in the clobber list
means that the asm reads from and writes to ZA, as an exception to the
normal meaning.  Admittedly this was a "path of least resistance" thing,
since changing the asm syntax for the benefit one target seemed like a
big ask.

We try to handle that with:

  /* "za" in the clobber list of a function with ZA state is defined to
     mean that the asm can read from and write to ZA.  We can model the
     read using a USE, but unfortunately, it's not possible to model the
     write directly.   Use a separate insn to model the effect.

     We must ensure that ZA is active on entry, which is enforced by using
     SME_STATE_REGNUM.  The asm must ensure that ZA is active on return.

     The same thing applies to ZT0.  */
  if (TARGET_ZA)
    for (unsigned int i = clobbers.length (); i-- > 0; )
      {
        rtx x = clobbers[i];
        if (REG_P (x)
            && (REGNO (x) == ZA_REGNUM || REGNO (x) == ZT0_REGNUM))
          {
            auto id = cfun->machine->next_asm_update_za_id++;

            start_sequence ();
            if (seq)
              emit_insn (seq);
            rtx id_rtx = gen_int_mode (id, SImode);
            emit_insn (REGNO (x) == ZA_REGNUM
                       ? gen_aarch64_asm_update_za (id_rtx)
                       : gen_aarch64_asm_update_zt0 (id_rtx));
            seq = end_sequence ();

            auto mode = REGNO (x) == ZA_REGNUM ? VNx16QImode : V8DImode;
            uses.safe_push (gen_rtx_REG (mode, REGNO (x)));
            uses.safe_push (gen_rtx_REG (DImode, SME_STATE_REGNUM));

            clobbers.ordered_remove (i);
            CLEAR_HARD_REG_BIT (clobbered_regs, REGNO (x));
          }
      }

Thanks,
Richard

Reply via email to