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.
Ok to apply?
Johann
--
PR target/127188
gcc/
* 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.
diff --git a/gcc/config/avr/avr-passes.cc b/gcc/config/avr/avr-passes.cc
index 73608de4f83..6091bdf3aa3 100644
--- a/gcc/config/avr/avr-passes.cc
+++ b/gcc/config/avr/avr-passes.cc
@@ -4923,18 +4923,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;
@@ -4974,7 +4975,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 00000000000..f2c5145b4c1
--- /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;
+}