Since flow_active_insn_p has:
if ((GET_CODE (PATTERN (insn)) == CLOBBER
|| GET_CODE (PATTERN (insn)) == USE)
&& REG_P (XEXP (PATTERN (insn), 0))
&& REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))
return true;
update DCE to always keep return value clobber.
Adjust assembly scan in gcc.target/i386/zero-scratch-regs-30.c to also
expect 8 "fstp %st(0)" in 64-bit mode for extra insns:
flds .LC2(%rip) // +QNaN
flds .LC2(%rip) // +QNaN
fstp %st(0)
fstp %st(0)
since return value clobber:
(insn 10 2 11 2 (clobber (reg/i:XC 8 st)) "zero-scratch-regs-30.c":7:1 -1
(nil))
is no longer removed as without -fzero-call-used-regs=all.
PR rtl-optimization/125375
* dce.cc: (deletable_insn_p): Always keep return value clobber.
gcc/testsuite/
PR rtl-optimization/125375
* gcc.target/i386/pr125375.c: New test.
* gcc.target/i386/zero-scratch-regs-30.c: Also expect 8
"fstp %st(0)" in 64-bit mode.
Signed-off-by: H.J. Lu <[email protected]>
Co-Developed-by: Andrew Pinski <[email protected]>
--
H.J.
From 16e73aea9e4962c9f14caaa7cecc14322cf83411 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Thu, 21 May 2026 08:26:49 +0800
Subject: [PATCH] dce: Always keep return value clobber
Since flow_active_insn_p has:
if ((GET_CODE (PATTERN (insn)) == CLOBBER
|| GET_CODE (PATTERN (insn)) == USE)
&& REG_P (XEXP (PATTERN (insn), 0))
&& REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))
return true;
update DCE to always keep return value clobber.
Adjust assembly scan in gcc.target/i386/zero-scratch-regs-30.c to also
expect 8 "fstp %st(0)" in 64-bit mode for extra insns:
flds .LC2(%rip) // +QNaN
flds .LC2(%rip) // +QNaN
fstp %st(0)
fstp %st(0)
since return value clobber:
(insn 10 2 11 2 (clobber (reg/i:XC 8 st)) "zero-scratch-regs-30.c":7:1 -1
(nil))
is no longer removed as without -fzero-call-used-regs=all.
PR rtl-optimization/125375
* dce.cc: (deletable_insn_p): Always keep return value clobber.
gcc/testsuite/
PR rtl-optimization/125375
* gcc.target/i386/pr125375.c: New test.
* gcc.target/i386/zero-scratch-regs-30.c: Also expect 8
"fstp %st(0)" in 64-bit mode.
Signed-off-by: H.J. Lu <[email protected]>
Co-Developed-by: Andrew Pinski <[email protected]>
---
gcc/dce.cc | 7 ++--
gcc/testsuite/gcc.target/i386/pr125375.c | 36 +++++++++++++++++++
.../gcc.target/i386/zero-scratch-regs-30.c | 3 +-
3 files changed, 42 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr125375.c
diff --git a/gcc/dce.cc b/gcc/dce.cc
index 693baab6386..7907140771c 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -178,9 +178,12 @@ deletable_insn_p (rtx_insn *insn, bool fast, bitmap arg_stores)
{
/* A CLOBBER of a dead pseudo register serves no purpose.
That is not necessarily true for hard registers until
- after reload. */
+ after reload. Always keep function return value clobber.
+ */
x = XEXP (body, 0);
- return REG_P (x) && (!HARD_REGISTER_P (x) || reload_completed);
+ return (REG_P (x)
+ && !REG_FUNCTION_VALUE_P (x)
+ && (!HARD_REGISTER_P (x) || reload_completed));
}
else
/* Because of the way that use-def chains are built, it is not
diff --git a/gcc/testsuite/gcc.target/i386/pr125375.c b/gcc/testsuite/gcc.target/i386/pr125375.c
new file mode 100644
index 00000000000..7654d23b9dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr125375.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-inline -fno-compare-elim" } */
+
+int a, c = 1;
+short b = 1, e;
+volatile
+unsigned short d;
+static int
+f(void)
+{
+ unsigned g = 2;
+ if (c >= a)
+ if ((c || b) && b)
+ {
+ unsigned h = c && d;
+ int i = e = d;
+ if (d)
+ i = d = 0;
+ g = c ^ g * i;
+ c = ~c;
+ b = b * (g | 9) & ((1 && a) - i);
+ h && i && d;
+ a = c ^ e ^ (g && a) * h;
+ d = e;
+ if (a)
+ return g;
+ }
+}
+
+int
+main(void)
+{
+ if (f() != 1)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/zero-scratch-regs-30.c b/gcc/testsuite/gcc.target/i386/zero-scratch-regs-30.c
index c4e99303d22..5cf4a435162 100644
--- a/gcc/testsuite/gcc.target/i386/zero-scratch-regs-30.c
+++ b/gcc/testsuite/gcc.target/i386/zero-scratch-regs-30.c
@@ -7,6 +7,5 @@ _Complex long double ret_x87_cplx (void)
}
/* { dg-final { scan-assembler-times "fldz" 8 { target ia32 } } } */
-/* { dg-final { scan-assembler-times "fstp\[ \t\]+%st\\(0\\)" 8 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "fstp\[ \t\]+%st\\(0\\)" 8 } } */
/* { dg-final { scan-assembler-times "fldz" 6 { target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-times "fstp\[ \t\]+%st\\(0\\)" 6 { target { ! ia32 } } } } */
--
2.54.0