https://gcc.gnu.org/g:97b691c72ba88be598dfb49d5cb6546df966519c
commit r17-5274-g97b691c72ba88be598dfb49d5cb6546df966519c Author: Yongqiang Tian <[email protected]> Date: Sat Oct 17 08:39:52 2026 -0600 [PATCH] rtl, aarch64, riscv: Ignore leading debug insns [PR127934, PR127936] Both rest_of_insert_bti and riscv_mode_needed need the first executable instruction in the function, but get_first_nonnote_insn can return a leading DEBUG_INSN. This makes their decisions depend on debug information. On AArch64 this can add a redundant BTI C before PACIASP. On RISC-V it can prevent a singleton VXRM setting from being hoisted to the function entry. Add get_first_nonnote_nondebug_insn and use it at both sites. Add regression tests that check both -fcompare-debug and the expected generated code. Tested at b3a3ecc46023 on x86_64-pc-linux-gnu with a native bootstrap and the gcc and g++ testsuites, comparing unmodified and patched trees. The summary counts and sorted FAIL lines are unchanged. The focused AArch64 and RISC-V tests also pass with the patch and fail without it. LLM-Review-Assistance: GCC Sashiko v0.6.0 PR target/127934 PR target/127936 gcc/ChangeLog: * config/arm/aarch-bti-insert.cc (rest_of_insert_bti): Use get_first_nonnote_nondebug_insn. * config/riscv/riscv.cc (riscv_mode_needed): Likewise. * emit-rtl.cc (get_first_nonnote_nondebug_insn): New function. * rtl.h (get_first_nonnote_nondebug_insn): Declare. gcc/testsuite/ChangeLog: * gcc.target/aarch64/bti-debug-1.c: New test. * gcc.target/riscv/rvv/base/vxrm-debug-1.c: New test. Suggested-by: Andrew Pinski <[email protected]> Signed-off-by: Yongqiang Tian <[email protected]> Diff: --- gcc/config/arm/aarch-bti-insert.cc | 2 +- gcc/config/riscv/riscv.cc | 4 +-- gcc/emit-rtl.cc | 13 +++++++++ gcc/rtl.h | 1 + gcc/testsuite/gcc.target/aarch64/bti-debug-1.c | 16 +++++++++++ .../gcc.target/riscv/rvv/base/vxrm-debug-1.c | 32 ++++++++++++++++++++++ 6 files changed, 65 insertions(+), 3 deletions(-) diff --git a/gcc/config/arm/aarch-bti-insert.cc b/gcc/config/arm/aarch-bti-insert.cc index 8d23eae77af9..4fc60e1f3075 100644 --- a/gcc/config/arm/aarch-bti-insert.cc +++ b/gcc/config/arm/aarch-bti-insert.cc @@ -183,7 +183,7 @@ rest_of_insert_bti (void) { bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; insn = BB_HEAD (bb); - if (!aarch_pac_insn_p (get_first_nonnote_insn ())) + if (!aarch_pac_insn_p (get_first_nonnote_nondebug_insn ())) { bti_insn = aarch_gen_bti_c (); emit_insn_before (bti_insn, insn); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 7e480e978d6d..47b20b8cdb4a 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -14187,10 +14187,10 @@ riscv_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET) switch (entity) { case RISCV_VXRM: - /* If CUR_INSN is the first insn in the function, then determine if we + /* If CUR_INSN is the first nondebug insn, then determine if we want to signal a need in ENTRY->succs to allow for aggressive elimination of subsequent sets of VXRM. */ - if (insn == get_first_nonnote_insn ()) + if (insn == get_first_nonnote_nondebug_insn ()) { int need = singleton_vxrm_need (); if (need != VXRM_MODE_NONE) diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc index d91995a40592..8be9d595b277 100644 --- a/gcc/emit-rtl.cc +++ b/gcc/emit-rtl.cc @@ -3567,6 +3567,19 @@ get_first_nonnote_insn (void) return insn; } +/* Return the first nonnote, nondebug insn emitted in current sequence or + current function. This routine follows get_first_nonnote_insn into a + leading SEQUENCE. */ + +rtx_insn * +get_first_nonnote_nondebug_insn (void) +{ + rtx_insn *insn = get_first_nonnote_insn (); + while (insn && (NOTE_P (insn) || DEBUG_INSN_P (insn))) + insn = next_insn (insn); + return insn; +} + /* Return the last nonnote insn emitted in current sequence or current function. This routine looks inside SEQUENCEs. */ diff --git a/gcc/rtl.h b/gcc/rtl.h index 228121d70d74..db696d699f2b 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -3374,6 +3374,7 @@ extern rtx convert_memory_address_addr_space (scalar_int_mode, rtx, extern const char *get_insn_name (int); extern rtx_insn *get_last_insn_anywhere (void); extern rtx_insn *get_first_nonnote_insn (void); +extern rtx_insn *get_first_nonnote_nondebug_insn (void); extern rtx_insn *get_last_nonnote_insn (void); extern void start_sequence (void); extern void push_to_sequence (rtx_insn *); diff --git a/gcc/testsuite/gcc.target/aarch64/bti-debug-1.c b/gcc/testsuite/gcc.target/aarch64/bti-debug-1.c new file mode 100644 index 000000000000..c2d2a1bea771 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/bti-debug-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* PR target/127934 */ +/* { dg-options "-O2 -mbranch-protection=standard -g -fno-var-tracking -fcompare-debug" } */ + +int g (int); + +int +f (int x) +{ + int y = g (x); + + return g (y) + 1; +} + +/* { dg-final { scan-assembler "hint\t25 // paciasp" } } */ +/* { dg-final { scan-assembler-not "hint\t34 // bti c" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vxrm-debug-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vxrm-debug-1.c new file mode 100644 index 000000000000..c1ef806e7647 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vxrm-debug-1.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* PR target/127936 */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -g -fcompare-debug" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "riscv_vector.h" + +/* +** f: +** csrwi\tvxrm,2 +** ... +** ble\t[a-z0-9]+,zero,\.L[0-9]+ +** ... +*/ + +void +f (void *in, void *out, int n) +{ + for (int i = 0; i < n; ++i) + { + vint32m1_t v = __riscv_vle32_v_i32m1 (in + i, 4); + vint32m1_t v2 + = __riscv_vle32_v_i32m1_tu (v, in + 100 + i, 4); + vint32m1_t v3 + = __riscv_vaadd_vx_i32m1 (v2, 0, __RISCV_VXRM_RDN, 4); + asm volatile ("csrwi\tvxrm,1"); + v3 = __riscv_vaadd_vx_i32m1 (v3, 3, __RISCV_VXRM_RDN, 4); + __riscv_vse32_v_i32m1 (out + 100 + i, v3, 4); + } +} + +/* { dg-final { scan-assembler-times {csrwi\s+vxrm,\s*2} 2 } } */
