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

            Bug ID: 119174
           Summary: [15 Regression] IRA allocating value live across a
                    call to call clobbered register
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: law at gcc dot gnu.org
  Target Milestone: ---

Since this change:

commit b191e8bdecf881d11c1544c441e38f4c18392a15 (HEAD)
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Thu Mar 6 11:06:25 2025 +0000

    ira: Add new hooks for callee-save vs spills [PR117477]

    Following on from the discussion in:

      https://gcc.gnu.org/pipermail/gcc-patches/2025-February/675256.html

    this patch removes TARGET_IRA_CALLEE_SAVED_REGISTER_COST_SCALE and
    replaces it with two hooks: one that controls the cost of using an
    extra callee-saved register and one that controls the cost of allocating
    a frame for the first spill.

    (The patch does not attempt to address the shrink-wrapping part of
    the thread above.)
[ ... ]

IRA has started allocating a pseudo that is live across calls to a call
clobbered regsiter on msp430-elf.   Clearly not good.  Marking as a P1 until we
know if it's something generic or specific to msp430-elf.

This testcase with -Os:

__attribute__((__noipa__))
void f3(int x, int (*p3 []) (int))
{
  int i;
  int next = x;
  for (i = 0; i < x; i++)
    next = p3[i](next);
}

Generates this loop + epilogue:

.L2:
        CMP.W   @R1, R10 { JL   .L3      ; 22   [c=8 l=4]  cbranchhi4_real/0
        ; start of epilogue      ; 42   [c=0 l=0]  epilogue_start_marker
        ADD.W   #2, R1   ; 43   [c=8 l=4]  addhi3/0
        POPM.W  #1, r10  ; 44   [c=4 l=2]  popm
        RET              ; 45   [c=4 l=2]  msp430_return
.L3:
        MOV.W   @R13+, R14       ; 35   [c=4 l=2]  movhi/1
        CALL    R14      ; 16   [c=4 l=2]  call_value_internal
        ADD.W   #1, R10  ; 18   [c=8 l=4]  addhi3/0
        BR      #.L2     ; 48   [c=8 l=4]  jump


Note carefully how the value of R13 is live across the call at insn 16.  Then
verify R13 is in call_used_regs on the msp430-elf port.

Looking at the .ira dump we find insn 16:

(call_insn 16 15 30 3 (set (reg:HI 12 R12)
        (call:HI (mem:HI (mem/f:HI (post_inc:HI (reg:HI 26 [ ivtmp.10 ])) [1
MEM[(int (*<T2da>) (int) *)_18]+0 S2 A16]) [0 *_4 S2 A16])
            (const_int 0 [0]))) "j.c":8:12 89 {call_value_internal}
     (expr_list:REG_INC (reg:HI 26 [ ivtmp.10 ])
        (expr_list:REG_CALL_DECL (nil)
            (nil)))
    (expr_list:HI (use (reg:HI 12 R12))
        (nil)))


So the pseudo is (reg:HI 26), and looking back to the actual allocation:


      Popping a3(r26,l0)  --         assign reg 13


So at this point we've lost.

I've also bisected an mcore-elf regression to the same change, but have not
debugged it as the testcase is more complex and GDB port for mcore faults, so
debugging is nontrivial.

Reply via email to