Skip to content

Differentiate FIR and basic support for Fortran MLIR#2969

Draft
vchuravy wants to merge 6 commits into
flang-plugin-sketchfrom
flang-fir-plugin
Draft

Differentiate FIR and basic support for Fortran MLIR#2969
vchuravy wants to merge 6 commits into
flang-plugin-sketchfrom
flang-fir-plugin

Conversation

@vchuravy

@vchuravy vchuravy commented Jul 22, 2026

Copy link
Copy Markdown
Member

Differentiate the basic FIR constructs.

🤖 Generated with Claude Code

vchuravy added a commit that referenced this pull request Jul 23, 2026
Extends the StoreLikeInterface generalization to the remaining store sites
in ActivityAnalysis and gates the pointer-like type check on the type
interface, so out-of-tree dialects (e.g. FIR/HLFIR) participate fully in
activity analysis without hard-coded dyn_casts. These are the
Fortran-independent pieces of #2969.

- isConstantValue: besides LLVM ptr / memref, treat any type whose
  AutoDiffTypeInterface reports isMutable() (e.g. !fir.ref) as a reference
  that carries active memory. Behavior-preserving in-tree: among core
  dialects only memref and LLVM pointer report isMutable(), and both are
  already matched by the existing isa<> check.
- isOperationInactiveFromOrigin: dialect-agnostic store branch mirroring
  the LLVM::StoreOp case (inactive iff stored value or pointer is constant).
- isValueActivelyStoredOrReturned: dialect-agnostic store branch mirroring
  the LLVM::StoreOp case.

Deliberately excludes the Fortran-coupled / behavior-changing parts of
#2969 (FIR/HLFIR models, flang plugin, the CoreDialects registration TU
split, and dropping tensor/linalg from the pass dependent dialects).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
vchuravy added a commit that referenced this pull request Jul 23, 2026
Extends the StoreLikeInterface generalization to the remaining store sites
in ActivityAnalysis and gates the pointer-like type check on the type
interface, so out-of-tree dialects (e.g. FIR/HLFIR) participate fully in
activity analysis without hard-coded dyn_casts. These are the
Fortran-independent pieces of #2969.

- isConstantValue: besides LLVM ptr / memref, treat any type whose
  AutoDiffTypeInterface reports isMutable() (e.g. !fir.ref) as a reference
  that carries active memory. Behavior-preserving in-tree: among core
  dialects only memref and LLVM pointer report isMutable(), and both are
  already matched by the existing isa<> check.
- isOperationInactiveFromOrigin: dialect-agnostic store branch mirroring
  the LLVM::StoreOp case (inactive iff stored value or pointer is constant).
- isValueActivelyStoredOrReturned: dialect-agnostic store branch mirroring
  the LLVM::StoreOp case.

Deliberately excludes the Fortran-coupled / behavior-changing parts of
#2969 (FIR/HLFIR models, flang plugin, the CoreDialects registration TU
split, and dropping tensor/linalg from the pass dependent dialects).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vchuravy
vchuravy force-pushed the flang-plugin-sketch branch from 919ab16 to 3f67afa Compare July 23, 2026 10:09
@vchuravy
vchuravy force-pushed the flang-plugin-sketch branch from 3f67afa to 2cac952 Compare July 23, 2026 12:02
@vchuravy
vchuravy force-pushed the flang-fir-plugin branch 4 times, most recently from bfff057 to a5daaf1 Compare July 23, 2026 15:39
@vchuravy
vchuravy force-pushed the flang-plugin-sketch branch from 5c556a3 to 290e091 Compare July 23, 2026 15:39
@vchuravy
vchuravy force-pushed the flang-plugin-sketch branch from 290e091 to 0a0078a Compare July 23, 2026 15:41
vchuravy added a commit that referenced this pull request Jul 23, 2026
Extends the StoreLikeInterface generalization to the remaining store sites
in ActivityAnalysis and gates the pointer-like type check on the type
interface, so out-of-tree dialects (e.g. FIR/HLFIR) participate fully in
activity analysis without hard-coded dyn_casts. These are the
Fortran-independent pieces of #2969.

- isConstantValue: besides LLVM ptr / memref, treat any type whose
  AutoDiffTypeInterface reports isMutable() (e.g. !fir.ref) as a reference
  that carries active memory. Behavior-preserving in-tree: among core
  dialects only memref and LLVM pointer report isMutable(), and both are
  already matched by the existing isa<> check.
- isOperationInactiveFromOrigin: dialect-agnostic store branch mirroring
  the LLVM::StoreOp case (inactive iff stored value or pointer is constant).
- isValueActivelyStoredOrReturned: dialect-agnostic store branch mirroring
  the LLVM::StoreOp case.

Deliberately excludes the Fortran-coupled / behavior-changing parts of
#2969 (FIR/HLFIR models, flang plugin, the CoreDialects registration TU
split, and dropping tensor/linalg from the pass dependent dialects).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vchuravy
vchuravy force-pushed the flang-plugin-sketch branch from 0a0078a to 74585c6 Compare July 23, 2026 15:48
//
// Enzyme autodiff support for FIR's by-reference memory model, so whole Fortran
// functions differentiate: their arguments and locals are !fir.ref<T> and the
// body is fir.load / hlfir.assign / fir.alloca / hlfir.declare over that

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use https://github.com/EnzymeAD/Enzyme/pull/2980 for fir.alloca

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be on flang-plugin-sketch

Comment thread enzyme/Enzyme/MLIR/Implementations/HLFIRFlangPluginRegistration.cpp
$<TARGET_FILE:MLIREnzymeAutoDiffInterface>
-Wl,--end-group)
target_link_options(FlangEnzymeMLIR-${LLVM_VERSION_MAJOR} PRIVATE
-Wl,--allow-shlib-undefined)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be on flang-plugin-sketch partially

vchuravy and others added 5 commits July 23, 2026 18:15
…lugins

Sets up the flang-dependent autodiff layer and its delivery vehicles for
differentiating by-reference Fortran (arguments/locals are !fir.ref<T>):

  * FIRAutoDiffOpInterfaceImpl.cpp + FIRDerivatives.td -- !fir.ref<T> as active
    memory: AutoDiffTypeInterface (mutable, parallel-ref shadow), the FIR/HLFIR
    memory ops as active-memory identities (fir.load/store, fir.alloca,
    hlfir.declare/assign), StoreLikeInterface, and hand-written reverse adjoints
    for fir.load/store, hlfir.assign, hlfir.declare (mirroring the LLVM dialect).
    Added to the flang-dependent MLIREnzymeHLFIRImplementations library.
  * fir-enzyme-opt registers the core + FIR autodiff interfaces.
  * enzyme-fir-plugin.cpp (FIREnzyme) -- the fir-opt dialect+pass plugin for a
    shared-libMLIR build; HLFIRFlangPluginRegistration.cpp (FlangEnzymeMLIR) --
    the -load'able plugin that registers the Enzyme passes into flang's own
    codegen pipeline via fir::registerPassPipelineConfigCallback.
  * %firenzyme / %firopt / %flang_enzyme lit substitutions.

The Tier-1 hlfir.* array-intrinsic models (hlfir.matmul) attach on top of this
layer in a follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BkvJByk8nTti2GiF4RudNG
Two core activity-analysis generalizations so whole by-reference Fortran
functions differentiate, kept free of any FIR/HLFIR dependency:

  * ActivityAnalysis.cpp queries enzyme::StoreLikeInterface alongside the
    existing memref/LLVM store cases, so activity propagates from an active
    stored value to the pointer written for fir.store / hlfir.assign.
  * isConstantValue's pointer-type gate now also admits any type whose
    AutoDiffTypeInterface::isMutable() is true (fir.ref, and any out-of-tree
    mutable reference), so a local fir.alloca result buffer enters the
    memory-based activity search. The memory-identity forward handler inverts a
    constant mutable operand rather than erroring.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BkvJByk8nTti2GiF4RudNG
fir-enzyme-opt FileCheck tests for !fir.ref forward and reverse modes through
the by-reference memory model (fir_ref_fwd/rev, fir_ref_function_result_fwd/rev),
a smoke test for the FIR+Enzyme wiring, and end-to-end flang-plugin tests
(flang_plugin_lower/emit_llvm/executable) that drive `flang -fc1` with the
FlangEnzymeMLIR plugin on a scalar function.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BkvJByk8nTti2GiF4RudNG
FIR_README.md (fir-enzyme-opt / plugin delivery vehicles, the static-LLVM
cl::opt constraint) and plan_fortran.md (the flang+plugin end-to-end plan and
op-level Tier-1/2/3 breakdown).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BkvJByk8nTti2GiF4RudNG
This entry point is implemented and used by this layer (FIRAutoDiffOpInterfaceImpl.cpp,
fir-enzyme-opt), so declare it here rather than in the base plugin header.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment on lines +70 to +85
# fir-opt (from the Flang/LLVM build) plus the FIREnzyme dialect+pass plugin, so
# hlfir.* array intrinsics can be differentiated while still ops. %firenzyme is
# the two --load-*-plugin flags; %firopt is fir-opt already carrying them.
firenzyme_plugin = (config.enzyme_obj_root
+ "/Enzyme/MLIR/FIREnzyme-" + config.llvm_ver
+ config.llvm_shlib_ext)
if len("@ENZYME_BINARY_DIR@") == 0:
firenzyme_plugin = (os.path.dirname(os.path.abspath(__file__))
+ "/../FIREnzyme-" + config.llvm_ver + config.llvm_shlib_ext)
firenzyme_flags = (" --load-dialect-plugin=" + firenzyme_plugin
+ " --load-pass-plugin=" + firenzyme_plugin)
config.substitutions.append(('%firenzyme', firenzyme_flags))
config.substitutions.append(('%firopt', config.llvm_tools_dir + "/fir-opt" + firenzyme_flags))
if os.path.exists(config.llvm_tools_dir + "/fir-opt") and os.path.exists(firenzyme_plugin):
config.available_features.add('fir_enzyme_plugin')

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should likely be on flang-plugin-sketch

@vchuravy vchuravy changed the title Differentiate HLFIR array intrinsics via Enzyme-MLIR (fir-opt tool + flang plugin) Differentiate FIR and basic support for Fortran MLIR Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant