Loop invariant operations#540
Conversation
| verif.ensure_compute %1 | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
We should add some tests here to check for mismatched loop args and init args.
There was a problem hiding this comment.
We should add some tests here for loops with init args
| [{Gets the ops that can be targeted by invariant ops.}], | ||
| "::llvm::SmallVector<::llzk::verif::InvariantTargetOpInterface>", | ||
| "getLoops", (ins), [{ | ||
| ::mlir::SmallVector<::llzk::verif::InvariantTargetOpInterface> targets; |
There was a problem hiding this comment.
I think this can be replaced with walkCollect
| }]; | ||
| } | ||
|
|
||
| def IncreasesOp : InvariantInnerOp<"increases"> {} |
There was a problem hiding this comment.
I didn't see any tests with these inner ops added, we should add some.
|
I had one broader concern while reading through this. The feature direction makes sense, but One thing I found confusing is the use of I also had questions about the structure of the new ops. Most of the invariant-related ops use ancestor checks rather than tighter placement rules. That makes it hard to tell whether nested invariants, nested steps, ranking ops inside steps, or broad The loop target binding also seems worth clarifying. The syntax looks symbol-like, for example Some tests that would make the intended behavior clearer: loops with init/iter args, duplicate labels in different scopes, nested invariant/step cases, misplaced inner ops, Overall I like the direction. I think this would be easier to build on if the invariant sublanguage had a more precise contract before more passes start depending on it. |
This PR adds operations for expressing loop invariants.
Invariants are defined with the
verif.invariantoperation and the other operations added in this PRare meant to be used within the body of that operation.
Also introduces two interfaces for handling contract and invariant targets. These interfaces abstract the exact operation that is
targeted by either a contract or an invariant. The contract target interface has been implemented for
function.defandstruct.defwhile the invariant target interface has been implemented for
scf.whileandscf.for.