[all-commits] [llvm/llvm-project] 50d9b2: [flang][OpenMP] Lower cross-module user-defined de...

Matt via All-commits all-commits at lists.llvm.org
Wed Jul 15 10:35:07 PDT 2026


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 50d9b2768f4cf224ed7c3d15703aa2d5190f9b4a
      https://github.com/llvm/llvm-project/commit/50d9b2768f4cf224ed7c3d15703aa2d5190f9b4a
  Author: Matt <MattPD at users.noreply.github.com>
  Date:   2026-07-15 (Wed, 15 Jul 2026)

  Changed paths:
    M flang/include/flang/Lower/OpenMP.h
    M flang/include/flang/Lower/Support/ReductionProcessor.h
    M flang/include/flang/Semantics/openmp-utils.h
    M flang/lib/Lower/OpenMP/ClauseProcessor.cpp
    M flang/lib/Lower/OpenMP/ClauseProcessor.h
    M flang/lib/Lower/OpenMP/OpenMP.cpp
    M flang/lib/Lower/Support/ReductionProcessor.cpp
    M flang/lib/Semantics/check-omp-structure.cpp
    M flang/lib/Semantics/mod-file.cpp
    M flang/lib/Semantics/mod-file.h
    M flang/lib/Semantics/openmp-utils.cpp
    A flang/test/Lower/OpenMP/Todo/declare-reduction-allocatable-trivial.f90
    R flang/test/Lower/OpenMP/Todo/declare-reduction-operator-multiple-types.f90
    R flang/test/Lower/OpenMP/Todo/declare-reduction-operator-use-assoc.f90
    R flang/test/Lower/OpenMP/Todo/multiple-types-declare_reduction.f90
    M flang/test/Lower/OpenMP/declare-reduction-character-allocatable.f90
    M flang/test/Lower/OpenMP/declare-reduction-initializer-component.f90
    M flang/test/Lower/OpenMP/declare-reduction-initializer-defined-assign.f90
    M flang/test/Lower/OpenMP/declare-reduction-initializer-rhs-call.f90
    M flang/test/Lower/OpenMP/declare-reduction-intrinsic-op.f90
    A flang/test/Lower/OpenMP/declare-reduction-intrinsic-same-name-different-scope.f90
    M flang/test/Lower/OpenMP/declare-reduction-logical-init.f90
    A flang/test/Lower/OpenMP/declare-reduction-merge-hermetic.f90
    A flang/test/Lower/OpenMP/declare-reduction-merge-version-skew.f90
    A flang/test/Lower/OpenMP/declare-reduction-name-type-token-collision.f90
    A flang/test/Lower/OpenMP/declare-reduction-named-renamed.f90
    A flang/test/Lower/OpenMP/declare-reduction-named-separate-rename.f90
    A flang/test/Lower/OpenMP/declare-reduction-named-use-assoc.f90
    M flang/test/Lower/OpenMP/declare-reduction-no-initializer-derived.f90
    M flang/test/Lower/OpenMP/declare-reduction-no-initializer-intrinsic.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-collide.f90
    M flang/test/Lower/OpenMP/declare-reduction-operator-derived.f90
    M flang/test/Lower/OpenMP/declare-reduction-operator-host-assoc.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-merged.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-multiple-types.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-renamed.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-collide-unused.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-combiners.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-hermetic.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-intrinsic-all.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-intrinsic-collide.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-intrinsic.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-multitype-partial.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-reexport.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-remerge.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-rename-remerge.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-submodule.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate-unused-unsupported.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-separate.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-use-assoc.f90
    A flang/test/Lower/OpenMP/declare-reduction-operator-use-only-nonreduction.f90
    M flang/test/Lower/OpenMP/declare-reduction-operator.f90
    M flang/test/Lower/OpenMP/declare-reduction-same-name-different-scope.f90
    A flang/test/Lower/OpenMP/declare-reduction-shadows-intrinsic-multiple-types.f90
    A flang/test/Lower/OpenMP/declare-reduction-shadows-intrinsic-separate.f90
    A flang/test/Lower/OpenMP/declare-reduction-shadows-intrinsic-use-assoc.f90
    M flang/test/Lower/OpenMP/declare-reduction-shadows-intrinsic.f90
    A flang/test/Lower/OpenMP/declare-reduction-special-separate-reexport.f90
    M flang/test/Lower/OpenMP/declare-reduction-target-intrinsic.f90
    A flang/test/Lower/OpenMP/multiple-types-declare_reduction.f90
    M flang/test/Lower/OpenMP/omp-declare-reduction-combsub.f90
    M flang/test/Lower/OpenMP/omp-declare-reduction-derivedtype.f90
    M flang/test/Lower/OpenMP/omp-declare-reduction-initsub.f90
    M flang/test/Lower/OpenMP/omp-declare-reduction.f90
    A flang/test/Semantics/OpenMP/declare-reduction-ambiguous.f90

  Log Message:
  -----------
  [flang][OpenMP] Lower cross-module user-defined declare reduction (#207493)

Lower a reduction clause naming a USE-associated, renamed, or merged-generic
user-defined reduction, which currently aborts lowering with a "not yet
implemented" TODO. Semantics already accepts these programs (since #200329).
This covers the defined-operator, intrinsic-operator, and named forms, each for
one or several types in a single declare reduction. One shape is still deferred.
A reduction on an allocatable or pointer operand of a trivial intrinsic element
type (integer, real, complex, or logical) is not lowered yet and reaches a clean
TODO, tracked by #186765. Character and derived-type allocatable reductions do
lower.

Fixes #207255.
Fixes #207489.

An imported reduction is materialized lazily. Its `omp.declare_reduction` op is
created on demand, only when a reduction clause has resolved the exact reduction
it references, through the same lowering path a local declare reduction uses.
There is no separate eager pass that walks accessible scopes to pre-create ops.
The module only-list property is therefore structural. A program using
`use m, only: <non-reduction>` never emits m's reduction, because nothing
references it. One path handles every import form: plain and renamed USE, nested
and merged generic operators, submodules, and intrinsic operators.

Resolve the use-site reduction to its source symbol through the shared semantic
resolver (`Fortran::semantics::omp::FindUserReductionSymbol`), extracted from
check-omp-structure.cpp into Semantics/openmp-utils so lowering and the semantic
checks share one resolution authority. Name the op from the resolved symbol's
ultimate name and owning scope via `getScopedUserReductionName`, on both the
clause and directive sides so the two cannot drift.

For a multi-type declare reduction, the same-file directive emits one op per
listed type and binds each variable to the op for its type. Lazy materialization
is stricter, emitting only the per-type op a clause requests, so an unsupported
sibling type does not block a supported one. The per-type lists advance in
lockstep: type, combiner, and initializer. The type suffix is unconditional,
including for a single-type reduction, so a multi-type per-type op cannot collide
with a single-type op sharing the same type-suffixed spelling.

Intrinsic-operator user reductions are named by their defining scope and ultimate
symbol, matching the defined-operator and named forms. Previously they used a
global name derived from the operator and element type, so two declare reductions
for the same operator and type in different scopes (two modules, or two
procedures in one file) could collide onto one op and silently bind the wrong
combiner. Builtin intrinsic reductions keep their global names.

For separate compilation the imported directive carries bound names but no typed
expressions, because mod-file reading runs only ResolveNames. The materializer
therefore runs expression analysis over the directive before lowering. Creating
the op from an imported module directive during lowering follows the imported
declare-mapper precedent.

An operator-less declare reduction (a special function such as max or min, or an
intrinsic operator such as `+` on an intrinsic type) has an internal mangled name
that is not valid Fortran, and no re-exported operator to recover through. When
such a reduction is re-exported through a facade, emitting it as a `use, only`
item produced a module file that failed to re-parse. The module-file writer
instead re-exports the defining module with a plain `use`, because a mangled name
cannot appear in an only-list. Entities the facade renames or makes private keep
their own use, rename, or private items, so the plain `use` does not widen their
visibility. The reduction then arrives as one shared use-association owned by the
defining module, binding the user's combiner rather than a facade-owned duplicate
that would fall back to the intrinsic. A private reduction is not re-exported.

When a reduction identifier resolves to more than one distinct user-defined
reduction for the list item's type, the clause is rejected as ambiguous rather
than selecting a combiner silently by USE order. Distinctness is by canonical
identity, the defining module and reduction name, so one reduction reached
through several USE, rename, or facade paths collapses to one candidate while
reductions from different modules stay separate. One case is not distinguished.
A same-named module loaded at two versions (a stale hermetic embed versus a
rebuilt copy) collapses to one candidate and is still resolved by USE order,
matching the prior behavior.

Assisted-by: Claude Opus 4.8, GPT-5.5.



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