Description
The constant propagation pass crashes with InterpreterError: SSAValue <DeletedSSAValue[State]...> not found when processing a kernel that contains triple-nested for-loops iterating over IList[IList[MeasurementResult, Any], Any].
The same logic expressed without loops (manually unrolled) compiles and runs correctly.
Minimal Reproduction
The reproduction requires bloqade-lanes (branch rafaelha/mvp_decoding) because the bug is triggered during compile_to_physical_stim_program, which calls the kirin aggressive-unroll → hint-const → constprop pipeline.
from bloqade.gemini import logical as gemini_logical
from bloqade import qubit, squin, annotate, types
from bloqade.lanes.logical_mvp import (
compile_to_physical_stim_program,
kernel,
set_observable,
)
from kirin.dialects import ilist
from typing import Any
# ── This kernel triggers the bug ──────────────────────────────
@kernel
def set_detector_loopy(
meas: ilist.IList[ilist.IList[types.MeasurementResult, Any], Any],
):
h = [[0, 1, 2, 3], [1, 2, 4, 5], [2, 3, 4, 6]]
num_meas = len(meas)
for i in range(len(h)):
stab = h[i]
res = []
for j in range(4):
for k in range(num_meas):
m = meas[k]
res = res + [m[stab[j]]]
annotate.set_detector(res, coordinates=[0, i])
# ── This equivalent kernel works fine ─────────────────────────
@kernel
def set_detector_unrolled(meas: ilist.IList[types.MeasurementResult, Any]):
annotate.set_detector([meas[0], meas[1], meas[2], meas[3]], coordinates=[0, 0])
annotate.set_detector([meas[1], meas[2], meas[4], meas[5]], coordinates=[0, 1])
annotate.set_detector([meas[2], meas[3], meas[4], meas[6]], coordinates=[0, 2])
@kernel
def circuit():
reg = qubit.qalloc(2)
squin.h(reg[0])
squin.cx(reg[0], reg[1])
measurements = gemini_logical.terminal_measure(reg)
set_detector_loopy(measurements) # ← crashes
# Workaround: use unrolled version per-qubit instead
# set_detector_unrolled(measurements[0]) # ← works
# set_detector_unrolled(measurements[1]) # ← works
set_observable(measurements[0], 0)
set_observable(measurements[1], 1)
program = compile_to_physical_stim_program(circuit) # raises InterpreterError
Stack Trace
File "kirin/passes/hint_const.py", line 18, in unsafe_run
frame, _ = constprop.run(mt)
File "kirin/analysis/forward.py", line 41, in run
return self.call(method, self.method_self(method), *args, **kwargs)
...
File "kirin/dialects/cf/constprop.py", line 40, in conditional_branch
stmt.then_successor, *frame.get_values(stmt.then_arguments)
File "kirin/interp/frame.py", line 121, in get
raise InterpreterError(f"SSAValue {key} not found")
kirin.interp.exceptions.InterpreterError: SSAValue <DeletedSSAValue[State] value: <ResultValue[State] stmt: load, uses: 0>, uses: 6> not found
The full call chain is:
compile_to_physical_stim_program → squin_to_stim → SquinToStimPass → Flatten.fixpoint → AggressiveUnroll → HintConst → ConstProp.run → crash in cf/constprop.py:conditional_branch
Versions Tested
| Version |
Result |
| kirin-toolchain 0.22.6 (PyPI) |
FAIL |
| kirin-toolchain 0.22.9 (PyPI) |
FAIL |
kirin-toolchain 0.23.0.dev0 (main @ d600bcce) |
FAIL |
Analysis
During aggressive unrolling of triple-nested for-loops, the constant propagation pass encounters an SSA value (ResultValue[State] from a load statement) that has been deleted but is still referenced by 6 uses in a conditional_branch's then_arguments. This suggests the IR rewrite that deletes the load statement does not properly update or remap the references held by the branch terminator.
Possibly related: PR #632 (ConstProp Early Termination Optimization).
Workaround
Manually unroll the loops so the kernel contains no for-loop constructs.
Description
The constant propagation pass crashes with
InterpreterError: SSAValue <DeletedSSAValue[State]...> not foundwhen processing a kernel that contains triple-nestedfor-loops iterating overIList[IList[MeasurementResult, Any], Any].The same logic expressed without loops (manually unrolled) compiles and runs correctly.
Minimal Reproduction
The reproduction requires
bloqade-lanes(branchrafaelha/mvp_decoding) because the bug is triggered duringcompile_to_physical_stim_program, which calls the kirin aggressive-unroll → hint-const → constprop pipeline.Stack Trace
The full call chain is:
compile_to_physical_stim_program→squin_to_stim→SquinToStimPass→Flatten.fixpoint→AggressiveUnroll→HintConst→ConstProp.run→ crash incf/constprop.py:conditional_branchVersions Tested
d600bcce)Analysis
During aggressive unrolling of triple-nested
for-loops, the constant propagation pass encounters an SSA value (ResultValue[State]from aloadstatement) that has been deleted but is still referenced by 6 uses in aconditional_branch'sthen_arguments. This suggests the IR rewrite that deletes theloadstatement does not properly update or remap the references held by the branch terminator.Possibly related: PR #632 (ConstProp Early Termination Optimization).
Workaround
Manually unroll the loops so the kernel contains no
for-loop constructs.