tree-optimization/116879 - failure to recognize non-empty latch

Message ID 20240930141923.C7DEE13A8B@imap1.dmz-prg2.suse.org
State Committed
Commit 18e905b461a7138185cf4f0efde4a4e1214fb798
Headers
Series tree-optimization/116879 - failure to recognize non-empty latch |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm warning Patch is already merged
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 warning Patch is already merged

Commit Message

Richard Biener Sept. 30, 2024, 2:19 p.m. UTC
  When we relaxed the vectorizers constraint on loop structure verifying
the emptiness of the latch became too lose as can be seen in the case
for PR116879 where the latch effectively contains two basic-blocks
which one being an unmerged forwarder that's not empty.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	PR tree-optimization/116879
	* tree-vect-loop.cc (vect_analyze_loop_form): Scan all
	blocks that form the latch.

	* gcc.dg/pr116879.c: New testcase.
---
 gcc/testsuite/gcc.dg/pr116879.c | 15 +++++++++++++++
 gcc/tree-vect-loop.cc           | 15 +++++++++++----
 2 files changed, 26 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr116879.c
  

Patch

diff --git a/gcc/testsuite/gcc.dg/pr116879.c b/gcc/testsuite/gcc.dg/pr116879.c
new file mode 100644
index 00000000000..73ddb2b658c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr116879.c
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fallow-store-data-races -fno-tree-ch -ftree-loop-distribution" } */
+
+static int b;
+int *a, c, *d = &c;
+int main() {
+  int e = 0;
+  for (; e < 8; e = (char)(e + 1)) {
+    int *f = &b, g[8], h = 0;
+    for (; h < 8; h++)
+      g[h] = 0;
+    --*f != (*d = g[0] || a);
+  }
+  return 0;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 5cd4bdb32e0..0ce1bf8ebba 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -1851,10 +1851,17 @@  vect_analyze_loop_form (class loop *loop, vect_loop_form_info *info)
 				   " too many incoming edges.\n");
 
   /* We assume that the latch is empty.  */
-  if (!empty_block_p (loop->latch)
-      || !gimple_seq_empty_p (phi_nodes (loop->latch)))
-    return opt_result::failure_at (vect_location,
-				   "not vectorized: latch block not empty.\n");
+  basic_block latch = loop->latch;
+  do
+    {
+      if (!empty_block_p (latch)
+	  || !gimple_seq_empty_p (phi_nodes (latch)))
+	return opt_result::failure_at (vect_location,
+				       "not vectorized: latch block not "
+				       "empty.\n");
+      latch = single_pred (latch);
+    }
+  while (single_succ_p (latch));
 
   /* Make sure there is no abnormal exit.  */
   auto_vec<edge> exits = get_loop_exit_edges (loop);