Skip to content

Commit

Permalink
fix: Fix linearity checking bug (#441)
Browse files Browse the repository at this point in the history
Fixes #438.

When checking that all live linear places in scope are definitely used,
we have to be more careful about determining whether variables are
*actually* live rather than only being included in scope because of the
less precise first pass of liveness analysis.
  • Loading branch information
mark-koch authored Sep 2, 2024
1 parent 5a59da3 commit 0b8ea21
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 1 deletion.
8 changes: 8 additions & 0 deletions guppylang/checker/linearity_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ def check_cfg_linearity(
checked: dict[BB, CheckedBB[Place]] = {}

for bb, scope in scopes.items():
live_before_bb = live_before[bb]

# We have to check that used linear variables are not being outputted
for succ in bb.successors:
live = live_before[succ]
Expand Down Expand Up @@ -457,6 +459,12 @@ def check_cfg_linearity(
for place in scope.values():
for leaf in leaf_places(place):
x = leaf.id
# Some values are just in scope because the type checker determined
# them as live in the first (less precises) dataflow analysis. It
# might be the case that x is actually not live when considering
# the second, more fine-grained, analysis based on places.
if x not in live_before_bb and x not in scope.vars:
continue
used_later = x in live
if leaf.ty.linear and not scope.used(x) and not used_later:
# TODO: This should be "Variable x with linear type ty is not
Expand Down
1 change: 0 additions & 1 deletion tests/integration/test_inout.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ def main(s: MyStruct, t: MyStruct) -> MyStruct:
validate(module.compile())


@pytest.mark.skip("Fails due to https://github.com/CQCL/guppylang/issues/337")
def test_move_back_branch(validate):
module = GuppyModule("test")
module.load(quantum)
Expand Down
24 changes: 24 additions & 0 deletions tests/integration/test_linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,30 @@ def foo(i: bool) -> bool:
return b


def test_while_move_back(validate):
module = GuppyModule("test")
module.load(quantum)

@guppy.struct(module)
class MyStruct:
q: qubit

@guppy.declare(module)
def use(q: qubit) -> None: ...

@guppy(module)
def test(s: MyStruct) -> MyStruct:
use(s.q)
while True:
s.q = qubit()
return s
# Guppy is not yet smart enough to detect that this code is unreachable
s.q = qubit()
return s

validate(module.compile())


def test_for(validate):
module = GuppyModule("test")
module.load(quantum)
Expand Down

0 comments on commit 0b8ea21

Please sign in to comment.