https://gcc.gnu.org/g:bf812363e66d58ea928e9b2daf3b28b71e4ec01d

commit r15-11545-gbf812363e66d58ea928e9b2daf3b28b71e4ec01d
Author: Georg-Johann Lay <[email protected]>
Date:   Fri Sep 4 13:14:10 2026 +0200

    AVR: target/127188 - Fix -fcompare-debug fail
    
    The transformations performed by the avr-2moves pass might depend
    on the presence of debug insns, which is fixed by this patch.
    
    It now uses next_nondebug_insn_bb() to traverses the insns in such a
    way that the seen insns don't depend on the presence of debug insns.
    
    Plus, it ignores debug insns when it traverses the DF_REG_USE_CHAIN
    of the considered register.
    
    The patch passes without new regression.  It fixes
    
      gcc.dg/pr103837.c (test for excess errors)
      gcc.dg/pr45865.c (test for excess errors)
    
    which failed with -fcompare-debug.
    
            PR target/127188
    gcc/
            * config/avr/avr-passes.cc (avr_pass_2moves) <optimize_2moves_bb>:
            Use next_nondebug_insn_bb to traverse the insns.
            <optimize_2moves>: Ignore degug insns when traversing
            DF_REG_USE_CHAIN.
    gcc/testsuite/
            * gcc.target/avr/pr127188.c: New test.
    
    (cherry picked from commit 740716f3b13102b93489eec8f3238aa1f356fe0b)

Diff:
---
 gcc/config/avr/avr-passes.cc            | 27 +++++++++++++++------------
 gcc/testsuite/gcc.target/avr/pr127188.c | 18 ++++++++++++++++++
 2 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/gcc/config/avr/avr-passes.cc b/gcc/config/avr/avr-passes.cc
index 56575d5539fb..1ea4f5a3885b 100644
--- a/gcc/config/avr/avr-passes.cc
+++ b/gcc/config/avr/avr-passes.cc
@@ -84,8 +84,7 @@ namespace
 {
 
 /////////////////////////////////////////////////////////////////////////////
-// Before we start with the very code, introduce some helpers that are
-// quite generic, though up to now only avr-fuse-add makes use of them.
+// Before we start with the very code, introduce some generic helpers.
 
 /* Get the next / previous NONDEBUG_INSN_P after INSN in basic block BB.
    This assumes we are in CFG layout mode so that BLOCK_FOR_INSN()
@@ -4925,18 +4924,19 @@ bool
 avr_pass_2moves::optimize_2moves_bb (basic_block bb)
 {
   bool changed = false;
-  rtx_insn *insn1 = nullptr;
-  rtx_insn *insn2 = nullptr;
-  rtx_insn *curr;
+  rtx_insn *insn1 = next_nondebug_insn_bb (bb, BB_HEAD (bb));
 
-  FOR_BB_INSNS (bb, curr)
+  while (insn1)
     {
-      if (insn1 && INSN_P (insn1)
-         && insn2 && INSN_P (insn2))
-       changed |= optimize_2moves (insn1, insn2);
+      rtx_insn *insn2 = next_nondebug_insn_bb (bb, insn1);
+      if (!insn2)
+       break;
+
+      rtx_insn *next = next_nondebug_insn_bb (bb, insn2);
 
-      insn1 = insn2;
-      insn2 = curr;
+      bool change = optimize_2moves (insn1, insn2);
+      changed |= change;
+      insn1 = change ? next : insn2;
     }
 
   return changed;
@@ -4976,7 +4976,10 @@ avr_pass_2moves::optimize_2moves (rtx_insn *insn1, 
rtx_insn *insn2)
       for (; use; use = DF_REF_NEXT_REG (use))
        {
          rtx_insn *user = DF_REF_INSN (use);
-         avr_dump (" %d", INSN_UID (user));
+         bool debug_p = DEBUG_INSN_P (user);
+         avr_dump (" %d%s", INSN_UID (user), debug_p ? "=debug_insn" : "");
+         if (debug_p)
+           continue;
          good |= INSN_UID (user) == INSN_UID (insn2);
          bad |= INSN_UID (user) != INSN_UID (insn2);
        }
diff --git a/gcc/testsuite/gcc.target/avr/pr127188.c 
b/gcc/testsuite/gcc.target/avr/pr127188.c
new file mode 100644
index 000000000000..f2c5145b4c15
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/pr127188.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcompare-debug" } */
+
+extern int foo (int);
+
+int bar (int a, int b)
+{
+  int q;
+  if (a < 0)
+    q = 0;
+  else
+    q = 1;
+  int c = foo (b);
+  if (q != 0)
+    c = foo (c);
+  int d = foo (c);
+  return d;
+}

Reply via email to