From 62e22fcb7985349b93646b86351033e1fb09c46c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 12 Jan 2015 15:37:07 +0000 Subject: [PATCH] re PR tree-optimization/64530 (Incorrect calculation when assigning to array with -O3) 2015-01-12 Richard Biener PR tree-optimization/64530 * tree-loop-distribution.c (pg_add_dependence_edges): Shuffle back dr1. * gfortran.dg/pr64530.f90: New testcase. From-SVN: r219474 --- gcc/ChangeLog | 6 +++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gfortran.dg/pr64530.f90 | 38 +++++++++++++++++++++++++++ gcc/tree-loop-distribution.c | 3 +++ 4 files changed, 52 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/pr64530.f90 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dfba0bc433c..a1b87f602f8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-01-12 Richard Biener + + PR tree-optimization/64530 + * tree-loop-distribution.c (pg_add_dependence_edges): Shuffle + back dr1. + 2015-01-12 Richard Biener PR middle-end/64357 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3cda6b359a6..e0ef2911a65 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-01-12 Richard Biener + + PR tree-optimization/64530 + * gfortran.dg/pr64530.f90: New testcase. + 2015-01-12 Richard Biener PR middle-end/64357 diff --git a/gcc/testsuite/gfortran.dg/pr64530.f90 b/gcc/testsuite/gfortran.dg/pr64530.f90 new file mode 100644 index 00000000000..9805f628c83 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr64530.f90 @@ -0,0 +1,38 @@ +! { dg-do run } + +program bug + ! Bug triggered with at least three elements + integer, parameter :: asize = 3 + + double precision,save :: ave(asize) + double precision,save :: old(asize) + double precision,save :: tmp(asize) + + ave(:) = 10.d0 + old(:) = 3.d0 + tmp(:) = 0.d0 + + call buggy(2.d0,asize,ave,old,tmp) + if (any (tmp(:) .ne. 3.5)) call abort +end + +subroutine buggy(scale_factor, asize, ave, old, tmp) + + implicit none + ! Args + double precision scale_factor + integer asize + double precision ave(asize) + double precision old(asize) + double precision tmp(asize) + + ! Local + integer i + + do i = 1, asize + tmp(i) = ave(i) - old(i) + old(i) = ave(i) + tmp(i) = tmp(i) / scale_factor + end do + +end subroutine buggy diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 1b799142b03..ecd51fb788a 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -1362,6 +1362,7 @@ pg_add_dependence_edges (struct graph *rdg, vec loops, int dir, for (int ii = 0; drs1.iterate (ii, &dr1); ++ii) for (int jj = 0; drs2.iterate (jj, &dr2); ++jj) { + data_reference_p saved_dr1 = dr1; int this_dir = 1; ddr_p ddr; /* Re-shuffle data-refs to be in dominator order. */ @@ -1407,6 +1408,8 @@ pg_add_dependence_edges (struct graph *rdg, vec loops, int dir, dir = this_dir; else if (dir != this_dir) return 2; + /* Shuffle "back" dr1. */ + dr1 = saved_dr1; } return dir; } -- 2.30.2