For h8300-elf, gcc.dg/pr114768.c fails when compiled with -O2 -msx since
cselib_redundant_set_p returns true when called with

(gdb) call debug (set)
(set (mem:HI (reg/f:SI 0 r0 [orig:21 p ] [21]) [1 *p_3(D)+0 S2 A16])
    (mem/v:HI (reg/f:SI 0 r0 [orig:21 p ] [21]) [1 MEM[(volatile int
*)p_3(D)]+0 S2 A16]))
(gdb)

from reload_cse_regs.  Update cselib_redundant_set_p to return false for
volatile memory source or destination.

gcc/

PR target/122343
* cselib.cc (cselib_redundant_set_p): Return false for volatile
memory source or destination.

gcc/testsuite/

PR target/122343
* gcc.dg/pr122343-1.c: New test.


-- 
H.J.
From 7b6aa7c61740abca75d4922340b516d2d64c74a2 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Wed, 17 Dec 2025 12:18:15 +0800
Subject: [PATCH] cse: Check volatile memory in cselib_redundant_set_p

For h8300-elf, gcc.dg/pr114768.c fails when compiled with -O2 -msx since
cselib_redundant_set_p returns true when called with

(gdb) call debug (set)
(set (mem:HI (reg/f:SI 0 r0 [orig:21 p ] [21]) [1 *p_3(D)+0 S2 A16])
    (mem/v:HI (reg/f:SI 0 r0 [orig:21 p ] [21]) [1 MEM[(volatile int *)p_3(D)]+0 S2 A16]))
(gdb)

from reload_cse_regs.  Update cselib_redundant_set_p to return false for
volatile memory source or destination.

gcc/

	PR target/122343
	* cselib.cc (cselib_redundant_set_p): Return false for volatile
	memory source or destination.

gcc/testsuite/

	PR target/122343
	* gcc.dg/pr122343-1.c: New test.

Signed-off-by: H.J. Lu <[email protected]>
---
 gcc/cselib.cc                     | 8 ++++++--
 gcc/testsuite/gcc.dg/pr122343-1.c | 9 +++++++++
 2 files changed, 15 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr122343-1.c

diff --git a/gcc/cselib.cc b/gcc/cselib.cc
index 930357409bc..5d78675c4ba 100644
--- a/gcc/cselib.cc
+++ b/gcc/cselib.cc
@@ -1194,7 +1194,9 @@ cselib_redundant_set_p (rtx set)
   if (cselib_reg_set_mode (dest) != GET_MODE (dest))
     return false;
 
-  if (!rtx_equal_for_cselib_p (dest, SET_SRC (set)))
+  rtx src = SET_SRC (set);
+  if ((MEM_P (src) && MEM_VOLATILE_P (src))
+       || !rtx_equal_for_cselib_p (dest, src))
     return false;
 
   while (GET_CODE (dest) == SUBREG
@@ -1205,6 +1207,9 @@ cselib_redundant_set_p (rtx set)
   if (!flag_strict_aliasing || !MEM_P (dest))
     return true;
 
+  if (MEM_VOLATILE_P (dest))
+    return false;
+
   /* For a store we need to check that suppressing it will not change
      the effective alias set.  */
   rtx dest_addr = XEXP (dest, 0);
@@ -1242,7 +1247,6 @@ cselib_redundant_set_p (rtx set)
   /* We failed to find a recorded value in the cselib history, so try
      the source of this set; this catches cases such as *p = *q when p
      and q have the same value.  */
-  rtx src = SET_SRC (set);
   while (GET_CODE (src) == SUBREG)
     src = XEXP (src, 0);
 
diff --git a/gcc/testsuite/gcc.dg/pr122343-1.c b/gcc/testsuite/gcc.dg/pr122343-1.c
new file mode 100644
index 00000000000..b1fd0f0abc2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr122343-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-final" } */
+/* { dg-final { scan-rtl-dump "\\\(mem/v:" "final" } } */
+
+void
+foo (int *p)
+{
+  *(volatile int *) p = *p;
+}
-- 
2.52.0

Reply via email to