Skip to content

QIR Generation panics when conditional branches use early return #2290

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
swernli opened this issue Apr 11, 2025 · 0 comments
Open

QIR Generation panics when conditional branches use early return #2290

swernli opened this issue Apr 11, 2025 · 0 comments
Labels
bug Something isn't working needs triage

Comments

@swernli
Copy link
Collaborator

swernli commented Apr 11, 2025

The following code causes a panic in QIR generation:

function Branch(value : Bool) : Int {
    if (value) {
        return 3;
    } else {
        return 4;
    }
}
@EntryPoint()
operation Main() : Int {
    use qubits = Qubit[2];
    H(qubits[0]);
    CNOT(qubits[0], qubits[1]);
    let result = Branch(MResetZ(qubits[0]) == Zero);
    result
}

However, the same code with implicit returns in the function works as expected:

function Branch(value : Bool) : Int {
    if (value) {
        3
    } else {
        4
    }
}
@EntryPoint()
operation Main() : Int {
    use qubits = Qubit[2];
    H(qubits[0]);
    CNOT(qubits[0], qubits[1]);
    let result = Branch(MResetZ(qubits[0]) == Zero);
    result
}

This appears to be because of how the BranchControlFlow::Return is used to short circuit the handling of the rest of the block:

if body_control.is_return() {
return Ok(BranchControlFlow::Return(body_control.into_value()));
}

This causes the generated RIR program to be missing branch and jump terminator instructions at the end of blocks. The empty block (should have one terminating jump) is what triggers the specific panic, but other non-empty blocks also are missing terminators that mean the program is invalid.

Either the early return should be fully handled by refactoring the control flow handling for dynamic branches (which must correctly handling inlining for functions like the example above) or the RuntimeFeatureFlags::ReturnWithinDynamicScope should be updated to require more than just TargetCapabilityFlags::Adaptive so that RCA rejects this pattern at compile time.

@swernli swernli added bug Something isn't working needs triage labels Apr 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs triage
Projects
None yet
Development

No branches or pull requests

1 participant