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

Reply via email to