re PR tree-optimization/84859 (bogus -Warray-bounds on a memcpy in a loop)
authorRichard Biener <rguenther@suse.de>
Mon, 19 Mar 2018 14:08:58 +0000 (14:08 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 19 Mar 2018 14:08:58 +0000 (14:08 +0000)
2018-03-19  Richard Biener  <rguenther@suse.de>

PR tree-optimization/84859
* tree-ssa-phiopt.c (single_trailing_store_in_bb): New function.
(cond_if_else_store_replacement): Perform sinking operation on
single-store BBs regardless of MAX_STORES_TO_SINK setting.
Generalize what a BB with a single eligible store is.

* gcc.dg/tree-ssa/pr84859.c: New testcase.
* gcc.dg/tree-ssa/pr35286.c: Disable cselim.
* gcc.dg/tree-ssa/split-path-6.c: Likewise.
* gcc.dg/tree-ssa/split-path-7.c: Likewise.

From-SVN: r258645

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr35286.c
gcc/testsuite/gcc.dg/tree-ssa/pr84859.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c
gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c
gcc/tree-ssa-phiopt.c

index b5b55598f81dad9dec12ba5b8f9663f8f884ea1a..b27b28f44ffd59a69fee347c9150e8054b62409b 100644 (file)
@@ -1,3 +1,11 @@
+2018-03-19  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/84859
+       * tree-ssa-phiopt.c (single_trailing_store_in_bb): New function.
+       (cond_if_else_store_replacement): Perform sinking operation on
+       single-store BBs regardless of MAX_STORES_TO_SINK setting.
+       Generalize what a BB with a single eligible store is.
+
 2018-03-19  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/84929
index 337b4bd1f25229eda5519f8743d795b6c043fd83..9f462160a61406e0999d9db0656e29da79ed0f1d 100644 (file)
@@ -1,3 +1,11 @@
+2018-03-19  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/84859
+       * gcc.dg/tree-ssa/pr84859.c: New testcase.
+       * gcc.dg/tree-ssa/pr35286.c: Disable cselim.
+       * gcc.dg/tree-ssa/split-path-6.c: Likewise.
+       * gcc.dg/tree-ssa/split-path-7.c: Likewise.
+
 2018-03-19  Nathan Sidwell  <nathan@acm.org>
 
        PR c++/84812
index 8f683fbd1623e8e7e6136da155a48e5ca6655dea..4429cc857bf69a80a3d62991f920f2d8fb13dc82 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */ 
-/* { dg-options "-O2 -fno-code-hoisting -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fno-code-hoisting -fno-tree-cselim -fdump-tree-pre-stats" } */
 int g2;
 struct A {
     int a; int b;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr84859.c b/gcc/testsuite/gcc.dg/tree-ssa/pr84859.c
new file mode 100644 (file)
index 0000000..577b561
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Warray-bounds -fdump-tree-phiopt1" } */
+
+void
+h (const void *p, unsigned n)
+{
+  unsigned char a[8];
+  if (n > sizeof a)
+    return;
+
+  for (; n > 0; n -= *a)
+    {
+      if (n > 255)
+       *a = 255;
+      else
+       *a = n;
+
+      __builtin_memcpy (a, p, *a);   /* { dg-bogus "bounds" } */
+    }
+}
+
+/* { dg-final { scan-tree-dump "MIN_EXPR" "phiopt1" } } */
index 682166f195cb94c3fb00e20f02af54331c78dd5d..e9b4f2628d55112c2c417d032e39d55aec5aea35 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details -w" } */
+/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fdump-tree-split-paths-details -w" } */
 
 struct __sFILE
 {
index f80d30655e718d326975beb4f1461c1eaeeecc89..3d6186b34d98f0c5b2bba8795245609ac291671b 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details -w" } */
+/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fdump-tree-split-paths-details -w" } */
 
 
 struct _reent
index e740cf5993079d7b1d88803810ebfcbba1218646..8e94f6a999ab8d48c88ee78a1cb138143b5a0259 100644 (file)
@@ -2035,6 +2035,36 @@ cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb,
   return true;
 }
 
+/* Return the single store in BB with VDEF or NULL if there are
+   other stores in the BB or loads following the store.  */
+
+static gimple *
+single_trailing_store_in_bb (basic_block bb, tree vdef)
+{
+  if (SSA_NAME_IS_DEFAULT_DEF (vdef))
+    return NULL;
+  gimple *store = SSA_NAME_DEF_STMT (vdef);
+  if (gimple_bb (store) != bb
+      || gimple_code (store) == GIMPLE_PHI)
+    return NULL;
+
+  /* Verify there is no other store in this BB.  */
+  if (!SSA_NAME_IS_DEFAULT_DEF (gimple_vuse (store))
+      && gimple_bb (SSA_NAME_DEF_STMT (gimple_vuse (store))) == bb
+      && gimple_code (SSA_NAME_DEF_STMT (gimple_vuse (store))) != GIMPLE_PHI)
+    return NULL;
+
+  /* Verify there is no load or store after the store.  */
+  use_operand_p use_p;
+  imm_use_iterator imm_iter;
+  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_vdef (store))
+    if (USE_STMT (use_p) != store
+       && gimple_bb (USE_STMT (use_p)) == bb)
+      return NULL;
+
+  return store;
+}
+
 /* Conditional store replacement.  We already know
    that the recognized pattern looks like so:
 
@@ -2061,8 +2091,6 @@ static bool
 cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb,
                                 basic_block join_bb)
 {
-  gimple *then_assign = last_and_only_stmt (then_bb);
-  gimple *else_assign = last_and_only_stmt (else_bb);
   vec<data_reference_p> then_datarefs, else_datarefs;
   vec<ddr_p> then_ddrs, else_ddrs;
   gimple *then_store, *else_store;
@@ -2073,13 +2101,32 @@ cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb,
   tree then_lhs, else_lhs;
   basic_block blocks[3];
 
-  if (MAX_STORES_TO_SINK == 0)
+  /* Handle the case with single store in THEN_BB and ELSE_BB.  That is
+     cheap enough to always handle as it allows us to elide dependence
+     checking.  */
+  gphi *vphi = NULL;
+  for (gphi_iterator si = gsi_start_phis (join_bb); !gsi_end_p (si);
+       gsi_next (&si))
+    if (virtual_operand_p (gimple_phi_result (si.phi ())))
+      {
+       vphi = si.phi ();
+       break;
+      }
+  if (!vphi)
     return false;
+  tree then_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (then_bb));
+  tree else_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (else_bb));
+  gimple *then_assign = single_trailing_store_in_bb (then_bb, then_vdef);
+  if (then_assign)
+    {
+      gimple *else_assign = single_trailing_store_in_bb (else_bb, else_vdef);
+      if (else_assign)
+       return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
+                                                then_assign, else_assign);
+    }
 
-  /* Handle the case with single statement in THEN_BB and ELSE_BB.  */
-  if (then_assign && else_assign)
-    return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
-                                             then_assign, else_assign);
+  if (MAX_STORES_TO_SINK == 0)
+    return false;
 
   /* Find data references.  */
   then_datarefs.create (1);