diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8fd8350a187..b31591245f9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-05-27 Richard Biener + + PR tree-optimization/57396 + * tree-affine.c (double_int_constant_multiple_p): Properly + return false for val == 0 and div != 0. + 2013-05-25 Richard Sandiford * config/mips/mips.h: Use #elif in preprocessor conditions. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5cb426f8542..d0f01c84c01 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-05-27 Richard Biener + + PR tree-optimization/57396 + * gfortran.fortran-torture/execute/pr57396.f90: New testcase. + 2013-05-26 Eric Botcazou * gnat.dg/specs/last_bit.ads: New test. diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/pr57396.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/pr57396.f90 new file mode 100644 index 00000000000..8ea92924ad8 --- /dev/null +++ b/gcc/testsuite/gfortran.fortran-torture/execute/pr57396.f90 @@ -0,0 +1,33 @@ +module testmod + implicit none + + contains + + subroutine foo(n) + integer, intent(in) :: n + real :: r(0:n,-n:n), a(0:n,-n:n), dj + integer :: k, j + + ! initialize with some dummy values + do j = -n, n + a(:, j) = j + r(:,j) = j + 1 + end do + + ! here be dragons + do k = 0, n + dj = r(k, k - 2) * a(k, k - 2) + r(k,k) = a(k, k - 1) * dj + enddo + + if (r(0,0) .ne. -2.) call abort + + end subroutine + +end module + +program test + use testmod + implicit none + call foo(5) +end program diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c index 0ee5eaa9db6..46a183a07b4 100644 --- a/gcc/tree-affine.c +++ b/gcc/tree-affine.c @@ -736,11 +736,10 @@ free_affine_expand_cache (struct pointer_map_t **cache) } /* If VAL != CST * DIV for any constant CST, returns false. - Otherwise, if VAL != 0 (and hence CST != 0), and *MULT_SET is true, - additionally compares CST and MULT, and if they are different, - returns false. Finally, if neither of these two cases occur, - true is returned, and if CST != 0, CST is stored to MULT and - MULT_SET is set to true. */ + Otherwise, if *MULT_SET is true, additionally compares CST and MULT, + and if they are different, returns false. Finally, if neither of these + two cases occur, true is returned, and CST is stored to MULT and MULT_SET + is set to true. */ static bool double_int_constant_multiple_p (double_int val, double_int div, @@ -749,7 +748,13 @@ double_int_constant_multiple_p (double_int val, double_int div, double_int rem, cst; if (val.is_zero ()) - return true; + { + if (*mult_set && !mult->is_zero ()) + return false; + *mult_set = true; + *mult = double_int_zero; + return true; + } if (div.is_zero ()) return false;