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 } } */

Reply via email to