From 2e6fbe7daaa13a46f8a1934f26b601776d2b58ad Mon Sep 17 00:00:00 2001 From: Harry Kalogirou Date: Wed, 1 May 2024 23:06:12 +0300 Subject: [PATCH] fix[codegen]: same symbol jumpdest merge (#3982) Update the assembly optimizer to return `False` when trying to optimize two consecutive `JUMPDEST`s with the same symbol. It used to return `True` when no change was made (resulting in an infinite loop) + unit tests --- tests/unit/compiler/asm/test_asm_optimizer.py | 7 +++++++ vyper/ir/compile_ir.py | 9 +++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/unit/compiler/asm/test_asm_optimizer.py b/tests/unit/compiler/asm/test_asm_optimizer.py index 5742f7c8df..ee6b1653b0 100644 --- a/tests/unit/compiler/asm/test_asm_optimizer.py +++ b/tests/unit/compiler/asm/test_asm_optimizer.py @@ -3,6 +3,7 @@ from vyper.compiler import compile_code from vyper.compiler.phases import CompilerData from vyper.compiler.settings import OptimizationLevel, Settings +from vyper.ir.compile_ir import _merge_jumpdests codes = [ """ @@ -123,3 +124,9 @@ def foo(): assert "unused1()" not in asm assert "unused2()" not in asm + + +def test_merge_jumpdests(): + asm = ["_sym_label_0", "JUMP", "PUSH0", "_sym_label_0", "JUMPDEST", "_sym_label_0", "JUMPDEST"] + + assert _merge_jumpdests(asm) is False, "should not return True as no changes were made" diff --git a/vyper/ir/compile_ir.py b/vyper/ir/compile_ir.py index 191803295e..472d28f4fb 100644 --- a/vyper/ir/compile_ir.py +++ b/vyper/ir/compile_ir.py @@ -892,10 +892,11 @@ def _merge_jumpdests(assembly): # replace all instances of _sym_x with _sym_y # (except for _sym_x JUMPDEST - don't want duplicate labels) new_symbol = assembly[i + 2] - for j in range(len(assembly)): - if assembly[j] == current_symbol and i != j: - assembly[j] = new_symbol - changed = True + if new_symbol != current_symbol: + for j in range(len(assembly)): + if assembly[j] == current_symbol and i != j: + assembly[j] = new_symbol + changed = True elif is_symbol(assembly[i + 2]) and assembly[i + 3] == "JUMP": # _sym_x JUMPDEST _sym_y JUMP # replace all instances of _sym_x with _sym_y