public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-5657] rtl-ssa: Fix splitting of clobber groups [PR108508]
@ 2023-02-02 14:53 Richard Sandiford
  0 siblings, 0 replies; only message in thread
From: Richard Sandiford @ 2023-02-02 14:53 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:f4e1b46618ef3bd7933992ab79f663ab9112bb80

commit r13-5657-gf4e1b46618ef3bd7933992ab79f663ab9112bb80
Author: Richard Sandiford <richard.sandiford@arm.com>
Date:   Thu Feb 2 14:53:34 2023 +0000

    rtl-ssa: Fix splitting of clobber groups [PR108508]
    
    Since rtl-ssa isn't a real/native SSA representation, it has
    to honour the constraints of the underlying rtl representation.
    Part of this involves maintaining an rpo list of definitions
    for each rtl register, backed by a splay tree where necessary
    for quick lookup/insertion.
    
    However, clobbers of a register don't act as barriers to
    other clobbers of a register.  E.g. it's possible to move one
    flag-clobbering instruction across an arbitrary number of other
    flag-clobbering instructions.  In order to allow passes to do
    that without quadratic complexity, the splay tree groups all
    consecutive clobbers into groups, with only the group being
    entered into the splay tree.  These groups in turn have an
    internal splay tree of clobbers where necessary.
    
    This means that, if we insert a new definition and use into
    the middle of a sea of clobbers, we need to split the clobber
    group into two groups.  This was quite a difficult condition
    to trigger during development, and the PR shows that the code
    to handle it had (at least) two bugs.
    
    First, the process involves searching the clobber tree for
    the split point.  This search can give either the previous
    clobber (which will belong to the first of the split groups)
    or the next clobber (which will belong to the second of the
    split groups).  The code for the former case handled the
    split correctly but the code for the latter case didn't.
    
    Second, I'd forgotten to add the second clobber group to the
    main splay tree. :-(
    
    gcc/
            PR rtl-optimization/108508
            * rtl-ssa/accesses.cc (function_info::split_clobber_group): When
            the splay tree search gives the first clobber in the second group,
            make sure that the root of the first clobber group is updated
            correctly.  Enter the new clobber group into the definition splay
            tree.
    
    gcc/testsuite/
            PR rtl-optimization/108508
            * gcc.target/aarch64/pr108508.c: New test.

Diff:
---
 gcc/rtl-ssa/accesses.cc                     | 14 ++++++++++----
 gcc/testsuite/gcc.target/aarch64/pr108508.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/gcc/rtl-ssa/accesses.cc b/gcc/rtl-ssa/accesses.cc
index 03b9a475d3b..f12b5f4dd77 100644
--- a/gcc/rtl-ssa/accesses.cc
+++ b/gcc/rtl-ssa/accesses.cc
@@ -794,23 +794,26 @@ function_info::merge_clobber_groups (clobber_info *clobber1,
 // GROUP spans INSN, and INSN now sets the resource that GROUP clobbers.
 // Split GROUP around INSN and return the clobber that comes immediately
 // before INSN.
+//
+// The resource that GROUP clobbers is known to have an associated
+// splay tree.
 clobber_info *
 function_info::split_clobber_group (clobber_group *group, insn_info *insn)
 {
   // Search for either the previous or next clobber in the group.
   // The result is less than zero if CLOBBER should come before NEIGHBOR
   // or greater than zero if CLOBBER should come after NEIGHBOR.
-  int comparison = lookup_clobber (group->m_clobber_tree, insn);
+  clobber_tree &tree1 = group->m_clobber_tree;
+  int comparison = lookup_clobber (tree1, insn);
   gcc_checking_assert (comparison != 0);
-  clobber_info *neighbor = group->m_clobber_tree.root ();
+  clobber_info *neighbor = tree1.root ();
 
-  clobber_tree tree1, tree2;
+  clobber_tree tree2;
   clobber_info *prev;
   clobber_info *next;
   if (comparison > 0)
     {
       // NEIGHBOR is the last clobber in what will become the first group.
-      tree1 = neighbor;
       tree2 = tree1.split_after_root ();
       prev = neighbor;
       next = as_a<clobber_info *> (prev->next_def ());
@@ -843,6 +846,9 @@ function_info::split_clobber_group (clobber_group *group, insn_info *insn)
   tree2->set_group (group2);
   last_clobber->set_group (group2);
 
+  // Insert GROUP2 into the splay tree as an immediate successor of GROUP1.
+  def_splay_tree::insert_child (group1, 1, group2);
+
   return prev;
 }
 
diff --git a/gcc/testsuite/gcc.target/aarch64/pr108508.c b/gcc/testsuite/gcc.target/aarch64/pr108508.c
new file mode 100644
index 00000000000..e97896b6a1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr108508.c
@@ -0,0 +1,28 @@
+/* { dg-options "-O3 -fharden-conditional-branches -fno-dce -fno-guess-branch-probability" } */
+
+#include <arm_neon.h>
+
+int
+test_vld3q_lane_f64 (void)
+{
+  float64x2x3_t vectors;
+  float64_t temp[2];
+  int i, j;
+
+  for (i = 0; i < 3; i++)
+  {
+    vst1q_f64 (temp, vectors.val[i]);
+    for (j = 0; j < 2; j++)
+      if (temp[j])
+        return 1;
+  }
+
+  return 0;
+}
+
+void
+foo (void)
+{
+  if (test_vld3q_lane_f64 () || test_vld3q_lane_f64 ())
+    __builtin_abort ();
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-02-02 14:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-02 14:53 [gcc r13-5657] rtl-ssa: Fix splitting of clobber groups [PR108508] Richard Sandiford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).