https://gcc.gnu.org/g:0ab0aff01313b52b1d2fc9e50294724fb30fc1f9
commit r17-5496-g0ab0aff01313b52b1d2fc9e50294724fb30fc1f9 Author: Yongqiang Tian <[email protected]> Date: Thu Oct 22 21:37:28 2026 -0600 [PATCH v2] combine: Ignore trailing debug insns when checking return values likely_spilled_retval_p uses BB_END to locate the USE of a multi-register return value. With debug information, BB_END can be a DEBUG_INSN, causing the check to fail and allowing combine to merge into a return-register copy that it rejects without debug information. Use prev_nondebug_insn to ignore trailing debug insns while preserving the existing treatment of notes. Skipping notes only when a debug insn follows them would introduce a compare-debug difference in the opposite direction. No null check is needed because BB_END is nonnull for the basic block being processed. The backwards walk cannot leave the block: in cfgrtl mode, BB_HEAD is a non-debug NOTE_INSN_BASIC_BLOCK. Add one MIPS __RTL test for the original failure and another that places a NOTE_INSN_DELETED between the return-value USE and the debug insn. The second test guards against skipping notes in the debug build. Bootstrapped and regression tested on x86_64-pc-linux-gnu. Also tested on mips-elf with an incremental GCC rebuild. The two targeted RTL tests produced 8 expected passes and no failures. contrib/check_GNU_style.sh and git diff --check also passed. Assisted-by: OpenAI Codex 5.6 Sol, co-reviewed by Claude and Yongqiang Tian. gcc/ChangeLog: * combine.cc (likely_spilled_retval_p): Skip trailing debug insns when locating the return-value USE. gcc/testsuite/ChangeLog: * gcc.dg/rtl/mips/combine-likely-spilled-retval.c: New test. * gcc.dg/rtl/mips/combine-likely-spilled-retval-note.c: New test. Signed-off-by: Yongqiang Tian <[email protected]> Diff: --- gcc/combine.cc | 8 +++- .../rtl/mips/combine-likely-spilled-retval-note.c | 47 +++++++++++++++++++++ .../rtl/mips/combine-likely-spilled-retval.c | 49 ++++++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/gcc/combine.cc b/gcc/combine.cc index c9daefc905c3..c57cd631b8b2 100644 --- a/gcc/combine.cc +++ b/gcc/combine.cc @@ -2315,7 +2315,13 @@ likely_spilled_retval_p (rtx_insn *insn) unsigned mask; struct likely_spilled_retval_info info; - if (!NONJUMP_INSN_P (use) || GET_CODE (PATTERN (use)) != USE || insn == use) + /* With -g, BB_END may be a DEBUG_INSN. Ignore trailing debug + instructions without changing how notes are handled. */ + if (DEBUG_INSN_P (use)) + use = prev_nondebug_insn (use); + if (!NONJUMP_INSN_P (use) + || GET_CODE (PATTERN (use)) != USE + || insn == use) return false; reg = XEXP (PATTERN (use), 0); if (!REG_P (reg) || !targetm.calls.function_value_regno_p (REGNO (reg))) diff --git a/gcc/testsuite/gcc.dg/rtl/mips/combine-likely-spilled-retval-note.c b/gcc/testsuite/gcc.dg/rtl/mips/combine-likely-spilled-retval-note.c new file mode 100644 index 000000000000..ec91c9b57749 --- /dev/null +++ b/gcc/testsuite/gcc.dg/rtl/mips/combine-likely-spilled-retval-note.c @@ -0,0 +1,47 @@ +/* { dg-do compile { target mips*-*-* } } */ +/* { dg-options "-O2 -g -mips1 -mabi=32 -mfix-r4000 -fdump-rtl-combine-details" } */ + +/* Verify that a trailing debug instruction does not cause the scan to skip + a note that it would retain without debug information. */ + +long long __RTL (startwith ("combine")) +f (long long a, long long b) +{ +(function "f" + (param "a" + (DECL_RTL (reg/v:DI <3> [ a ])) + (DECL_RTL_INCOMING (reg:DI $4 [ a ]))) + (param "b" + (DECL_RTL (reg/v:DI <4> [ b ])) + (DECL_RTL_INCOMING (reg:DI $6 [ b ]))) + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 8 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cinsn 19 (set (reg:SI <0> [ a+4 ]) + (reg:SI $5 [ a+4 ]))) + (cinsn 21 (set (reg:SI <1> [ b+4 ]) + (reg:SI $7 [ b+4 ]))) + (cnote 7 NOTE_INSN_FUNCTION_BEG) + (cinsn 10 (set (reg:DI <2>) + (mult:DI + (sign_extend:DI (reg:SI <0> [ a+4 ])) + (sign_extend:DI (reg:SI <1> [ b+4 ]))))) + (cinsn 15 (set (reg/i:DI $2) + (reg:DI <2>))) + (cinsn 16 (use (reg/i:DI $2))) + (cnote 18 NOTE_INSN_DELETED) + (cdebug_insn 17 (debug_marker)) + (edge-to exit (flags "FALLTHRU")) + ) + ) + (crtl + (return_rtx (reg/i:DI $2)) + ) +) +} + +/* The combine cost dump prints the BEGIN_STMT marker. Check it so that the + other scans cannot pass because debug information was discarded. */ +/* { dg-final { scan-rtl-dump "debug begin stmt marker" "combine" } } */ +/* { dg-final { scan-rtl-dump "allowing combination of insns 10 and 15" "combine" } } */ diff --git a/gcc/testsuite/gcc.dg/rtl/mips/combine-likely-spilled-retval.c b/gcc/testsuite/gcc.dg/rtl/mips/combine-likely-spilled-retval.c new file mode 100644 index 000000000000..d9cb86e40a98 --- /dev/null +++ b/gcc/testsuite/gcc.dg/rtl/mips/combine-likely-spilled-retval.c @@ -0,0 +1,49 @@ +/* { dg-do compile { target mips*-*-* } } */ +/* { dg-options "-O2 -g -mips1 -mabi=32 -mfix-r4000 -fdump-rtl-combine-details" } */ + +/* Verify that a debug instruction after the return-value USE does not allow + combine to form a multi-register return value in a likely-spilled register + class. */ + +long long __RTL (startwith ("combine")) +f (long long a, long long b) +{ +(function "f" + (param "a" + (DECL_RTL (reg/v:DI <3> [ a ])) + (DECL_RTL_INCOMING (reg:DI $4 [ a ]))) + (param "b" + (DECL_RTL (reg/v:DI <4> [ b ])) + (DECL_RTL_INCOMING (reg:DI $6 [ b ]))) + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 8 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cinsn 19 (set (reg:SI <0> [ a+4 ]) + (reg:SI $5 [ a+4 ]))) + (cinsn 21 (set (reg:SI <1> [ b+4 ]) + (reg:SI $7 [ b+4 ]))) + (cnote 7 NOTE_INSN_FUNCTION_BEG) + (cinsn 10 (set (reg:DI <2>) + (mult:DI + (sign_extend:DI (reg:SI <0> [ a+4 ])) + (sign_extend:DI (reg:SI <1> [ b+4 ]))))) + (cinsn 15 (set (reg/i:DI $2) + (reg:DI <2>))) + (cinsn 16 (use (reg/i:DI $2))) + (cdebug_insn 17 (debug_marker)) + (edge-to exit (flags "FALLTHRU")) + ) + ) + (crtl + (return_rtx (reg/i:DI $2)) + ) +) +} + +/* The combine cost dump prints the BEGIN_STMT marker. Check it so that the + other scans cannot pass because debug information was discarded. */ +/* { dg-final { scan-rtl-dump "debug begin stmt marker" "combine" } } */ +/* { dg-final { scan-rtl-dump "\\(insn 10 " "combine" } } */ +/* { dg-final { scan-rtl-dump "\\(insn 15 " "combine" } } */ +/* { dg-final { scan-rtl-dump-not "combination of insns 10 and 15" "combine" } } */
