Re: [RFC][PATCH 2/2] fortran: Add -fdoconcurrent-force-parallel flag [PR125717]
Harald Anlauf <[email protected]> Wed, 17 Jun 2026 22:32:34 +0200
| Newsgroups | gmane.comp.gcc.patches,gmane.comp.gcc.fortran |
|---|---|
| Message-ID | <[email protected]> |
Am 17.06.26 um 11:09 AM schrieb Richard Biener: > On Wed, Jun 17, 2026 at 10:57 AM Dhruv Chawla <[email protected]> wrote: >> >> On 17/06/26 14:03, Kyrylo Tkachov wrote: >> Yes, that is what it turned out to be - a caller-allocated stack array >> used as return storage for a callee (`compute` in the test case) got >> hoisted outside the loop (as its address was loop-invariant for a >> single thread), so multiple threads ended up writing to the same address >> thus leading to garbage output. This doesn't occur in the pot3d function, >> so it is safe to ignore this bug. > > But it must be possible to classify a conservatively safe subset of > do concurrent loops from inside the frontend? I'd really prefer that. I do also see the data race for the temporary for the array-valued function result of compute with -fsanitize=thread, which does not occur when I use an ordinary OpenMP do loop instead of do concurrent. So how does OpenMP annotate the temporary (it should be PRIVATE)? And can this be used to annotate frontend-generated temporaries for the auto-parallelizer? (BTW: the testcase runs a factor of 10 faster for me when I replace tmp(k) = tmp(k) + (-1.0_real64)**(j+1) / real( 2*j-1 ) by tmp(k) = tmp(k) + (-1)**(j+1) / real( 2*j-1, real64) because the power of integer (-1) is expanded inline.) > autopar is essentially unmaintained ... but clearly the can_be_parallel > flag isn't correct for the IL as-is? While I looked into autpar years > ago I don't remember much in what guarantees it makes, but I think > all of the safety is with the dependence analysis we skip with > can_be_parallel annotated loops. I think the loop is fine (Fortran-wise). I also tried to use an explicit temporary and making compute a subroutine, like ... real(real64), dimension(nsplit) :: mytmp ... do concurrent (i = 1:nsplit) local (mytmp) call compute( low(i), high(i) , mytmp) pi(i) = sum (mytmp) end do This avoids frontend-generated temporaries, but still has the same data race. Cheers, Harald