From f20132e7aefa8b3615154925559dd19f204c8eca Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 19 Sep 2012 08:59:06 +0000 Subject: [PATCH] re PR tree-optimization/54132 (Incorrect loop transformation with -ftree-loop-distribute-patterns) 2012-09-19 Richard Guenther PR tree-optimization/54132 * tree-loop-distribution.c (classify_partition): Properly check dependences for memmove. * tree-data-ref.h (compute_affine_dependence): Declare. * tree-data-ref.c (compute_affine_dependence): Export. * gcc.dg/tree-ssa/ldist-21.c: New testcase. * gcc.dg/torture/pr54132.c: Likewise. From-SVN: r191463 --- gcc/ChangeLog | 8 ++++++ gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/gcc.dg/torture/pr54132.c | 18 +++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/ldist-21.c | 11 ++++++++ gcc/tree-data-ref.c | 2 +- gcc/tree-data-ref.h | 2 ++ gcc/tree-loop-distribution.c | 33 ++++++++++++++++++++++++ 7 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr54132.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ldist-21.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 936b7d0f5881..fc1938924710 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-09-19 Richard Guenther + + PR tree-optimization/54132 + * tree-loop-distribution.c (classify_partition): Properly + check dependences for memmove. + * tree-data-ref.h (compute_affine_dependence): Declare. + * tree-data-ref.c (compute_affine_dependence): Export. + 2012-09-19 Zhenqiang Chen PR middle-end/54364 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index df70396f9366..bf497ee1169c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-09-19 Richard Guenther + + PR tree-optimization/54132 + * gcc.dg/tree-ssa/ldist-21.c: New testcase. + * gcc.dg/torture/pr54132.c: Likewise. + 2012-09-19 Terry Guo * lib/gcc-dg.exp (dg_runtest_extra_prunes): New variable to define diff --git a/gcc/testsuite/gcc.dg/torture/pr54132.c b/gcc/testsuite/gcc.dg/torture/pr54132.c new file mode 100644 index 000000000000..97bc01caf8de --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr54132.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ + +extern void abort (void); +void foo(char *p, int n) +{ + int i; + for (i = 1; i < n; i++) + p[i] = p[i - 1]; +} +int main() +{ + char a[1024]; + a[0] = 1; + foo (a, 1024); + if (a[1023] != 1) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-21.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-21.c new file mode 100644 index 000000000000..35f01aba2a6a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-21.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-ldist-details" } */ + +void bar(char *p, int n) +{ + int i; + for (i = 1; i < n; i++) + p[i-1] = p[i]; +} + +/* { dg-final { scan-tree-dump "generated memmove" "ldist" } } */ diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 0f68fdf4020a..4f6df91ec287 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -4130,7 +4130,7 @@ ddr_consistent_p (FILE *file, relation the first time we detect a CHREC_KNOWN element for a given subscript. */ -static void +void compute_affine_dependence (struct data_dependence_relation *ddr, struct loop *loop_nest) { diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h index db33e328c3ed..b00a4f752b05 100644 --- a/gcc/tree-data-ref.h +++ b/gcc/tree-data-ref.h @@ -396,6 +396,8 @@ struct data_reference *create_data_ref (loop_p, loop_p, tree, gimple, bool); extern bool find_loop_nest (struct loop *, VEC (loop_p, heap) **); extern struct data_dependence_relation *initialize_data_dependence_relation (struct data_reference *, struct data_reference *, VEC (loop_p, heap) *); +extern void compute_affine_dependence (struct data_dependence_relation *, + loop_p); extern void compute_self_dependence (struct data_dependence_relation *); extern bool compute_all_dependences (VEC (data_reference_p, heap) *, VEC (ddr_p, heap) **, VEC (loop_p, heap) *, diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index f340eab2a0fe..b24af33d7abc 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -1011,6 +1011,39 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition) || !operand_equal_p (DR_STEP (single_store), DR_STEP (single_load), 0)) return; + /* Now check that if there is a dependence this dependence is + of a suitable form for memmove. */ + VEC(loop_p, heap) *loops = NULL; + ddr_p ddr; + VEC_safe_push (loop_p, heap, loops, loop); + ddr = initialize_data_dependence_relation (single_load, single_store, + loops); + compute_affine_dependence (ddr, loop); + VEC_free (loop_p, heap, loops); + if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) + { + free_dependence_relation (ddr); + return; + } + if (DDR_ARE_DEPENDENT (ddr) != chrec_known) + { + if (DDR_NUM_DIST_VECTS (ddr) == 0) + { + free_dependence_relation (ddr); + return; + } + lambda_vector dist_v; + FOR_EACH_VEC_ELT (lambda_vector, DDR_DIST_VECTS (ddr), i, dist_v) + { + int dist = dist_v[index_in_loop_nest (loop->num, + DDR_LOOP_NEST (ddr))]; + if (dist > 0 && !DDR_REVERSED_P (ddr)) + { + free_dependence_relation (ddr); + return; + } + } + } partition->kind = PKIND_MEMCPY; partition->main_dr = single_store; partition->secondary_dr = single_load; -- 2.47.2