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

--- Comment #2 from Andreas Krebbel <krebbel at gcc dot gnu.org> ---
I think this is a different problem.  In my case the reason for adding an
invalid rematerialization appears to be that the live ranges of an hard
registers are not correctly calculated.

I've just verified with GCC head r249394:

For the two insns:

(insn 470 25077 476 10 (set (reg:CCU 33 %cc)
        (compare:CCU (reg:DI 3 %r3 [orig:1277 _1997 ] [1277])
            (mem/u/c:DI (reg:DI 5 %r5 [14737]) [5  S8 A64]))) "t.f90":48 1242
{*cmpdi_ccu}
     (nil))

(insn 472 27815 25079 10 (parallel [
            (set (reg:SI 7 %r7 [orig:1282 _2003 ] [1282])
                (plus:SI (plus:SI (gtu:SI (reg:CCU 33 %cc)
                            (const_int 0 [0]))
                        (reg:SI 7 %r7 [orig:1256 _1967 ] [1256]))
                    (reg:SI 2 %r2 [orig:1258 _1969 ] [1258])))
            (clobber (reg:CC 33 %cc))
        ]) "t.f90":48 1661 {*addsi3_alc}
     (nil))

LRA records the following registers:

470:
{early_clobber_alts = 0, biggest_mode = DImode, type = OP_IN, subreg_p = 0, 
  early_clobber = 0, regno = 1277, next = 0x3cdb480}
{early_clobber_alts = 0, biggest_mode = DImode, type = OP_IN, subreg_p = 0, 
  early_clobber = 0, regno = 14737, next = 0x0}

hardregs:

{early_clobber_alts = 0, biggest_mode = CCUmode, type = OP_OUT, subreg_p = 0, 
  early_clobber = 0, regno = 33, next = 0x0}


472:

{early_clobber_alts = 0, biggest_mode = SImode, type = OP_OUT, subreg_p = 0, 
  early_clobber = 0, regno = 1282, next = 0x3cdb400}
{early_clobber_alts = 0, biggest_mode = SImode, type = OP_IN, subreg_p = 0, 
  early_clobber = 0, regno = 1256, next = 0x3cdb3e0}
{early_clobber_alts = 0, biggest_mode = SImode, type = OP_IN, subreg_p = 0, 
  early_clobber = 0, regno = 1258, next = 0x3cdb3c0}
{early_clobber_alts = 0, biggest_mode = CCUmode, type = OP_IN, subreg_p = 0, 
  early_clobber = 0, regno = 33, next = 0x0}

hardregs:
{early_clobber_alts = 18446744073709551615, biggest_mode = CCmode, type =  
OP_OUT, subreg_p = 0, early_clobber = 1, regno = 33, next = 0x0}

Marking r33 as early_clobber output makes it dead before insn 472 here:

lra-lives.c(915)
      /* Mark early clobber outputs dead.  */
      for (reg = curr_id->regs; reg != NULL; reg = reg->next)
        if (reg->type == OP_OUT
            && reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p)
          need_curr_point_incr
            |= mark_regno_dead (reg->regno, reg->biggest_mode,
                                curr_point);

Reaching insn 470 with r33 being dead the reg is consequently marked as
"unused":

(insn 470 25077 476 10 (set (reg:CCU 33 %cc)
        (compare:CCU (reg:DI 1277 [ _1997 ])
            (mem/u/c:DI (reg:DI 14737) [5  S8 A64]))) "t.f90":48 1242
{*cmpdi_ccu}
     (expr_list:REG_UNUSED (reg:CC 33 %cc)
        (expr_list:REG_DEAD (reg:DI 14737)
            (nil))))

Since r33 is also an input operand to insn 472 it should not be marked as
early_clobber. The attached patch prevents that and fixes the problem for me.

Reply via email to