Differentiate FIR and basic support for Fortran MLIR#2969
Draft
vchuravy wants to merge 6 commits into
Draft
Conversation
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
force-pushed
the
flang-plugin-sketch
branch
from
July 23, 2026 10:09
919ab16 to
3f67afa
Compare
vchuravy
force-pushed
the
flang-fir-plugin
branch
from
July 23, 2026 10:09
37683b4 to
9b544ae
Compare
vchuravy
force-pushed
the
flang-plugin-sketch
branch
from
July 23, 2026 12:02
3f67afa to
2cac952
Compare
vchuravy
force-pushed
the
flang-fir-plugin
branch
4 times, most recently
from
July 23, 2026 15:39
bfff057 to
a5daaf1
Compare
vchuravy
force-pushed
the
flang-plugin-sketch
branch
from
July 23, 2026 15:39
5c556a3 to
290e091
Compare
vchuravy
force-pushed
the
flang-fir-plugin
branch
from
July 23, 2026 15:41
a5daaf1 to
eef53d0
Compare
vchuravy
force-pushed
the
flang-plugin-sketch
branch
from
July 23, 2026 15:41
290e091 to
0a0078a
Compare
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
force-pushed
the
flang-plugin-sketch
branch
from
July 23, 2026 15:48
0a0078a to
74585c6
Compare
vchuravy
force-pushed
the
flang-fir-plugin
branch
from
July 23, 2026 15:48
eef53d0 to
90369f2
Compare
vchuravy
commented
Jul 23, 2026
| // | ||
| // 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 |
Member
Author
There was a problem hiding this comment.
Use https://github.com/EnzymeAD/Enzyme/pull/2980 for fir.alloca
vchuravy
commented
Jul 23, 2026
Member
Author
There was a problem hiding this comment.
This should be on flang-plugin-sketch
vchuravy
commented
Jul 23, 2026
vchuravy
commented
Jul 23, 2026
| $<TARGET_FILE:MLIREnzymeAutoDiffInterface> | ||
| -Wl,--end-group) | ||
| target_link_options(FlangEnzymeMLIR-${LLVM_VERSION_MAJOR} PRIVATE | ||
| -Wl,--allow-shlib-undefined) |
Member
Author
There was a problem hiding this comment.
This should be on flang-plugin-sketch partially
…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>
vchuravy
force-pushed
the
flang-fir-plugin
branch
from
July 23, 2026 16:17
e63b5cc to
e086584
Compare
vchuravy
commented
Jul 23, 2026
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') | ||
|
|
Member
Author
There was a problem hiding this comment.
This should likely be on flang-plugin-sketch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Differentiate the basic FIR constructs.
🤖 Generated with Claude Code