Skip to content

🔁 MLIR - inv (adjoint) modifier (op- and region-level) #1130

@burgholzer

Description

@burgholzer

Background

We currently support eagerly evaluated inversion in MQT Core IR (e.g., Operation::invert, Operation::get_inverted). In MLIR, however, we want inversion to be represented and optimized lazily by the compiler rather than applied eagerly in-place. Most quantum languages expose an inv/adjoint modifier for both single ops and blocks.

Problem

Add MLIR support for a single inv modifier that can apply to either a single op or a region (block) of ops, with lazy semantics: the IR carries the modifier and canonicalization/lowering passes decide when to rewrite or sink it. Provide canonicalizations for all standard unitary gates we define so the modifier can be eliminated when it’s provably safe.

Proposal:

  • Use one name for both forms: mqtref.inv.
    • Region form (authoritative IR): mqtref.inv owns a region containing unitary-only ops; verifier enforces unitary-only content.
    • Single-op sugar: mqtref.inv may print/parse as a local modifier around a single op (or a per-op {inv} attribute that canonicalizes to the region form). The canonical IR remains the region wrapper.
  • Lazy evaluation requirement:
    • Do not eagerly rewrite the target operation(s) at construction/import time. Preserve mqtref.inv in the IR until a canonicalization or lowering pass applies.
    • Pass(es) provide the eager rewrites when legal (e.g., invert rotation angles, reverse order for blocks) and otherwise keep mqtref.inv for later stages.
  • Canonicalizations (must-cover set): provide adjoints for all standard unitary gates in our dialect, including but not limited to
    • Single-qubit: H (self-adjoint), X/Y/Z (self-adjoint), S ↔ Sdg, T ↔ Tdg, Rx(θ) → Rx(-θ), Ry(θ) → Ry(-θ), Rz(θ) → Rz(-θ), etc.
    • Two-qubit: CX/CNOT (self-adjoint), CZ (self-adjoint), SWAP (self-adjoint), CRz(θ) → CRz(-θ); in general, Ctrl(U)† = Ctrl(U†) where legal.
    • Composite/compound: reverse operation order and apply the per-op adjoint canonicalizations.
  • Interfaces/traits:
    • Introduce/require a UnitaryOpInterface (or equivalent trait) that marks ops/regions eligible for mqtref.inv.
    • Verifier rejects non-unitary content inside mqtref.inv regions.
  • Interop with Core IR:
    • Lowering/raising should avoid Core’s eager inversion by default; prefer representing inversion as mqtref.inv and only materialize eager rewrites in designated passes.

Examples

  • Single-op (sugar) — prints as a local modifier but canonicalizes to region form:
    // Printed sugar (parser may accept this and build a one-op region)
    mqtref.inv {
      mqtref.rz %q, %theta : (!mqtref.qubit, f64) -> ()
    }
    // Canonicalization may rewrite to:
    // mqtref.rz %q, %neg_theta : (!mqtref.qubit, f64) -> ()
    // where %neg_theta = arith.negf %theta
  • Region-level (block adjoint):
    mqtref.inv {
      mqtref.h  %q0 : !mqtref.qubit
      mqtref.cz %q0, %q1 : !mqtref.qubit, !mqtref.qubit
    }
    // Canonicalization: reverse order and adjoint per op
    // => mqtref.cz %q0, %q1; mqtref.h %q0 (both self-adjoint)

Acceptance criteria

  • mqtref.inv exists and is usable both as a region wrapper and (via sugar) for single ops; verifier enforces unitary-only content.
  • Lazy-by-default behavior: construction/import never eagerly inverts; canonicalizations and lowerings control when inv is eliminated.
  • Canonicalizations implemented for all standard unitary gates in our dialect (single- and two-qubit families, plus controlled variants when unitary).
  • Tests for: single-op inversion, block inversion (order reversal + per-op adjoints), rejection of non-unitary content, and preservation of inv when not yet legal to rewrite.
  • Documentation in docs/mlir.md updated to reflect naming, lazy semantics, and canonicalization coverage.

Metadata

Metadata

Assignees

Labels

MLIRAnything related to MLIRc++Anything related to C++ codefeatureNew feature or request

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions