On Tue, Jan 13, 2026 at 05:50:47PM +0100, Stefan Schulze Frielinghaus wrote:
> On Tue, Jan 13, 2026 at 08:20:49AM -0700, Jeffrey Law wrote:
> >
> >
> > On 1/10/2026 9:11 AM, Stefan Schulze Frielinghaus wrote:
> > > From: Stefan Schulze Frielinghaus <[email protected]>
> > >
> > > This fixes
> > >
> > > t.c:17:3: error: 'asm' operand has impossible constraints or there are
> > > not enough registers
> > > 17 | __asm__ ("" : "=f" (a), "={fr2}" (e) : "{fr1}" (d));
> > > | ^~~~~~~
> > >
> > > on powerpc64le-unknown-linux-gnu for the attached test. Prior cse1 we
> > > have
> > >
> > > (insn 2 4 3 2 (set (reg/v:TF 120 [ c ])
> > > (reg:TF 33 1 [ c ])) "t.c":14:26 614 {*movtf_64bit_dm}
> > > (nil))
> > > ...
> > > (insn 10 9 6 2 (parallel [
> > > (set (reg:DF 121)
> > > (asm_operands:DF ("") ("=f") 0 [
> > > (reg:TF 124)
> > > ]
> > > [
> > > (asm_input:TF ("{fr1}") t.c:17)
> > > ]
> > > [] t.c:17))
> > > (set (reg:DF 123 [ e ])
> > > (asm_operands:DF ("") ("={fr2}") 1 [
> > > (reg:TF 124)
> > > ]
> > > [
> > > (asm_input:TF ("{fr1}") t.c:17)
> > > ]
> > > [] t.c:17))
> > > (clobber (reg:SI 98 ca))
> > > ]) "t.c":17:3 -1
> > > (nil))
> > > ...
> > > (insn 12 11 13 2 (set (reg:TF 33 1)
> > > (reg/v:TF 120 [ c ])) "t.c":18:12 614 {*movtf_64bit_dm}
> > > (nil))
> > >
> > > During cse1, in insn 12 pseudo 120 is substituted with hard register 33
> > > rendering the resulting insn trivial which is why the insn gets removed
> > > afterwards. Since hard register 33 has a use after insn 12, the
> > > register is live before and after insn 10. This leaves us with the
> > > non-trivial problem, during LRA, to also assign hard register 33 to
> > > pseudo 124 which is coming from the constraint of insn 10. Since hard
> > > registers are not tracked, except for liveness, this cannot be solved by
> > > reloads which is why we end up with an error.
> > >
> > > Therefore, treat single register constraints as clobbers of the
> > > respective hard registers. This includes constraints associated a
> > > single register class as well as hard register constraints.
> > >
> > > gcc/ChangeLog:
> > >
> > > * cse.cc (invalidate_from_sets_and_clobbers): Consider any hard
> > > register referred to by any single register constraint
> > > potentially being clobbered.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * gcc.target/powerpc/asm-hard-reg-2.c: New test.
> > Can we really get at the register classes while in CSE? That's a bit of a
> > surprise. My recollection is these kinds of cases a handled by the
> > likely-spilled hooks. Look in hash_rtx, where that code is lying around.
>
> ira_class_singleton is setup in
> setup_prohibited_and_exclude_class_mode_regs() which is called during
> ira_init() which itself is called during backend_init_target(). So my
> reading is that it should be save to access during CSE. On the other
> hand I'm wondering why this is not in ira_init_once(). Maybe I'm
> overlooking something here. Let me double check.
Hmm even after giving it a second thought I still don't see a reason not
to access ira_class_singleton since it is set during initialize_rtl().
Maybe I'm overlooking something fundamental here?
Anyhow, I added
else
{
enum reg_class cl
= reg_class_for_constraint (lookup_constraint (p));
if (cl == NO_REGS)
continue;
machine_mode mode = recog_data.operand_mode[nop];
int regno = ira_class_singleton[cl][mode];
if (regno >= 0)
invalidate_reg (gen_rtx_REG (mode, regno));
}
for the sake of completeness and symmetry of hard register constraints
and constraints associated a single register class. Maybe the stage4
interrupt should be applied here, too, i.e., I don't want to risk it and
introduce hiccups. Would the patch be ok if I remove the else clause
and the include statement of ira.h?
Cheers,
Stefan