Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions tests/compiler/ir/test_optimize_ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@
(["le", 0, "x"], [1]),
(["le", 0, ["sload", 0]], None), # no-op
(["ge", "x", 0], [1]),
(["le", "x", "x"], [1]),
(["ge", "x", "x"], [1]),
(["sle", "x", "x"], [1]),
(["sge", "x", "x"], [1]),
(["lt", "x", "x"], [0]),
(["gt", "x", "x"], [0]),
(["slt", "x", "x"], [0]),
(["sgt", "x", "x"], [0]),
# boundary conditions
(["slt", "x", -(2**255)], [0]),
(["sle", "x", -(2**255)], ["eq", "x", -(2**255)]),
Expand Down Expand Up @@ -253,3 +261,10 @@ def test_ir_optimizer(ir):
def test_static_assertions(ir, assert_compile_failed):
ir = IRnode.from_list(ir)
assert_compile_failed(lambda: optimizer.optimize(ir), StaticAssertionException)


def test_operator_set_values():
# some sanity checks
assert optimizer.COMPARISON_OPS == {"lt", "gt", "le", "ge", "slt", "sgt", "sle", "sge"}
assert optimizer.STRICT_COMPARISON_OPS == {"lt", "gt", "slt", "sgt"}
assert optimizer.UNSTRICT_COMPARISON_OPS == {"le", "ge", "sle", "sge"}
15 changes: 12 additions & 3 deletions vyper/ir/optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ def _deep_contains(node_or_list, node):

COMMUTATIVE_OPS = {"add", "mul", "eq", "ne", "and", "or", "xor"}
COMPARISON_OPS = {"gt", "sgt", "ge", "sge", "lt", "slt", "le", "sle"}
STRICT_COMPARISON_OPS = {t for t in COMPARISON_OPS if t.endswith("t")}
UNSTRICT_COMPARISON_OPS = {t for t in COMPARISON_OPS if t.endswith("e")}

assert not (STRICT_COMPARISON_OPS & UNSTRICT_COMPARISON_OPS)
assert STRICT_COMPARISON_OPS | UNSTRICT_COMPARISON_OPS == COMPARISON_OPS


def _flip_comparison_op(opname):
Expand Down Expand Up @@ -256,11 +261,15 @@ def _conservative_eq(x, y):
return finalize("seq", [args[0]])

if binop in {"sub", "xor", "ne"} and _conservative_eq(args[0], args[1]):
# x - x == x ^ x == x != x == 0
# (x - x) == (x ^ x) == (x != x) == 0
return finalize(0, [])

if binop in STRICT_COMPARISON_OPS and _conservative_eq(args[0], args[1]):
# (x < x) == (x > x) == 0
return finalize(0, [])

if binop == "eq" and _conservative_eq(args[0], args[1]):
# (x == x) == 1
if binop in {"eq"} | UNSTRICT_COMPARISON_OPS and _conservative_eq(args[0], args[1]):
# (x == x) == (x >= x) == (x <= x) == 1
return finalize(1, [])

# TODO associativity rules
Expand Down