The reverse-mode call handler refuses a callee that writes memory:
cannot differentiate a call in reverse mode whose callee touches memory; caching of overwritten arguments is not yet implemented here
The refusal exists because the adjoint of a call re-runs/uses the callee's primal values in the reverse pass, and a pointer argument may have been overwritten between the original forward execution of the call and its reverse — LLVM Enzyme handles this with overwritten_args (caching the argument values/buffers that later writes clobber), which has no MLIR-side counterpart yet (#3079 renamed the plumbing to overwritten_args but the analysis and caching are not implemented).
The guard checks, transitively through direct callees: an llvm.call/llvm.func with a none memory_effects attr or readnone passthrough, or a body whose ops are all memory-effect-free. What it cannot accept is a callee that genuinely stores — enzyme/test/MLIR/ReverseMode/func_call_write.mlir (a callee writing through a dup memref argument) is exactly that case and is marked XFAIL until the caching lands.
@Pangoraw — flagging per the split-reverse discussion: implementing overwritten-args caching on the MLIR side would re-enable that test (remove its XFAIL) and lift the refusal generally.
🤖 Generated with Claude Code
https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
The reverse-mode call handler refuses a callee that writes memory:
The refusal exists because the adjoint of a call re-runs/uses the callee's primal values in the reverse pass, and a pointer argument may have been overwritten between the original forward execution of the call and its reverse — LLVM Enzyme handles this with
overwritten_args(caching the argument values/buffers that later writes clobber), which has no MLIR-side counterpart yet (#3079 renamed the plumbing tooverwritten_argsbut the analysis and caching are not implemented).The guard checks, transitively through direct callees: an
llvm.call/llvm.funcwith a nonememory_effectsattr orreadnonepassthrough, or a body whose ops are all memory-effect-free. What it cannot accept is a callee that genuinely stores —enzyme/test/MLIR/ReverseMode/func_call_write.mlir(a callee writing through a dup memref argument) is exactly that case and is marked XFAIL until the caching lands.@Pangoraw — flagging per the split-reverse discussion: implementing overwritten-args caching on the MLIR side would re-enable that test (remove its XFAIL) and lift the refusal generally.
🤖 Generated with Claude Code
https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD