Skip to content

Commit

Permalink
signess
Browse files Browse the repository at this point in the history
  • Loading branch information
HodanPlodky committed Jan 14, 2025
1 parent 16622be commit fb20392
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 23 deletions.
19 changes: 9 additions & 10 deletions tests/unit/compiler/venom/test_sccp_algebraic.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
RemoveUnusedVariablesPass,
StoreElimination,
)
from vyper.venom.passes.sccp.eval import signed_to_unsigned

"""
Test abstract binop+unop optimizations in sccp and algebraic optimizations pass
Expand Down Expand Up @@ -380,7 +379,7 @@ def test_comparison_almost_never():

max_uint256 = 2**256 - 1
max_int256 = 2**255 - 1
min_int256 = 2**255
min_int256 = -(2**255)
pre = f"""
_global:
%par = param
Expand Down Expand Up @@ -418,7 +417,7 @@ def test_comparison_almost_always():

max_uint256 = 2**256 - 1
max_int256 = 2**255 - 1
min_int256 = 2**255
min_int256 = -(2**255)

pre = f"""
_global:
Expand Down Expand Up @@ -466,15 +465,15 @@ def test_comparison_ge_le(val):
up = val + 1
down = val - 1

val = signed_to_unsigned(val, 256)
up = signed_to_unsigned(up, 256)
down = signed_to_unsigned(down, 256)
abs_val = abs(val)
abs_up = abs_val + 1
abs_down = abs_val - 1

pre = f"""
_global:
%par = param
%1 = lt %par, {val}
%3 = gt %par, {val}
%1 = lt %par, {abs_val}
%3 = gt %par, {abs_val}
%4 = iszero %3
%2 = iszero %1
%5 = slt %par, {val}
Expand All @@ -486,8 +485,8 @@ def test_comparison_ge_le(val):
post = f"""
_global:
%par = param
%1 = lt {down}, %par
%3 = gt {up}, %par
%1 = lt {abs_down}, %par
%3 = gt {abs_up}, %par
%5 = slt {down}, %par
%7 = sgt {up}, %par
return %1, %3, %5, %7
Expand Down
16 changes: 4 additions & 12 deletions vyper/venom/passes/algebraic_optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,18 +348,13 @@ 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):
if lit_eq(operands[0], almost_never, unsigned):
# (lt x 1), (gt x (MAX_UINT256 - 1)), (slt x (MIN_INT256 + 1))
self.updater._update(inst, "eq", [operands[1], IRLiteral(never)])
return

# rewrites. in positions where iszero is preferred, (gt x 5) => (ge x 6)
if prefer_iszero and lit_eq(operands[0], almost_always):
if prefer_iszero and lit_eq(operands[0], almost_always, unsigned):
# e.g. gt x 0, slt x MAX_INT256
tmp = self.updater._add_before(inst, "eq", operands)
self.updater._update(inst, "iszero", [tmp])
Expand All @@ -368,7 +363,7 @@ def _optimize_comparator_instruction(self, inst, prefer_iszero):
# since push0 was introduced in shanghai, it's potentially
# better to actually reverse this optimization -- i.e.
# replace iszero(iszero(x)) with (gt x 0)
if opcode == "gt" and lit_eq(operands[0], 0):
if opcode == "gt" and lit_eq(operands[0], 0, unsigned):
tmp = self.updater._add_before(inst, "iszero", [operands[1]])
self.updater._update(inst, "iszero", [tmp])
return
Expand Down Expand Up @@ -405,13 +400,10 @@ def _rewrite_ge_le(self, inst: IRInstruction):
val -= 1
new_opcode = _flip_comparison_op(opcode)

if not unsigned:
val = signed_to_unsigned(val, 256)

# this can happen for cases like `lt x 0` which get reduced in SCCP.
# don't handle them here, just return
# unsigned is true since we already converted it if needed
if _wrap256(val, unsigned=True) != val:
if _wrap256(val, unsigned) != val:
return

self.updater._update(inst, new_opcode, [IRLiteral(val), operands[1]])
Expand Down
4 changes: 3 additions & 1 deletion vyper/venom/passes/sccp/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
from vyper.venom.basicblock import IRLiteral, IROperand


def lit_eq(op: IROperand, val: int) -> bool:
def lit_eq(op: IROperand, val: int, unsigned: bool = True) -> bool:
if not unsigned:
return isinstance(op, IRLiteral) and _unsigned_to_signed(op.value) == val
return isinstance(op, IRLiteral) and op.value == val


Expand Down

0 comments on commit fb20392

Please sign in to comment.