[all-commits] [llvm/llvm-project] ec62b5: [flang][OpenMP] Fix wrong results for FORALL in a ...
Carlos Seo via All-commits
all-commits at lists.llvm.org
Wed Aug 5 10:38:04 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: ec62b5ae07df222f06526d5260cf6baea28c7a30
https://github.com/llvm/llvm-project/commit/ec62b5ae07df222f06526d5260cf6baea28c7a30
Author: Carlos Seo <carlos.seo at linaro.org>
Date: 2026-08-05 (Wed, 05 Aug 2026)
Changed paths:
M flang/lib/Optimizer/OpenMP/LowerWorkshare.cpp
M flang/test/Transforms/OpenMP/lower-workshare-nowait.mlir
M flang/test/Transforms/OpenMP/lower-workshare-thread-local.mlir
Log Message:
-----------
[flang][OpenMP] Fix wrong results for FORALL in a workshare construct (#211371)
A FORALL in a workshare construct could produce wrong results
non-deterministically. This is caused by two issues in the workshare
lowering:
1. A FORALL whose left-hand side may overlap its right-hand side is
lowered into two loop nests around a runtime value stack: the first nest
evaluates each right-hand side and pushes it, the second one fetches the
saved values back with a running counter. That counter lives in a
fir.alloca which, since omp.parallel is an alloca scope, is thread
private. The counter is read, incremented and written back from inside
the omp.single generated for the fetch, because the incremented value is
only available there. Only the thread which executed the omp.single
therefore bumped its own copy of the counter, and all the other threads
kept a stale one and refetched an already consumed element on the
following iterations.
Collect the thread local memory which is only updated by the thread
executing an omp.single and broadcast it with copyprivate, so that the
copies of the other threads stay in sync. As nowait and copyprivate are
mutually exclusive on a single construct, nowait is no longer set when
there is something to broadcast.
2. nowait was only suppressed when the immediately enclosing operation
was loop-like. A masked FORALL introduces a fir.if inside the
fir.do_loop, so the last omp.single or omp.wsloop of the fir.if body was
given nowait even though the loop may run it again, and even though
there was more work after the loop. Thread the information down the
recursion instead, so that only the work which is really last in the
whole omp.workshare region may rely on the barrier emitted at the end of
that region.
Fixes #209942
Fixes #209943
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list