[llvm-branch-commits] [Clang][OpenMP] Fix capture of reduction variables under nested default(firstprivate) (PR #216329)

Julian Brown via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Aug 14 07:32:34 PDT 2026


https://github.com/jtb20 created https://github.com/llvm/llvm-project/pull/216329

isOpenMPCapturedByRef() decided whether a scalar is captured by copy for a
given capture Level, but consulted the default data-sharing attribute of the
innermost directive (getDefaultDSA()) instead of the one at that Level
(getDefaultDSA(Level)).

When a construct with default(firstprivate) (or default(private)) is nested in
an enclosing captured region within the same function -- e.g. a taskloop with a
reduction inside a 'parallel' region -- this made the enclosing region capture
the reduction variable by copy.  The reduction then combined into that copy and
its result never propagated back to the original variable (it read as 0).

Query the default attribute at the capture Level being considered, matching the
Level already used by the neighbouring hasExplicitDSA()/isLoopControlVariable()
checks.  For top-level captures Level is the top of stack, so behaviour is
unchanged there.

This bug is independent of the 'taskgraph' directive; add a CodeGen regression
test (taskloop_reduction_default_firstprivate_codegen.cpp) exercising it with a
taskloop reduction under default(firstprivate) nested in a plain parallel/single
region.

Assisted-By: Claude Opus 4.8





More information about the llvm-branch-commits mailing list