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)))) {