Commit 68d93a19 by Richard Biener Committed by Richard Biener

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
parent 8f3284a4
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.
......
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
......
/* { 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;
......
/* { 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" } } */
/* { 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
{
......
/* { 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
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment