[gcc r14-7196] middle-end: thread through existing LCSSA variable for alternative exits too [PR113237]

Tamar Christina tnfchris@gcc.gnu.org
Fri Jan 12 15:32:44 GMT 2024


https://gcc.gnu.org/g:99c0a540d6689ede068f9ba98af6f38c3cd71362

commit r14-7196-g99c0a540d6689ede068f9ba98af6f38c3cd71362
Author: Tamar Christina <tamar.christina@arm.com>
Date:   Fri Jan 12 15:25:58 2024 +0000

    middle-end: thread through existing LCSSA variable for alternative exits too [PR113237]
    
    Builing on top of the previous patch, similar to when we have a single exit if
    we have a case where all exits are considered early exits and there are existing
    non virtual phi then in order to maintain LCSSA we have to use the existing PHI
    variables.  We can't simply clear them and just rebuild them because the order
    of the PHIs in the main exit must match the original exit for when we add the
    skip_epilog guard.
    
    But the infrastructure is already in place to maintain them, we just have to use
    the right value.
    
    gcc/ChangeLog:
    
            PR tree-optimization/113237
            * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg): Use
            existing LCSSA variable for exit when all exits are early break.
    
    gcc/testsuite/ChangeLog:
    
            PR tree-optimization/113237
            * gcc.dg/vect/vect-early-break_98-pr113237.c: New test.

Diff:
---
 .../gcc.dg/vect/vect-early-break_98-pr113237.c       | 20 ++++++++++++++++++++
 gcc/tree-vect-loop-manip.cc                          |  9 +++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_98-pr113237.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_98-pr113237.c
new file mode 100644
index 00000000000..e6d150b571f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_98-pr113237.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+long Perl_pp_split_limit;
+int Perl_block_gimme();
+int Perl_pp_split() {
+  char strend;
+  long iters;
+  int gimme = Perl_block_gimme();
+  while (--Perl_pp_split_limit) {
+    if (gimme)
+      iters++;
+    if (strend)
+      break;
+  }
+  if (iters)
+    return 0;
+}
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index da64738c710..2a1f9cd7707 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -1697,10 +1697,15 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
 		 virtual operands we have to keep the original link.   Virtual
 		 operands don't all become the same because we'll corrupt the
 		 vUSE chains among others.  */
-	      if (peeled_iters && !virtual_operand_p (new_arg))
+	      if (peeled_iters)
 		{
 		  tree tmp_arg = gimple_phi_result (from_phi);
-		  if (!new_phi_args.get (tmp_arg))
+		  /* Similar to the single exit case, If we have an existing
+		     LCSSA variable thread through the original value otherwise
+		     skip it and directly use the final value.  */
+		  if (tree *res = new_phi_args.get (tmp_arg))
+		    new_arg = *res;
+		  else if (!virtual_operand_p (new_arg))
 		    new_arg = tmp_arg;
 		}


More information about the Gcc-cvs mailing list