re PR fortran/66111 (ICE with matmul and vector subscripts)
authorThomas Koenig <tkoenig@gcc.gnu.org>
Tue, 12 May 2015 21:12:55 +0000 (21:12 +0000)
committerThomas Koenig <tkoenig@gcc.gnu.org>
Tue, 12 May 2015 21:12:55 +0000 (21:12 +0000)
2015-05-12  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/66111
* frontend-passes.c (has_dimen_vector_ref):  New function.
(inline_matmul_assign):  Use it to return early in case
of unhandled vector subscripts.

2015-05-12  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/66111
* gfortran.dg/inline_matmul_10.f90:  New test.

From-SVN: r223099

gcc/fortran/ChangeLog
gcc/fortran/frontend-passes.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/inline_matmul_10.f90 [new file with mode: 0644]

index 174e3b4..1b455b5 100644 (file)
@@ -1,5 +1,12 @@
 2015-05-12  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
+       PR fortran/66111
+       * frontend-passes.c (has_dimen_vector_ref):  New function.
+       (inline_matmul_assign):  Use it to return early in case
+       of unhandled vector subscripts.
+
+2015-05-12  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
        PR fortran/66041
        PR fortran/37131
        * gfortran.h (gfc_array_spec):  Add field resolved.
index 30085e8..a6b5786 100644 (file)
@@ -2680,6 +2680,25 @@ scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index)
   return e;
 }
 
+/* Helper function to check for a dimen vector as subscript.  */
+
+static bool
+has_dimen_vector_ref (gfc_expr *e)
+{
+  gfc_array_ref *ar;
+  int i;
+
+  ar = gfc_find_array_ref (e);
+  gcc_assert (ar);
+  if (ar->type == AR_FULL)
+    return false;
+
+  for (i=0; i<ar->dimen; i++)
+    if (ar->dimen_type[i] == DIMEN_VECTOR)
+      return true;
+
+  return false;
+}
 
 /* Inline assignments of the form c = matmul(a,b).
    Handle only the cases currently where b and c are rank-two arrays.
@@ -2752,6 +2771,10 @@ inline_matmul_assign (gfc_code **c, int *walk_subtrees,
       || matrix_b->expr_type != EXPR_VARIABLE)
     return 0;
 
+  if (has_dimen_vector_ref (expr1) || has_dimen_vector_ref (matrix_a)
+      || has_dimen_vector_ref (matrix_b))
+    return 0;
+
   if (matrix_a->rank == 2)
     m_case = matrix_b->rank == 1 ? A2B1 : A2B2;
   else
index 60f7d30..d8b6a58 100644 (file)
@@ -1,3 +1,8 @@
+2015-05-12  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/66111
+       * gfortran.dg/inline_matmul_10.f90:  New test.
+
 2015-05-12  David Malcolm  <dmalcolm@redhat.com>
 
        * c-c++-common/Wmisleading-indentation.c: New testcase.
diff --git a/gcc/testsuite/gfortran.dg/inline_matmul_10.f90 b/gcc/testsuite/gfortran.dg/inline_matmul_10.f90
new file mode 100644 (file)
index 0000000..3a577b0
--- /dev/null
@@ -0,0 +1,35 @@
+! { dg-do  run }
+! { dg-options "-ffrontend-optimize" }
+! PR 66111 - this used to ICE with matmul inlining.
+! Original test case by Mikael Morin.
+
+implicit none
+  integer, parameter :: n = 4
+  integer, dimension(n, n) :: a, b, c
+  integer, dimension(n*n)  :: p, res, res2
+  integer, dimension(n)    :: v
+
+  integer :: i
+
+  p = [ +59, -53, +47, -43, &
+        -37, +31, -29, +23, &
+        +19, -17, +13, -11, &
+        - 7, + 5, - 3, + 2  ]
+  a = reshape(p, shape(a))
+  b = reshape([(i, i=1, size(a))], shape(b))
+  v = [ 3, 1, 2, 4]
+  c = matmul(a, b)
+  res = [ + 14, - 22, + 16, - 22, &
+          +150, -158, +128, -138, &
+          +286, -294, +240, -254, &
+          +422, -430, +352, -370  ]
+  !print *,c
+  if (any(c /= reshape(res, shape(c)))) call abort
+  c(:,v) = matmul(a, b)
+  if (any(c(:,v) /= reshape(res, shape(c)))) call abort
+  c(v,:) = matmul(a, b)
+  if (any(c(v,:) /= reshape(res, shape(c)))) call abort
+
+  c = matmul(a(:,v),b(v,:))
+  if (any(c /= reshape(res, shape(c)))) call abort
+end