|q⟩ Bad Qubits

advanced · Programming · Quantum Software Engineering & Resource Estimation

Intermediate Representations (QIR/QASM)

An intermediate representation (IR) is the data structure a compiler manipulates between the human-facing front end and the device-specific back end. In classical compilers this role is played by something like LLVM IR. Quantum computing has two dominant choices: OpenQASM, a text-based quantum assembly language, and QIR, an LLVM-based binary representation. Both exist so that a circuit can be analysed, optimised, and re-targeted without committing to any single front-end framework or back-end device.

What an IR must capture

A faithful quantum IR has to encode more than a gate list:

The op list our circuit(n) builder produces — a sequence of u, cu, swap, and measure records — is itself a miniature IR. It is serialisable, replayable, and analysable, which is exactly why the same description drives state-vector simulation, sampling, and resource counting.

OpenQASM: text, human-readable

OpenQASM (Open Quantum Assembly Language) reads like assembly for circuits. A Bell-pair program declares its registers, applies gates, and measures:

OPENQASM 3.0;
include "stdgates.inc";
qubit[2] q;
bit[2] c;
h q[0];
cx q[0], q[1];
c = measure q;

OpenQASM 3 adds real classical types, for/while loops, if conditioning on measurement, and user-defined gates with gate and def. Because it is text, it is easy to inspect, diff, and check into version control — properties we exploit in later lessons. Its weakness is that text is slow to parse and awkward to optimise programmatically at scale.

QIR: binary, LLVM-based

QIR (Quantum Intermediate Representation) takes the opposite approach: it represents a quantum program as LLVM IR, the same intermediate form used by Clang and Rust. Qubits and gates appear as opaque pointer types and function calls (e.g. __quantum__qis__h__body). Because QIR is LLVM IR, it inherits LLVM's mature optimisation infrastructure, its tooling, and its ability to interleave arbitrary classical computation with quantum operations. This makes QIR well suited to hybrid algorithms where classical and quantum code are tightly coupled, and to ahead-of-time compilation with aggressive optimisation passes.

What the IR layer buys you

Standardising on an IR delivers three concrete engineering wins:

  1. Interoperability. A circuit emitted by one framework can be consumed by another vendor's compiler, breaking the lock-in that would otherwise tie an algorithm to one stack.
  2. Optimisation. Passes such as gate cancellation (XX=IXX = I), rotation merging (Rz(α)Rz(β)=Rz(α+β)R_z(\alpha)R_z(\beta) = R_z(\alpha+\beta)), and commutation-based rescheduling all operate on the IR, reducing depth and gate count before transpilation.
  3. Analysis without execution. Resource estimators walk the IR to tally qubits, gate counts, TT-counts, and depth — the numbers the rest of this module is about — without ever simulating or running the circuit.

A note on lowering

Translating a higher IR to a lower one is called lowering. Lowering OpenQASM to a device means decomposing each abstract gate into the target's native set and routing two-qubit gates onto the hardware connectivity graph. Crucially, lowering is not unique: the same logical circuit has many valid lowerings with different gate counts and depths, and choosing a good one is the optimisation problem at the heart of transpilation. Because the choice changes the resource cost, every honest resource estimate must state which gate set and connectivity it assumes.

Sign in on the full site to ask questions and join the discussion.