------- Comment #5 from jakub at gcc dot gnu dot org 2006-05-01 16:07 ------- We do need a barrier (well, in some cases with extra code we can avoid it in some cases), in order to honor 2.8.3.4: "If a list item appears in both firstprivate and lastprivate clauses, the update required for lastprivate occurs after all the initializations for firstprivate." Now, as e.g. Richard's testcase shows, without a barrier somewhere between the firstprivate initializations and lastprivate copying it is possible that some thread is initialized for the first time after the thread handling the last case executed the lastprivate copying. That can happen either because some constructor in firstprivate initialization slept intentionally, or just the thread was not being scheduled to run for sufficiently long.
The patch I'll post RSN will just add the barrier for any firstprivate+lastprivate, correctness first, then we can optimize. Cases which can be optimized: 1) if we prove the structured block has at least one barrier in between the firstprivate and lastprivate code chunks (doesn't matter if explicit #pragma omp barrier or some other OMP stuff that acts similarly) 2) if the variable is not passed by reference (i.e. scalar put directly into .omp_data_*) and we use 2 fields for it rather than one - sender initializes first field and firstprivate uses that, then lastprivate sets the second field and sender copies from the second field. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26943