diff --git a/tests/unit/compiler/venom/test_sccp_algebraic.py b/tests/unit/compiler/venom/test_sccp_algebraic.py index 108eab0d60..a91206650d 100644 --- a/tests/unit/compiler/venom/test_sccp_algebraic.py +++ b/tests/unit/compiler/venom/test_sccp_algebraic.py @@ -367,3 +367,37 @@ def test_comparison_zero(): """ _sccp_algebraic_runner(pre, post) + + +def test_comparison_almost_never(): + # x > 0 => iszero(iszero x) + # 0 < x => iszero(iszero x) + + max_uint256 = 2**256 - 1 + max_int256 = 2**255 - 1 + min_int256 = 2**255 + pre = f""" + _global: + %par = param + %1 = lt %par, 1 + %2 = gt 1, %par + %3 = gt %par, {max_uint256 - 1} + %4 = sgt %par, {max_int256 - 1} + %5 = slt %par, {min_int256 + 1} + return %1, %2, %3, %4, %5 + """ + post = f""" + _global: + %par = param + ; first into eq 0 %par then into iszere + %1 = iszero %par + %2 = iszero %par + ; this also goes through eq + %6 = not %par + %3 = iszero %6 + %4 = eq {max_int256}, %par + %5 = eq {min_int256}, %par + return %1, %2, %3, %4, %5 + """ + + _sccp_algebraic_runner(pre, post) diff --git a/vyper/venom/passes/algebraic_optimization.py b/vyper/venom/passes/algebraic_optimization.py index 36f3cdd92f..d13f5855df 100644 --- a/vyper/venom/passes/algebraic_optimization.py +++ b/vyper/venom/passes/algebraic_optimization.py @@ -348,6 +348,11 @@ def _optimize_comparator_instruction(self, inst, prefer_iszero): almost_always, never = hi, lo almost_never = lo + 1 + if not unsigned: + almost_never = signed_to_unsigned(almost_never, 256, strict=True) + almost_always = signed_to_unsigned(almost_always, 256, strict=True) + never = signed_to_unsigned(never, 256, strict=True) + if lit_eq(operands[0], almost_never): # (lt x 1), (gt x (MAX_UINT256 - 1)), (slt x (MIN_INT256 + 1)) self.updater._update(inst, "eq", [operands[1], IRLiteral(never)])