Skip to content

Commit

Permalink
fix[venom]: move loop invariant assertion to entry block (#4098)
Browse files Browse the repository at this point in the history
loop invariant bound check was in the body of the loop, not the entry
block. move it up to the entry so we don't re-check the same assertion
every loop iteration.
  • Loading branch information
charles-cooper authored Jun 10, 2024
1 parent 24cfe0b commit 4d1bacd
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 14 deletions.
4 changes: 2 additions & 2 deletions tests/functional/syntax/test_for_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,14 @@ def foo():
"""
@external
def foo():
x: int128 = 5
x: int128 = 4
for i: int128 in range(x, bound=4):
pass
""",
"""
@external
def foo():
x: int128 = 5
x: int128 = 4
for i: int128 in range(0, x, bound=4):
pass
""",
Expand Down
20 changes: 8 additions & 12 deletions vyper/venom/ir_node_to_venom.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,14 +468,7 @@ def emit_body_blocks():
start, end, _ = _convert_ir_bb_list(fn, ir.args[1:4], symbols)

assert ir.args[3].is_literal, "repeat bound expected to be literal"

bound = ir.args[3].value
if (
isinstance(end, IRLiteral)
and isinstance(start, IRLiteral)
and end.value + start.value <= bound
):
bound = None

body = ir.args[4]

Expand All @@ -491,19 +484,22 @@ def emit_body_blocks():

counter_var = entry_block.append_instruction("store", start)
symbols[sym.value] = counter_var

if bound is not None:
# assert le end bound
invalid_end = entry_block.append_instruction("gt", bound, end)
valid_end = entry_block.append_instruction("iszero", invalid_end)
entry_block.append_instruction("assert", valid_end)

end = entry_block.append_instruction("add", start, end)
if bound:
bound = entry_block.append_instruction("add", start, bound)

entry_block.append_instruction("jmp", cond_block.label)

xor_ret = cond_block.append_instruction("xor", counter_var, end)
cont_ret = cond_block.append_instruction("iszero", xor_ret)
fn.append_basic_block(cond_block)

fn.append_basic_block(body_block)
if bound:
xor_ret = body_block.append_instruction("xor", counter_var, bound)
body_block.append_instruction("assert", xor_ret)

emit_body_blocks()
body_end = fn.get_basic_block()
Expand Down

0 comments on commit 4d1bacd

Please sign in to comment.