Skip to content

Fix miscompile due to SSA aliasing - #3775

Open
Stefan J. Wernli (swernli) wants to merge 4 commits into
mainfrom
swernli/issue3769
Open

Stefan J. Wernli (swernli) wants to merge 4 commits into
mainfrom
swernli/issue3769

Conversation

@swernli

@swernli Stefan J. Wernli (swernli) commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

This change updates variable mapping logic in RIR passes to differentiate between "deep" and "shallow" mappings, where the former indicates the mapping should be followed through successive links until the terminator operand is reached and the latter indicates no further mapping should be performed. Fixes #3769

This change updates variable mapping logic in RIR passes to differentiate between "strong" and "weak" mappings, where the former indicates the mapping should be followed through successive links until the terminator operand is reached and the latter indicates no further mapping should be performed.
Fixes #3769
Comment thread source/compiler/qsc_rir/src/rir.rs
Comment thread source/compiler/qsc_rir/src/utils.rs
Comment thread source/compiler/qsc/src/codegen/tests/adaptive_profile.rs
Comment thread source/compiler/qsc_rir/src/passes/ssa_transform/tests.rs
if var_stor_to_keep.contains(&var.variable_id) {
// Only keep stores to variables that are in the set to keep.
*operand = operand.mapped(var_map);
} else if let Operand::Variable(mapped_var) = operand.mapped(var_map)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't depend on whether it's deep or shallow?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not directly, but operand.mapped(var_map) will follow the deep vs shallow rules, so stop at the first shallow mapping.

Comment thread source/compiler/qsc_rir/src/passes/ssa_transform.rs Outdated
@amcasey

Andrew Casey (amcasey) commented Oct 1, 2026 •

Copy link
Copy Markdown
Member
operation Main() : Int {
    use q0 = Qubit();
    use q1 = Qubit();

    X(q0);
    X(q1);

    mutable n = 0;
    if MResetZ(q0) == One {
        n = 1;
    }

    let h = n;

    if MResetZ(q1) == One {
        n = 2;
    }

    h + n
}

Expected: 3
Actual: 4

Speculative explanation (copilot): At ssa_transform.rs:167, only Shallow(n) aliases are redirected when the earlier phi for n is created. An alias that is still Deep(n) remains tied to the mutable ID. Later, ssa_transform.rs:190 can overwrite the shallow mapping created by a branch-local mutation.

@swernli

Copy link
Copy Markdown
Contributor Author
operation Main() : Int {

    use q0 = Qubit();

    use q1 = Qubit();



    X(q0);

    X(q1);



    mutable n = 0;

    if MResetZ(q0) == One {

        n = 1;

    }



    let h = n;



    if MResetZ(q1) == One {

        n = 2;

    }



    h + n

}

Expected: 3

Actual: 4

Speculative explanation (copilot): At ssa_transform.rs:167, only Shallow(n) aliases are redirected when the earlier phi for n is created. An alias that is still Deep(n) remains tied to the mutable ID. Later, ssa_transform.rs:190 can overwrite the shallow mapping created by a branch-local mutation.

This is the resolved in the latest changes.

@swernli
Stefan J. Wernli (swernli) added this pull request to stack #3786 October 2, 2026 17:12

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Miscompile due to SSA aliasing

2 participants