diff options
-rw-r--r-- | gcc/fortran/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/fortran/frontend-passes.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/inline_matmul_12.f90 | 22 |
4 files changed, 49 insertions, 0 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index c38c280..051c6ed 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2016-01-10 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/69154 + * frontend-passes.c (in_where): New variable. + (inline_matmul_assign): Don't try this if we are within + a WHERE statement. + (gfc_code_walker): Keep track of in_where. + 2016-01-10 Paul Thomas <pault@gcc.gnu.org> PR fortran/67779 diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index c02fc36..9fad41d8 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -78,6 +78,10 @@ static int forall_level; static bool in_omp_workshare; +/* Keep track of whether we are within a WHERE statement. */ + +static bool in_where; + /* Keep track of iterators for array constructors. */ static int iterator_level; @@ -2790,6 +2794,9 @@ inline_matmul_assign (gfc_code **c, int *walk_subtrees, if (co->op != EXEC_ASSIGN) return 0; + if (in_where) + return 0; + expr1 = co->expr1; expr2 = co->expr2; if (expr2->expr_type != EXPR_FUNCTION @@ -3268,12 +3275,14 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn, gfc_code *co; gfc_association_list *alist; bool saved_in_omp_workshare; + bool saved_in_where; /* There might be statement insertions before the current code, which must not affect the expression walker. */ co = *c; saved_in_omp_workshare = in_omp_workshare; + saved_in_where = in_where; switch (co->op) { @@ -3301,6 +3310,10 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn, WALK_SUBEXPR (co->ext.iterator->step); break; + case EXEC_WHERE: + in_where = true; + break; + case EXEC_CALL: case EXEC_ASSIGN_CALL: for (a = co->ext.actual; a; a = a->next) @@ -3554,6 +3567,7 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn, doloop_level --; in_omp_workshare = saved_in_omp_workshare; + in_where = saved_in_where; } } return 0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6ab64f7..f233bb9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-10 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/69154 + * gfortran.dg/inline_matmul_12.f90: New test. + 2016-01-10 Paul Thomas <pault@gcc.gnu.org> PR fortran/67779 diff --git a/gcc/testsuite/gfortran.dg/inline_matmul_12.f90 b/gcc/testsuite/gfortran.dg/inline_matmul_12.f90 new file mode 100644 index 0000000..cc6fabd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/inline_matmul_12.f90 @@ -0,0 +1,22 @@ +! { dg-do compile } +! { dg-options "-ffrontend-optimize -fdump-tree-original" } +! PR 69154 - inlined matmul used to cause an ICE inside a WHERE. +MODULE m_numeric_tools + INTEGER, PARAMETER :: dp=8 +CONTAINS +subroutine llsfit_svd(xx,yy,sigma,nfuncs,funcs,chisq,par,var,cov,info) + real(dp),intent(in) :: xx(:),yy(:),sigma(:) + real(dp),dimension(SIZE(xx)) :: bb,sigm1 + real(dp) :: tmp(nfuncs) + real(dp),allocatable :: work(:),Vt(:,:),U(:,:),S(:) + real(dp),dimension(3,3) :: a, b, c + WHERE (S>TOL_*MAXVAL(S)) + tmp=MATMUL(bb,U)/S + END WHERE + call random_number(a) + call random_number(b) + c = matmul(a,b) +end subroutine llsfit_svd + +END MODULE m_numeric_tools +! { dg-final { scan-tree-dump-times "matmul_r8" 1 "original" } } |