https://gcc.gnu.org/g:3b84ac64816557e6c953984f096e0995f946e063

commit r14-11502-g3b84ac64816557e6c953984f096e0995f946e063
Author: Richard Biener <rguent...@suse.de>
Date:   Fri Feb 28 10:36:11 2025 +0100

    tree-optimization/87984 - hard register assignments not preserved
    
    The following disables redundant store elimination to hard register
    variables which isn't valid.
    
            PR tree-optimization/87984
            * tree-ssa-dom.cc (dom_opt_dom_walker::optimize_stmt): Do
            not perform redundant store elimination to hard register
            variables.
            * tree-ssa-sccvn.cc (eliminate_dom_walker::eliminate_stmt):
            Likewise.
    
            * gcc.target/i386/pr87984.c: New testcase.
    
    (cherry picked from commit 535115caaf97f5201fb528f67f15b4c52be5619d)

Diff:
---
 gcc/testsuite/gcc.target/i386/pr87984.c | 23 +++++++++++++++++++++++
 gcc/tree-ssa-dom.cc                     |  4 +++-
 gcc/tree-ssa-sccvn.cc                   |  2 ++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/i386/pr87984.c 
b/gcc/testsuite/gcc.target/i386/pr87984.c
new file mode 100644
index 000000000000..39a6a7480f9e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr87984.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+__attribute__((noipa))
+int f(void)
+{
+  int o = 0;
+  for (int i = 0; i < 3; i++)
+    {
+      register int a asm("eax");
+      a = 1;
+      asm("add %1, %0" : "+r"(o) : "r"(a));
+      asm("xor %%eax, %%eax" ::: "eax");
+    }
+  return o;
+}
+
+int main()
+{
+  if (f() != 3)
+    __builtin_abort();
+  return 0;
+}
diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc
index 73264852ebd9..544e4ca7c7e9 100644
--- a/gcc/tree-ssa-dom.cc
+++ b/gcc/tree-ssa-dom.cc
@@ -2455,7 +2455,9 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, 
gimple_stmt_iterator *si,
 
       /* Perform simple redundant store elimination.  */
       if (gimple_assign_single_p (stmt)
-         && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
+         && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME
+         && (TREE_CODE (gimple_assign_lhs (stmt)) != VAR_DECL
+             || !DECL_HARD_REGISTER (gimple_assign_lhs (stmt))))
        {
          tree lhs = gimple_assign_lhs (stmt);
          tree rhs = gimple_assign_rhs1 (stmt);
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index ff27b75313e0..debfd1d04355 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -7084,6 +7084,8 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, 
gimple_stmt_iterator *gsi)
   if (gimple_assign_single_p (stmt)
       && !gimple_has_volatile_ops (stmt)
       && !is_gimple_reg (gimple_assign_lhs (stmt))
+      && (TREE_CODE (gimple_assign_lhs (stmt)) != VAR_DECL
+         || !DECL_HARD_REGISTER (gimple_assign_lhs (stmt)))
       && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
          || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
     {

Reply via email to