aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-02-12 11:20:10 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2025-02-20 08:38:41 +0100
commit94d01a884702934bc03ccedff62e2c65515c8c83 (patch)
treec3bd123e7381217f39d5b869307194756224d5a8 /gcc
parent83bc61c9fd6581d0a4c4ee16bdfdaeedcdd6ebcd (diff)
downloadgcc-94d01a884702934bc03ccedff62e2c65515c8c83.zip
gcc-94d01a884702934bc03ccedff62e2c65515c8c83.tar.gz
gcc-94d01a884702934bc03ccedff62e2c65515c8c83.tar.bz2
tree-optimization/86270 - improve SSA coalescing for loop exit test
The PR indicates a very specific issue with regard to SSA coalescing failures because there's a pre IV increment loop exit test. While IVOPTs created the desired IL we later simplify the exit test into the undesirable form again. The following fixes this up during RTL expansion where we try to improve coalescing of IVs. That seems easier that trying to avoid the simplification with some weird heuristics (it could also have been written this way). PR tree-optimization/86270 * tree-outof-ssa.cc (insert_backedge_copies): Pattern match a single conflict in a loop condition and adjust that avoiding the conflict if possible. * gcc.target/i386/pr86270.c: Adjust to check for no reg-reg copies as well.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.target/i386/pr86270.c3
-rw-r--r--gcc/tree-outof-ssa.cc61
2 files changed, 59 insertions, 5 deletions
diff --git a/gcc/testsuite/gcc.target/i386/pr86270.c b/gcc/testsuite/gcc.target/i386/pr86270.c
index 6856244..89b9aeb 100644
--- a/gcc/testsuite/gcc.target/i386/pr86270.c
+++ b/gcc/testsuite/gcc.target/i386/pr86270.c
@@ -13,3 +13,6 @@ test ()
/* Check we do not split the backedge but keep nice loop form. */
/* { dg-final { scan-assembler-times "L\[0-9\]+:" 2 } } */
+/* Check we do not end up with reg-reg moves from a pre-increment IV
+ exit test. */
+/* { dg-final { scan-assembler-not "mov\[lq\]\?\t%\?\[er\].x, %\?\[er\].x" } } */
diff --git a/gcc/tree-outof-ssa.cc b/gcc/tree-outof-ssa.cc
index d340d4b..c2fe398 100644
--- a/gcc/tree-outof-ssa.cc
+++ b/gcc/tree-outof-ssa.cc
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-outof-ssa.h"
#include "dojump.h"
#include "internal-fn.h"
+#include "gimple-fold.h"
/* FIXME: A lot of code here deals with expanding to RTL. All that code
should be in cfgexpand.cc. */
@@ -1259,10 +1260,10 @@ insert_backedge_copies (void)
if (gimple_nop_p (def)
|| gimple_code (def) == GIMPLE_PHI)
continue;
- tree name = copy_ssa_name (result);
- gimple *stmt = gimple_build_assign (name, result);
imm_use_iterator imm_iter;
gimple *use_stmt;
+ auto_vec<use_operand_p, 8> uses;
+ int idx = -1;
/* The following matches trivially_conflicts_p. */
FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, result)
{
@@ -1273,11 +1274,61 @@ insert_backedge_copies (void)
{
use_operand_p use;
FOR_EACH_IMM_USE_ON_STMT (use, imm_iter)
- SET_USE (use, name);
+ {
+ uses.safe_push (use);
+ if (!is_gimple_debug (use_stmt))
+ {
+ if (idx == -1)
+ idx = uses.length () - 1;
+ else
+ idx = -2;
+ }
+ }
}
}
- gimple_stmt_iterator gsi = gsi_for_stmt (def);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ /* When there is just a conflicting statement try to
+ adjust that to refer to the new definition.
+ In particular for now handle a conflict with the
+ use in a (exit) condition with a NE compare,
+ replacing a pre-IV-increment compare with a
+ post-IV-increment one. */
+ if (idx >= 0
+ && is_a <gcond *> (USE_STMT (uses[idx]))
+ && (gimple_cond_code (USE_STMT (uses[idx])) == NE_EXPR
+ || gimple_cond_code (USE_STMT (uses[idx])) == EQ_EXPR)
+ && is_gimple_assign (def)
+ && gimple_assign_rhs1 (def) == result
+ && (gimple_assign_rhs_code (def) == PLUS_EXPR
+ || gimple_assign_rhs_code (def) == MINUS_EXPR
+ || gimple_assign_rhs_code (def) == POINTER_PLUS_EXPR)
+ && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
+ {
+ gcond *cond = as_a <gcond *> (USE_STMT (uses[idx]));
+ tree *adj;
+ if (gimple_cond_lhs (cond) == result)
+ adj = gimple_cond_rhs_ptr (cond);
+ else
+ adj = gimple_cond_lhs_ptr (cond);
+ gimple_stmt_iterator gsi = gsi_for_stmt (cond);
+ tree newval
+ = gimple_build (&gsi, true, GSI_SAME_STMT,
+ UNKNOWN_LOCATION,
+ gimple_assign_rhs_code (def),
+ TREE_TYPE (*adj),
+ *adj, gimple_assign_rhs2 (def));
+ *adj = newval;
+ SET_USE (uses[idx], arg);
+ update_stmt (cond);
+ }
+ else
+ {
+ tree name = copy_ssa_name (result);
+ gimple *stmt = gimple_build_assign (name, result);
+ gimple_stmt_iterator gsi = gsi_for_stmt (def);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ for (auto use : uses)
+ SET_USE (use, name);
+ }
}
}
}