[PATCH] tree-optimization/126865 - SLP node with trapping stmt in wrong BB

Richard Biener <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
The following fixes a SLP discovery issue where we fail to properly
ensure that when there's a trapping stmt all stmts of a node belong
to the same BB.

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

	PR tree-optimization/126865
	* tree-vect-slp.cc (vect_build_slp_tree_1): Track common
	BB and whether there's any trapping stmt in the matching set
	and verify the same BB constraint after we've seen all stmts.

	* gcc.dg/vect/bb-slp-pr126865.c: New testcase.
	* gcc.dg/vect/bb-slp-pr100778-1.c: Adjust.
---
 gcc/testsuite/gcc.dg/vect/bb-slp-pr100778-1.c |  2 +-
 gcc/testsuite/gcc.dg/vect/bb-slp-pr126865.c   | 13 +++++++++
 gcc/tree-vect-slp.cc                          | 27 ++++++++++++++++---
 3 files changed, 38 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr126865.c

diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr100778-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr100778-1.c
index 9f8b7eecef1..a5ec4f148c6 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr100778-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr100778-1.c
@@ -15,4 +15,4 @@ double foo (int x, double *p)
 
 /* We may not SLP vectorize the FP division because it can trap and it
    is distributed between two basic-blocks.  */
-/* { dg-final { scan-tree-dump "Build SLP failed: different BB for PHI or possibly trapping operation in _\[0-9\]+ = _\[0-9\]+ / _\[0-9\]+;" "slp2" } } */
+/* { dg-final { scan-tree-dump "Build SLP failed: not all stmts in same BB but possibly trapping operation in tem_\[0-9\]+ = _\[0-9\]+ / _\[0-9\]+;" "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr126865.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr126865.c
new file mode 100644
index 00000000000..ab00f3208b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr126865.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+uint16_t g2, g24, g11;
+_Bool g28_c11;
+uint16_t g28()
+{
+  g24 = 10690 / (int16_t)g2;
+  if (g28_c11)
+    g11 = (int16_t)(uintptr_t)g28 / 9 + g24;
+  __builtin_abort();
+}
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index d6515be26d1..c9f835358c0 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -1207,6 +1207,9 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
   gcc_assert (vectype || !gimple_get_lhs (first_stmt_info->stmt));
   *node_vectype = vectype;
 
+  basic_block common_bb = gimple_bb (first_stmt_info->stmt);
+  gimple *trapping_stmt = NULL;
+
   /* For every stmt in NODE find its def stmt/s.  */
   stmt_vec_info stmt_info;
   FOR_EACH_VEC_ELT (stmts, i, stmt_info)
@@ -1495,14 +1498,14 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
 		}
 	    }
 
-	  if ((phi_p || gimple_could_trap_p (stmt_info->stmt))
+	  if (phi_p
 	      && (gimple_bb (first_stmt_info->stmt)
 		  != gimple_bb (stmt_info->stmt)))
 	    {
 	      if (dump_enabled_p ())
 		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-				 "Build SLP failed: different BB for PHI "
-				 "or possibly trapping operation in %G", stmt);
+				 "Build SLP failed: different BB for PHI %G",
+				 stmt);
 	      /* Mismatch.  */
 	      continue;
 	    }
@@ -1681,9 +1684,27 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
 	    swap[i] = 1;
 	}
 
+      /* We need to ensure all stmts are in the same BB when one stmt could
+	 trap.  Not matching stmts are not relevant, so exclude those.  */
+      if (!trapping_stmt && gimple_could_trap_p (stmt))
+	trapping_stmt = stmt;
+      if (common_bb != gimple_bb (stmt))
+	common_bb = NULL;
+
       matches[i] = true;
     }
 
+  if (trapping_stmt && common_bb == NULL)
+    {
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+			 "Build SLP failed: not all stmts in same BB but "
+			 "possibly trapping operation in %G", trapping_stmt);
+      /* Fatal mismatch.  */
+      matches[0] = false;
+      return false;
+    }
+
   for (i = 0; i < group_size; ++i)
     if (!matches[i])
       return false;
-- 
2.51.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.