Hello world, the attached patch fixes the regression. Before this, front-end optimization would have tried to put a DO loop inside a WHERE construct, leading to an ICE.
Regression-tested. OK for trunk? Thomas 2016-01-10 Thomas Koenig <tkoe...@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.
Index: frontend-passes.c =================================================================== --- frontend-passes.c (revision 232196) +++ frontend-passes.c (working copy) @@ -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_subt 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,6 +3275,7 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t code 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. */ @@ -3274,6 +3282,7 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t code 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 code 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 code doloop_level --; in_omp_workshare = saved_in_omp_workshare; + in_where = saved_in_where; } } return 0;
! { dg-do compile } ! 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(:) WHERE (S>TOL_*MAXVAL(S)) tmp=MATMUL(bb,U)/S END WHERE end subroutine llsfit_svd END MODULE m_numeric_tools