re PR tree-optimization/57396 (Wrong code with -fpredictive-commoning in Fortran...
authorRichard Biener <rguenther@suse.de>
Mon, 27 May 2013 07:48:37 +0000 (07:48 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 27 May 2013 07:48:37 +0000 (07:48 +0000)
2013-05-27  Richard Biener  <rguenther@suse.de>

PR tree-optimization/57396
* tree-affine.c (double_int_constant_multiple_p): Properly
return false for val == 0 and div != 0.

* gfortran.fortran-torture/execute/pr57396.f90: New testcase.

From-SVN: r199350

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.fortran-torture/execute/pr57396.f90 [new file with mode: 0644]
gcc/tree-affine.c

index 8fd8350a18727e5bfb6113e2a339618872508ece..b31591245f9ff2192c8fbe502a99287b199f4494 100644 (file)
@@ -1,3 +1,9 @@
+2013-05-27  Richard Biener  <rguenther@suse.de>
+
+       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  <rdsandiford@googlemail.com>
 
        * config/mips/mips.h: Use #elif in preprocessor conditions.
index 5cb426f8542bc44bde970124bfd985bcfb8b24ea..d0f01c84c010e8249549287c28a84de165f1c60b 100644 (file)
@@ -1,3 +1,8 @@
+2013-05-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/57396
+       * gfortran.fortran-torture/execute/pr57396.f90: New testcase.
+
 2013-05-26  Eric Botcazou  <ebotcazou@adacore.com>
 
        * 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 (file)
index 0000000..8ea9292
--- /dev/null
@@ -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
index 0ee5eaa9db6da0067670c50e73819c8a2684e829..46a183a07b4ddd10e0bb1bb3b1807e37ac0b6fcc 100644 (file)
@@ -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;