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.