diff options
author | Richard Biener <rguenther@suse.de> | 2025-02-28 10:36:11 +0100 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2025-02-28 12:38:00 +0100 |
commit | 535115caaf97f5201fb528f67f15b4c52be5619d (patch) | |
tree | bc7b66797e4fe1190f14b73318addddb1262303f /gcc | |
parent | 95f5d6cc17e7d6b689674756c62b6b5e1284afd0 (diff) | |
download | gcc-535115caaf97f5201fb528f67f15b4c52be5619d.zip gcc-535115caaf97f5201fb528f67f15b4c52be5619d.tar.gz gcc-535115caaf97f5201fb528f67f15b4c52be5619d.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr87984.c | 23 | ||||
-rw-r--r-- | gcc/tree-ssa-dom.cc | 4 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.cc | 2 |
3 files changed, 28 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.target/i386/pr87984.c b/gcc/testsuite/gcc.target/i386/pr87984.c new file mode 100644 index 0000000..39a6a74 --- /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 291c3a4..b1ac35e 100644 --- a/gcc/tree-ssa-dom.cc +++ b/gcc/tree-ssa-dom.cc @@ -2454,7 +2454,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 1468406..5a8c7c3 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -7081,6 +7081,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)))) { |