From: Richard Biener Date: Mon, 19 Mar 2018 14:08:58 +0000 (+0000) Subject: re PR tree-optimization/84859 (bogus -Warray-bounds on a memcpy in a loop) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=68d93a19c4d764012d947ef7c0ab8abbb0d72775;p=gcc.git re PR tree-optimization/84859 (bogus -Warray-bounds on a memcpy in a loop) 2018-03-19 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b5b55598f81..b27b28f44ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-03-19 Richard Biener + + 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 PR tree-optimization/84929 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 337b4bd1f25..9f462160a61 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2018-03-19 Richard Biener + + 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 PR c++/84812 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c b/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c index 8f683fbd162..4429cc857bf 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 00000000000..577b561545d --- /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 682166f195c..e9b4f2628d5 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 f80d30655e7..3d6186b34d9 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 e740cf59930..8e94f6a999a 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 then_datarefs, else_datarefs; vec 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);