Hi! This patch makes sure we have OMP_CLAUSE_LINEAR_NO_COPYIN set on iterator vars, both with implicit and explicit linear clause, so that we don't ICE on those - the iterator vars don't need original list item value. The patch also fixes up the step value for the artificial count iterator var, which always has step of one.
The patch doesn't cure linear clauses on combined do simd (or for simd) constructs if the var in the linear clause is not iterator var and is private in outer context - have asked on omp-lang whether it should be rejected or what behavior it should have. Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk so far (plan to backport to 4.9 eventually). 2015-03-30 Jakub Jelinek <ja...@redhat.com> PR fortran/65597 * trans-openmp.c (gfc_trans_omp_do): For !simple simd with explicit linear clause for the iterator set OMP_CLAUSE_LINEAR_NO_COPYIN. For implcitly added !simple OMP_CLAUSE_LINEAR set it too. Use step 1 instead of the original step on the new iterator - count. * testsuite/libgomp.fortran/pr65597.f90: New test. --- gcc/fortran/trans-openmp.c.jj 2015-01-28 08:39:53.000000000 +0100 +++ gcc/fortran/trans-openmp.c 2015-03-30 16:50:27.710714334 +0200 @@ -3255,6 +3255,19 @@ gfc_trans_omp_do (gfc_code *code, gfc_ex inits.safe_push (e); } + if (dovar_found == 2 + && op == EXEC_OMP_SIMD + && collapse == 1 + && !simple) + { + for (tmp = omp_clauses; tmp; tmp = OMP_CLAUSE_CHAIN (tmp)) + if (OMP_CLAUSE_CODE (tmp) == OMP_CLAUSE_LINEAR + && OMP_CLAUSE_DECL (tmp) == dovar) + { + OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1; + break; + } + } if (!dovar_found) { if (op == EXEC_OMP_SIMD) @@ -3263,6 +3276,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_ex { tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR); OMP_CLAUSE_LINEAR_STEP (tmp) = step; + OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1; } else tmp = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE); @@ -3330,7 +3344,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_ex else if (collapse == 1) { tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR); - OMP_CLAUSE_LINEAR_STEP (tmp) = step; + OMP_CLAUSE_LINEAR_STEP (tmp) = build_int_cst (type, 1); OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1; OMP_CLAUSE_LINEAR_NO_COPYOUT (tmp) = 1; } --- libgomp/testsuite/libgomp.fortran/pr65597.f90.jj 2015-03-30 16:57:50.685614350 +0200 +++ libgomp/testsuite/libgomp.fortran/pr65597.f90 2015-03-30 16:57:10.000000000 +0200 @@ -0,0 +1,21 @@ +! PR fortran/65597 +! { dg-do run } + + integer :: i, a(151) + a(:) = 0 + !$omp do simd + do i = 1, 151, 31 + a(i) = a(i) + 1 + end do + !$omp do simd linear (i: 31) + do i = 1, 151, 31 + a(i) = a(i) + 1 + end do + do i = 1, 151 + if (mod (i, 31) .eq. 1) then + if (a(i) .ne. 2) call abort + else + if (a(i) .ne. 0) call abort + end if + end do +end Jakub