aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-03-19 14:08:58 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2018-03-19 14:08:58 +0000
commit68d93a19c4d764012d947ef7c0ab8abbb0d72775 (patch)
treebb10fb061c799fb918ebf41eac6f1b6f6a97e5ef /gcc
parent8f3284a4866183caec602737f35c088d982e18bb (diff)
downloadgcc-68d93a19c4d764012d947ef7c0ab8abbb0d72775.zip
gcc-68d93a19c4d764012d947ef7c0ab8abbb0d72775.tar.gz
gcc-68d93a19c4d764012d947ef7c0ab8abbb0d72775.tar.bz2
re PR tree-optimization/84859 (bogus -Warray-bounds on a memcpy in a loop)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr35286.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr84859.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c2
-rw-r--r--gcc/tree-ssa-phiopt.c61
7 files changed, 95 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b5b5559..b27b28f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
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
* tree-data-ref.c (analyze_siv_subscript_cst_affine): Guard
chrec_is_positive against non-chrec arg.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 337b4bd..9f46216 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c b/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c
index 8f683fb..4429cc8 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c
@@ -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
index 0000000..577b561
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr84859.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c
index 682166f..e9b4f26 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c
@@ -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
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c
index f80d306..3d6186b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c
@@ -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
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index e740cf5..8e94f6a 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -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);