re PR tree-optimization/82574 (wrong code at -O3 on x86_64-linux-gnu)

PR tree-optimization/82574
	* tree-loop-distribution.c (find_single_drs): New parameter.  Check
	that data reference must be executed exactly once per iteration
	against the outermost loop in nest.
	(classify_partition): Update call to above function.

	gcc/testsuite
	* gcc.dg/tree-ssa/pr82574.c: New test.

From-SVN: r253857
This commit is contained in:
Bin Cheng 2017-10-18 15:56:15 +00:00 committed by Bin Cheng
parent e33507e33c
commit 85aa9ed64b
4 changed files with 47 additions and 11 deletions

View File

@ -1,3 +1,11 @@
2017-10-18 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/82574
* tree-loop-distribution.c (find_single_drs): New parameter. Check
that data reference must be executed exactly once per iteration
against the outermost loop in nest.
(classify_partition): Update call to above function.
2017-10-18 Richard Biener <rguenther@suse.de>
PR tree-optimization/82591

View File

@ -1,3 +1,8 @@
2017-10-18 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/82574
* gcc.dg/tree-ssa/pr82574.c: New test.
2017-10-18 Martin Liska <mliska@suse.cz>
* gcc.dg/tree-prof/switch-case-2.c: Scan IPA profile dump

View File

@ -0,0 +1,19 @@
/* { dg-do run } */
/* { dg-options "-O3" } */
unsigned char a, b, c, d[200][200];
void abort (void);
int main ()
{
for (; a < 200; a++)
for (b = 0; b < 200; b++)
if (c)
d[a][b] = 1;
if ((c && d[0][0] != 1) || (!c && d[0][0] != 0))
abort ();
return 0;
}

View File

@ -1283,12 +1283,12 @@ build_rdg_partition_for_vertex (struct graph *rdg, int v)
return partition;
}
/* Given PARTITION of RDG, record single load/store data references for
builtin partition in SRC_DR/DST_DR, return false if there is no such
/* Given PARTITION of LOOP and RDG, record single load/store data references
for builtin partition in SRC_DR/DST_DR, return false if there is no such
data references. */
static bool
find_single_drs (struct graph *rdg, partition *partition,
find_single_drs (struct loop *loop, struct graph *rdg, partition *partition,
data_reference_p *dst_dr, data_reference_p *src_dr)
{
unsigned i;
@ -1344,10 +1344,12 @@ find_single_drs (struct graph *rdg, partition *partition,
&& DECL_BIT_FIELD (TREE_OPERAND (DR_REF (single_st), 1)))
return false;
/* Data reference must be executed exactly once per iteration. */
/* Data reference must be executed exactly once per iteration of each
loop in the loop nest. We only need to check dominance information
against the outermost one in a perfect loop nest because a bb can't
dominate outermost loop's latch without dominating inner loop's. */
basic_block bb_st = gimple_bb (DR_STMT (single_st));
struct loop *inner = bb_st->loop_father;
if (!dominated_by_p (CDI_DOMINATORS, inner->latch, bb_st))
if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb_st))
return false;
if (single_ld)
@ -1365,14 +1367,16 @@ find_single_drs (struct graph *rdg, partition *partition,
/* Load and store must be in the same loop nest. */
basic_block bb_ld = gimple_bb (DR_STMT (single_ld));
if (inner != bb_ld->loop_father)
if (bb_st->loop_father != bb_ld->loop_father)
return false;
/* Data reference must be executed exactly once per iteration. */
if (!dominated_by_p (CDI_DOMINATORS, inner->latch, bb_ld))
/* Data reference must be executed exactly once per iteration.
Same as single_st, we only need to check against the outermost
loop. */
if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb_ld))
return false;
edge e = single_exit (inner);
edge e = single_exit (bb_st->loop_father);
bool dom_ld = dominated_by_p (CDI_DOMINATORS, e->src, bb_ld);
bool dom_st = dominated_by_p (CDI_DOMINATORS, e->src, bb_st);
if (dom_ld != dom_st)
@ -1611,7 +1615,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition *partition,
return;
/* Find single load/store data references for builtin partition. */
if (!find_single_drs (rdg, partition, &single_st, &single_ld))
if (!find_single_drs (loop, rdg, partition, &single_st, &single_ld))
return;
/* Classify the builtin kind. */