Skip to content

Commit

Permalink
add optimizer rules for exp
Browse files Browse the repository at this point in the history
  • Loading branch information
charles-cooper committed May 6, 2022
1 parent f999143 commit 2d49d2f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
7 changes: 7 additions & 0 deletions tests/compiler/ir/test_optimize_ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@
(["mod", "x", 128], ["and", "x", 127]),
(["sdiv", "x", 64], ["sdiv", "x", 64]), # no-op
(["smod", "x", 64], ["smod", "x", 64]), # no-op
(["exp", 3, 5], [3**5]),
(["exp", 3, 256], [(3**256) % (2**256)]),
(["exp", 2, 257], [0]),
(["exp", "x", 0], ["iszero", "x"]),
(["exp", "x", 1], ["x"]),
(["exp", 1, "x"], [1]),
(["exp", 0, "x"], [0]),
# bitwise ops
(["shr", 0, "x"], ["x"]),
(["sar", 0, "x"], ["x"]),
Expand Down
15 changes: 15 additions & 0 deletions vyper/ir/optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def _is_int(node: IRnode) -> bool:
"sdiv": (evm_div, "/", SIGNED),
"mod": (evm_mod, "%", UNSIGNED),
"smod": (evm_mod, "%", SIGNED),
"exp": (operator.pow, "**", UNSIGNED),
"eq": (operator.eq, "==", UNSIGNED),
"ne": (operator.ne, "!=", UNSIGNED),
"lt": (operator.lt, "<", UNSIGNED),
Expand Down Expand Up @@ -165,6 +166,20 @@ def _conservative_eq(x, y):
new_val = "sub"
new_args = [0, args[0]]

elif binop == "exp":
# n ** 0 == (0 if n == 0 else 1)
if _int(args[1]) == 0:
new_val = "iszero"
new_args = [args[0]]
# n ** 1 == n
if _int(args[1]) == 1:
new_val = args[0].value
new_args = args[0].args
# 0 ** n == 0; 1 ** n == 1
if _int(args[0]) in (0, 1):
new_val = _int(args[0])
new_args = []

# maybe OK:
# elif binop == "div" and _int(args[1], UNSIGNED) == MAX_UINT256:
# # (div x (2**256 - 1)) == (eq x (2**256 - 1))
Expand Down

0 comments on commit 2d49d2f

Please sign in to comment.