A DEBUG_INSN can retain a volatile MEM after the corresponding ordinary
instruction has been deleted. Do not treat that non-executing payload as an
intervening volatile access in can_combine_p.
PR rtl-optimization/127422
gcc/ChangeLog:
* combine.cc (can_combine_p): Ignore debug instructions when scanning
for intervening volatile references.
gcc/testsuite/ChangeLog:
* gcc.dg/pr127422.c: New test.
Assisted-by: OpenAI Codex 5.6 Sol, co-reviewed by Claude and Yongqiang Tian.
Signed-off-by: Yongqiang Tian <[email protected]>
---
gcc/combine.cc | 5 ++++-
gcc/testsuite/gcc.dg/pr127422.c | 35 +++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.dg/pr127422.c
diff --git a/gcc/combine.cc b/gcc/combine.cc
index 35c6a529950..11427f5a920 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -2024,7 +2024,10 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn
*pred ATTRIBUTE_UNUSED,
: volatile_insn_p;
for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
- if (INSN_P (p) && p != succ && p != succ2 && is_volatile_p (PATTERN (p)))
+ if (NONDEBUG_INSN_P (p)
+ && p != succ
+ && p != succ2
+ && is_volatile_p (PATTERN (p)))
return false;
/* If INSN contains an autoincrement or autodecrement, make sure that
diff --git a/gcc/testsuite/gcc.dg/pr127422.c b/gcc/testsuite/gcc.dg/pr127422.c
new file mode 100644
index 00000000000..bba30ad7844
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr127422.c
@@ -0,0 +1,35 @@
+/* PR rtl-optimization/127422 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcompare-debug" } */
+
+static int ordinary_0 = 3;
+static int ordinary_1 = 22;
+static volatile int effect_0 = 6;
+static volatile int effect_1 = 23;
+static int ordinary_2 = 41;
+__attribute__ ((used)) int *ordinary_escape[]
+ = { &ordinary_0, &ordinary_1, &ordinary_2 };
+
+static inline __attribute__ ((always_inline))
+unsigned long long
+accumulate (unsigned long long acc, unsigned long long val)
+{
+ return acc + val;
+}
+
+unsigned long long
+foo (void)
+{
+ int staged_ordinary_0 = ordinary_0;
+ int staged_ordinary_1 = ordinary_1;
+ int staged_effect_0 = effect_0;
+ int staged_effect_1 = effect_1;
+ int staged_ordinary_2 = ordinary_2;
+ unsigned long long sum = 0;
+ sum = accumulate (sum, staged_ordinary_0);
+ sum = accumulate (sum, staged_ordinary_1);
+ sum = accumulate (sum, staged_effect_0);
+ sum = accumulate (sum, staged_effect_1);
+ sum = accumulate (sum, staged_ordinary_2);
+ return sum;
+}
--
2.34.1