https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125173

Stefan Schulze Frielinghaus <stefansf at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2026-05-04
                 CC|                            |stefansf at gcc dot gnu.org
             Status|UNCONFIRMED                 |NEW

--- Comment #1 from Stefan Schulze Frielinghaus <stefansf at gcc dot gnu.org> 
---
Confirmed.  This is target independent and also reproducible on e.g. s390. 
Seems to be the case since the assert was added (at least reproducible for me
with gcc 8/9/10/11/12).

10: r70:DI=`*.LANCHOR0'
   REG_EQUIV `*.LANCHOR0'
11:
{[`*.LANCHOR0']=asm_operands;[const(`*.LANCHOR0'+0x8)]=asm_operands;[const(`*.LANCHOR0'+0xc)]=asm_operands;}
   REG_DEAD r70:DI

We fail while trying to replace r70 with its equiv in insn 11.  In each
asm_operands r70 is referred to.  Therefore, while walking over all uses via

rtx_insn *use_insn = 0;
for (df_ref use = DF_REG_USE_CHAIN (regno);
     use;
     use = DF_REF_NEXT_REG (use))
  if (DF_REF_INSN_INFO (use))
    {
      if (DEBUG_INSN_P (DF_REF_INSN (use)))
        continue;
      gcc_assert (!use_insn);
      use_insn = DF_REF_INSN (use);
    }

we see insn 11 multiple times which is why the assert triggers.  I think the
assert could be relaxed since what we want to ensure here is that a register is
not referred to by multiple/different insns since otherwise we cannot trivially
move the definition.  So maybe something like the attached patch which is
completely untested.

Reply via email to