‘qc’ Dialect

The QC (reference semantics) dialect for quantum computing.

The QC dialect uses reference semantics where quantum operations modify qubits in place, similar to how hardware physically transforms quantum states. This model provides:

  • Natural mapping to hardware execution models

  • Intuitive representation for circuit descriptions

  • Direct compatibility with imperative quantum programming languages

  • Straightforward backend code generation

The name “QC” stands for “Quantum Circuit.”

Example:

qc.h %q          // Applies Hadamard to qubit %q in place
qc.swap %q0, %q1 // Applies SWAP using %q0, %q1 as targets

Operations

qc.alloc (qc::AllocOp)

Allocate a qubit dynamically

Syntax:

operation ::= `qc.alloc` attr-dict `:` type($result)

Allocates a new qubit dynamically and returns a reference to it. The qubit is initialized to the |0⟩ state.

Example:

%q = qc.alloc : !qc.qubit

Interfaces: InferTypeOpInterface, MemoryEffectOpInterface (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{MemoryEffects::Allocate on ::mlir::SideEffects::DefaultResource}

Results:

Result

Description

result

QC qubit reference type

qc.barrier (qc::BarrierOp)

Apply a barrier gate to a set of qubits

Syntax:

operation ::= `qc.barrier` $qubits attr-dict `:` type($qubits)

Applies a barrier gate to a set of qubits, modifying them in place.

Example:

qc.barrier %q : !qc.qubit

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubits

variadic of QC qubit reference type

qc.ctrl (qc::CtrlOp)

Add control qubits to a unitary operation

Syntax:

operation ::= `qc.ctrl` `(` $controls `)`
              `targets`
              custom<TargetAliasing>($region, $targets)
              attr-dict `:`
              `{` type($controls) `}` ( `,` `{` type($targets)^ `}` )?

A modifier operation that adds control qubits to the unitary operation defined in its body region. The controlled operation applies the underlying unitary only when all control qubits are in the \(|1\rangle\) state.

Note that control qubits are logically unmodified by this operation in that their quantum state remains unchanged. However, the controls argument is marked with MemWrite to ensure correct dependency tracking in MLIR.

The body region may contain an arbitrary amount of unitary and classical operations. Non-unitary operations, such as AllocOp and MeasureOp, are not allowed.

Example:

qc.ctrl(%q0) targets(%a0 = %q1) {
  qc.x %a0 : !qc.qubit
} : !qc.qubit

Traits: AttrSizedOperandSegments, RecursiveMemoryEffects, SingleBlockImplicitTerminator<::mlir::qc::YieldOp>, SingleBlock

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

controls

variadic of QC qubit reference type

targets

variadic of QC qubit reference type

qc.dcx (qc::DCXOp)

Apply a DCX gate to two qubits

Syntax:

operation ::= `qc.dcx` $qubit0_in `,` $qubit1_in attr-dict `:` type($qubit0_in) `,` type($qubit1_in)

Applies a DCX gate to two qubits, modifying them in place.

Example:

qc.dcx %q0, %q1 : !qc.qubit, !qc.qubit

Traits: TwoTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit0_in

QC qubit reference type

qubit1_in

QC qubit reference type

qc.dealloc (qc::DeallocOp)

Deallocate a qubit

Syntax:

operation ::= `qc.dealloc` $qubit attr-dict `:` type($qubit)

Deallocates a qubit, releasing its resources.

Example:

qc.dealloc %q : !qc.qubit

Interfaces: MemoryEffectOpInterface (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{MemoryEffects::Free on ::mlir::SideEffects::DefaultResource}

Operands:

Operand

Description

qubit

QC qubit reference type

qc.ecr (qc::ECROp)

Apply an ECR gate to two qubits

Syntax:

operation ::= `qc.ecr` $qubit0_in `,` $qubit1_in attr-dict `:` type($qubit0_in) `,` type($qubit1_in)

Applies an ECR gate to two qubits, modifying them in place.

Example:

qc.ecr %q0, %q1 : !qc.qubit, !qc.qubit

Traits: TwoTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit0_in

QC qubit reference type

qubit1_in

QC qubit reference type

qc.gphase (qc::GPhaseOp)

Apply a global phase to the state

Syntax:

operation ::= `qc.gphase` `(` $theta `)` attr-dict

Applies a global phase to the state.

Example:

qc.gphase(%theta)

Traits: ZeroTargetOneParameter

Interfaces: MemoryEffectOpInterface (MemoryEffectOpInterface), UnitaryOpInterface

Effects: MemoryEffects::Effect{MemoryEffects::Write on ::mlir::SideEffects::DefaultResource}

Operands:

Operand

Description

theta

64-bit float

qc.h (qc::HOp)

Apply an H gate to a qubit

Syntax:

operation ::= `qc.h` $qubit_in attr-dict `:` type($qubit_in)

Applies an H gate to a qubit, modifying it in place.

Example:

qc.h %q : !qc.qubit

Traits: OneTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

qc.id (qc::IdOp)

Apply an Id gate to a qubit

Syntax:

operation ::= `qc.id` $qubit_in attr-dict `:` type($qubit_in)

Applies an Id gate to a qubit, modifying it in place.

Example:

qc.id %q : !qc.qubit

Traits: OneTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

qc.inv (qc::InvOp)

Invert a unitary operation

Syntax:

operation ::= `qc.inv` custom<TargetAliasing>($region, $qubits)
              attr-dict `:`
              type($qubits)

A modifier operation that inverts the unitary operation defined in its body region.

The body region may contain an arbitrary amount of unitary and classical operations. Non-unitary operations, such as AllocOp and MeasureOp, are not allowed.

Example:

qc.inv (%a0 = %q0) {
  qc.s %a0 : !qc.qubit
}

Traits: RecursiveMemoryEffects, SingleBlockImplicitTerminator<::mlir::qc::YieldOp>, SingleBlock

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubits

variadic of QC qubit reference type

qc.iswap (qc::iSWAPOp)

Apply a iSWAP gate to two qubits

Syntax:

operation ::= `qc.iswap` $qubit0_in `,` $qubit1_in attr-dict `:` type($qubit0_in) `,` type($qubit1_in)

Applies a iSWAP gate to two qubits, modifying them in place.

Example:

qc.iswap %q0, %q1 : !qc.qubit, !qc.qubit

Traits: TwoTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit0_in

QC qubit reference type

qubit1_in

QC qubit reference type

qc.measure (qc::MeasureOp)

Measure a qubit in the computational basis

Syntax:

operation ::= `qc.measure` (`(` $register_name^ `,` $register_size `,` $register_index `)`)?
              $qubit `:` type($qubit) `->` type($result) attr-dict

Measures a qubit in the computational (Z) basis, collapsing the state and returning a classical bit result.

Optionally, the measurement can be recorded to an output register by specifying:

  • register_name: Name of the classical register (e.g., “c”)

  • register_size: Total size of the register

  • register_index: Index within the register for this measurement

Example (simple measurement):

%result = qc.measure %q : !qc.qubit -> i1

Example (measurement with output recording):

%result = qc.measure("c", 2, 0) %q : !qc.qubit -> i1

Interfaces: InferTypeOpInterface

Attributes:

AttributeMLIR TypeDescription
register_name::mlir::StringAttrstring attribute
register_size::mlir::IntegerAttr64-bit signless integer attribute whose value is positive
register_index::mlir::IntegerAttr64-bit signless integer attribute whose value is non-negative

Operands:

Operand

Description

qubit

QC qubit reference type

Results:

Result

Description

result

1-bit signless integer

qc.p (qc::POp)

Apply a P gate to a qubit

Syntax:

operation ::= `qc.p` `(` $theta `)` $qubit_in attr-dict `:` type($qubit_in)

Applies a P gate to a qubit, modifying it in place.

Example:

qc.p(%theta) %q : !qc.qubit

Traits: OneTargetOneParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

theta

64-bit float

qc.r (qc::ROp)

Apply an R gate to a qubit

Syntax:

operation ::= `qc.r` `(` $theta `,` $phi `)` $qubit_in attr-dict `:` type($qubit_in)

Applies an R gate to a qubit, modifying it in place.

Example:

qc.r(%theta, %phi) %q : !qc.qubit

Traits: OneTargetTwoParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

theta

64-bit float

phi

64-bit float

qc.reset (qc::ResetOp)

Reset a qubit to |0⟩ state

Syntax:

operation ::= `qc.reset` $qubit attr-dict `:` type($qubit)

Resets a qubit to the |0⟩ state, regardless of its current state.

Example:

qc.reset %q : !qc.qubit

Operands:

Operand

Description

qubit

QC qubit reference type

qc.rx (qc::RXOp)

Apply an RX gate to a qubit

Syntax:

operation ::= `qc.rx` `(` $theta `)` $qubit_in attr-dict `:` type($qubit_in)

Applies an RX gate to a qubit, modifying it in place.

Example:

qc.rx(%theta) %q : !qc.qubit

Traits: OneTargetOneParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

theta

64-bit float

qc.rxx (qc::RXXOp)

Apply an RXX gate to two qubits

Syntax:

operation ::= `qc.rxx` `(` $theta `)` $qubit0_in `,` $qubit1_in attr-dict `:` type($qubit0_in) `,` type($qubit1_in)

Applies an RXX gate to two qubits, modifying them in place.

Example:

qc.rxx(%theta) %q0, %q1 : !qc.qubit, !qc.qubit

Traits: TwoTargetOneParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit0_in

QC qubit reference type

qubit1_in

QC qubit reference type

theta

64-bit float

qc.ry (qc::RYOp)

Apply an RY gate to a qubit

Syntax:

operation ::= `qc.ry` `(` $theta `)` $qubit_in attr-dict `:` type($qubit_in)

Applies an RY gate to a qubit, modifying it in place.

Example:

qc.ry(%theta) %q : !qc.qubit

Traits: OneTargetOneParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

theta

64-bit float

qc.ryy (qc::RYYOp)

Apply an RYY gate to two qubits

Syntax:

operation ::= `qc.ryy` `(` $theta `)` $qubit0_in `,` $qubit1_in attr-dict `:` type($qubit0_in) `,` type($qubit1_in)

Applies an RYY gate to two qubits, modifying them in place.

Example:

qc.ryy(%theta) %q0, %q1 : !qc.qubit, !qc.qubit

Traits: TwoTargetOneParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit0_in

QC qubit reference type

qubit1_in

QC qubit reference type

theta

64-bit float

qc.rz (qc::RZOp)

Apply an RZ gate to a qubit

Syntax:

operation ::= `qc.rz` `(` $theta `)` $qubit_in attr-dict `:` type($qubit_in)

Applies an RZ gate to a qubit, modifying it in place.

Example:

qc.rz(%theta) %q : !qc.qubit

Traits: OneTargetOneParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

theta

64-bit float

qc.rzx (qc::RZXOp)

Apply an RZX gate to two qubits

Syntax:

operation ::= `qc.rzx` `(` $theta `)` $qubit0_in `,` $qubit1_in attr-dict `:` type($qubit0_in) `,` type($qubit1_in)

Applies an RZX gate to two qubits, modifying them in place.

Example:

qc.rzx(%theta) %q0, %q1 : !qc.qubit, !qc.qubit

Traits: TwoTargetOneParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit0_in

QC qubit reference type

qubit1_in

QC qubit reference type

theta

64-bit float

qc.rzz (qc::RZZOp)

Apply an RZZ gate to two qubits

Syntax:

operation ::= `qc.rzz` `(` $theta `)` $qubit0_in `,` $qubit1_in attr-dict `:` type($qubit0_in) `,` type($qubit1_in)

Applies an RZZ gate to two qubits, modifying them in place.

Example:

qc.rzz(%theta) %q0, %q1 : !qc.qubit, !qc.qubit

Traits: TwoTargetOneParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit0_in

QC qubit reference type

qubit1_in

QC qubit reference type

theta

64-bit float

qc.s (qc::SOp)

Apply an S gate to a qubit

Syntax:

operation ::= `qc.s` $qubit_in attr-dict `:` type($qubit_in)

Applies an S gate to a qubit, modifying it in place.

Example:

qc.s %q : !qc.qubit

Traits: OneTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

qc.sdg (qc::SdgOp)

Apply an Sdg gate to a qubit

Syntax:

operation ::= `qc.sdg` $qubit_in attr-dict `:` type($qubit_in)

Applies an Sdg gate to a qubit, modifying it in place.

Example:

qc.sdg %q : !qc.qubit

Traits: OneTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

qc.static (qc::StaticOp)

Retrieve a static qubit by index

Syntax:

operation ::= `qc.static` $index attr-dict `:` type($qubit)

The qc.static operation produces an SSA value representing a qubit identified by a static index. This is useful for referring to fixed qubits in a quantum program or to hardware-mapped qubits.

Example:

%q = qc.static 0 : !qc.qubit

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
index::mlir::IntegerAttr64-bit signless integer attribute whose value is non-negative

Results:

Result

Description

qubit

QC qubit reference type

qc.swap (qc::SWAPOp)

Apply a SWAP gate to two qubits

Syntax:

operation ::= `qc.swap` $qubit0_in `,` $qubit1_in attr-dict `:` type($qubit0_in) `,` type($qubit1_in)

Applies a SWAP gate to two qubits, modifying them in place.

Example:

qc.swap %q0, %q1 : !qc.qubit, !qc.qubit

Traits: TwoTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit0_in

QC qubit reference type

qubit1_in

QC qubit reference type

qc.sx (qc::SXOp)

Apply an SX gate to a qubit

Syntax:

operation ::= `qc.sx` $qubit_in attr-dict `:` type($qubit_in)

Applies an SX gate to a qubit, modifying it in place.

Example:

qc.sx %q : !qc.qubit

Traits: OneTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

qc.sxdg (qc::SXdgOp)

Apply an SXdg gate to a qubit

Syntax:

operation ::= `qc.sxdg` $qubit_in attr-dict `:` type($qubit_in)

Applies an SXdg gate to a qubit, modifying it in place.

Example:

qc.sxdg %q : !qc.qubit

Traits: OneTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

qc.t (qc::TOp)

Apply a T gate to a qubit

Syntax:

operation ::= `qc.t` $qubit_in attr-dict `:` type($qubit_in)

Applies a T gate to a qubit, modifying it in place.

Example:

qc.t %q : !qc.qubit

Traits: OneTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

qc.tdg (qc::TdgOp)

Apply a Tdg gate to a qubit

Syntax:

operation ::= `qc.tdg` $qubit_in attr-dict `:` type($qubit_in)

Applies a Tdg gate to a qubit, modifying it in place.

Example:

qc.tdg %q : !qc.qubit

Traits: OneTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

qc.u (qc::UOp)

Apply a U gate to a qubit

Syntax:

operation ::= `qc.u` `(` $theta `,` $phi `,` $lambda `)` $qubit_in attr-dict `:` type($qubit_in)

Applies a U gate to a qubit, modifying it in place.

Example:

qc.u(%theta, %phi, %lambda) %q : !qc.qubit

Traits: OneTargetThreeParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

theta

64-bit float

phi

64-bit float

lambda

64-bit float

qc.u2 (qc::U2Op)

Apply a U2 gate to a qubit

Syntax:

operation ::= `qc.u2` `(` $phi `,` $lambda `)` $qubit_in attr-dict `:` type($qubit_in)

Applies a U2 gate to a qubit, modifying it in place.

Example:

qc.u2(%phi, %lambda) %q : !qc.qubit

Traits: OneTargetTwoParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

phi

64-bit float

lambda

64-bit float

qc.x (qc::XOp)

Apply an X gate to a qubit

Syntax:

operation ::= `qc.x` $qubit_in attr-dict `:` type($qubit_in)

Applies an X gate to a qubit, modifying it in place.

Example:

qc.x %q : !qc.qubit

Traits: OneTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

qc.xx_minus_yy (qc::XXMinusYYOp)

Apply an XX-YY gate to two qubits

Syntax:

operation ::= `qc.xx_minus_yy` `(` $theta `,` $beta `)` $qubit0_in `,` $qubit1_in attr-dict `:` type($qubit0_in) `,` type($qubit1_in)

Applies an XX-YY gate to two qubits, modifying them in place.

Example:

qc.xx_minus_yy(%theta, %beta) %q0, %q1 : !qc.qubit, !qc.qubit

Traits: TwoTargetTwoParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit0_in

QC qubit reference type

qubit1_in

QC qubit reference type

theta

64-bit float

beta

64-bit float

qc.xx_plus_yy (qc::XXPlusYYOp)

Apply an XX+YY gate to two qubits

Syntax:

operation ::= `qc.xx_plus_yy` `(` $theta `,` $beta `)` $qubit0_in `,` $qubit1_in attr-dict `:` type($qubit0_in) `,` type($qubit1_in)

Applies an XX+YY gate to two qubits, modifying them in place.

Example:

qc.xx_plus_yy(%theta, %beta) %q0, %q1 : !qc.qubit, !qc.qubit

Traits: TwoTargetTwoParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit0_in

QC qubit reference type

qubit1_in

QC qubit reference type

theta

64-bit float

beta

64-bit float

qc.y (qc::YOp)

Apply a Y gate to a qubit

Syntax:

operation ::= `qc.y` $qubit_in attr-dict `:` type($qubit_in)

Applies a Y gate to a qubit, modifying it in place.

Example:

qc.y %q : !qc.qubit

Traits: OneTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

qc.yield (qc::YieldOp)

Yield from a modifier region

Syntax:

operation ::= `qc.yield` attr-dict

Terminates a modifier region, yielding control back to the enclosing operation.

Traits: Terminator

qc.z (qc::ZOp)

Apply a Z gate to a qubit

Syntax:

operation ::= `qc.z` $qubit_in attr-dict `:` type($qubit_in)

Applies a Z gate to a qubit, modifying it in place.

Example:

qc.z %q : !qc.qubit

Traits: OneTargetZeroParameter

Interfaces: UnitaryOpInterface

Operands:

Operand

Description

qubit_in

QC qubit reference type

Types

QubitType

QC qubit reference type

Syntax: !qc.qubit

The !qc.qubit type represents a reference to a quantum bit in the QC dialect. Operations using this type modify qubits in place using reference semantics, similar to how classical imperative languages handle mutable references.

OpInterface definitions

UnitaryOpInterface (UnitaryOpInterface)

This interface provides a unified API for all operations that apply or produce a unitary transformation. This includes base gates, user-defined gates, modifier operations (control, inverse, power), and sequences.

The interface enables uniform introspection and composition capabilities across all unitary operations in the QC dialect.

Methods:

getNumQubits
size_t getNumQubits();

Returns the number of qubits acted on by the unitary operation.

NOTE: This method must be implemented by the user.

getNumTargets
size_t getNumTargets();

Returns the number of target qubits (excluding control qubits).

NOTE: This method must be implemented by the user.

getNumControls
size_t getNumControls();

Returns the number of control qubits (both positive and negative).

NOTE: This method must be implemented by the user.

getQubit
Value getQubit(size_t i);

Returns the i-th qubit (targets + controls combined).

NOTE: This method must be implemented by the user.

getTarget
Value getTarget(size_t i);

Returns the i-th target qubit.

NOTE: This method must be implemented by the user.

getControl
Value getControl(size_t i);

Returns the i-th control qubit.

NOTE: This method must be implemented by the user.

getQubits
OperandRange getQubits();

Returns a range of all qubits (targets + controls combined).

NOTE: This method must be implemented by the user.

getTargets
OperandRange getTargets();

Returns a range of all target qubits.

NOTE: This method must be implemented by the user.

getControls
OperandRange getControls();

Returns a range of all control qubits.

NOTE: This method must be implemented by the user.

getNumParams
size_t getNumParams();

Returns the number of parameters.

NOTE: This method must be implemented by the user.

getParameter
Value getParameter(size_t i);

Returns the i-th parameter.

NOTE: This method must be implemented by the user.

getParameters
OperandRange getParameters();

Returns a range of all parameters.

NOTE: This method must be implemented by the user.

isControlled
bool isControlled();

Returns true if the operation has any control qubits, otherwise false.

isSingleQubit
bool isSingleQubit();

Returns true if the operation only acts on a single qubit.

isTwoQubit
bool isTwoQubit();

Returns true if the operation acts on two qubits.

getBaseSymbol
StringRef getBaseSymbol();

Returns the base symbol/mnemonic of the operation.

NOTE: This method must be implemented by the user.

Passes

-qc-shrink-qubit-registers

Shrink static qc::QubitType MemRef registers to accessed indices.

Shrinks one-dimensional static MemRef registers with element type !qc.qubit by removing never-read indices and remapping memref.load users accordingly.