From 85aa9ed64bf871b2e620211609855804e1775864 Mon Sep 17 00:00:00 2001 From: Bin Cheng Date: Wed, 18 Oct 2017 15:56:15 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 8 ++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/tree-ssa/pr82574.c | 19 ++++++++++++++++++ gcc/tree-loop-distribution.c | 26 ++++++++++++++----------- 4 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr82574.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 51ad45e7964..1eee85d3328 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2017-10-18 Bin Cheng + + 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 PR tree-optimization/82591 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 37454e1d5b5..d642a6aba80 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-10-18 Bin Cheng + + PR tree-optimization/82574 + * gcc.dg/tree-ssa/pr82574.c: New test. + 2017-10-18 Martin Liska * gcc.dg/tree-prof/switch-case-2.c: Scan IPA profile dump diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr82574.c b/gcc/testsuite/gcc.dg/tree-ssa/pr82574.c new file mode 100644 index 00000000000..8fc459631ef --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr82574.c @@ -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; +} diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 5e835be779d..6abb7e43421 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -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. */ -- 2.30.2