diff --git a/test/formal/opcodes.py b/test/formal/opcodes.py index cdd60ddae..e65ecef29 100644 --- a/test/formal/opcodes.py +++ b/test/formal/opcodes.py @@ -42,6 +42,9 @@ def ISZERO(x): def AND(x, y): return x & y +def OR(x, y): + return x | y + def SHL(x, y): return y << x diff --git a/test/formal/repeated_and.py b/test/formal/repeated_and.py new file mode 100644 index 000000000..2e8431b3c --- /dev/null +++ b/test/formal/repeated_and.py @@ -0,0 +1,39 @@ +from rule import Rule +from opcodes import * + +""" +Rule: +AND(AND(X, Y), Y) -> AND(X, Y) +AND(Y, AND(X, Y)) -> AND(X, Y) +AND(AND(Y, X), Y) -> AND(Y, X) +AND(Y, AND(Y, X)) -> AND(Y, X) +Requirements: +""" + +rule = Rule() + +n_bits = 256 + +# Input vars +X = BitVec('X', n_bits) +Y = BitVec('Y', n_bits) + +# Constants +BitWidth = BitVecVal(n_bits, n_bits) + +# Requirements + +# Non optimized result +nonopt_1 = AND(AND(X, Y), Y) +nonopt_2 = AND(Y, AND(X, Y)) +nonopt_3 = AND(AND(Y, X), Y) +nonopt_4 = AND(Y, AND(Y, X)) + +# Optimized result +opt_1 = AND(X, Y) +opt_2 = AND(Y, X) + +rule.check(nonopt_1, opt_1) +rule.check(nonopt_2, opt_1) +rule.check(nonopt_3, opt_2) +rule.check(nonopt_4, opt_2) diff --git a/test/formal/repeated_or.py b/test/formal/repeated_or.py new file mode 100644 index 000000000..c1b2ebd09 --- /dev/null +++ b/test/formal/repeated_or.py @@ -0,0 +1,39 @@ +from rule import Rule +from opcodes import * + +""" +Rule: +OR(OR(X, Y), Y) -> OR(X, Y) +OR(Y, OR(X, Y)) -> OR(X, Y) +OR(OR(Y, X), Y) -> OR(Y, X) +OR(Y, OR(Y, X)) -> OR(Y, X) +Requirements: +""" + +rule = Rule() + +n_bits = 256 + +# Input vars +X = BitVec('X', n_bits) +Y = BitVec('Y', n_bits) + +# Constants +BitWidth = BitVecVal(n_bits, n_bits) + +# Requirements + +# Non optimized result +nonopt_1 = OR(OR(X, Y), Y) +nonopt_2 = OR(Y, OR(X, Y)) +nonopt_3 = OR(OR(Y, X), Y) +nonopt_4 = OR(Y, OR(Y, X)) + +# Optimized result +opt_1 = OR(X, Y) +opt_2 = OR(Y, X) + +rule.check(nonopt_1, opt_1) +rule.check(nonopt_2, opt_1) +rule.check(nonopt_3, opt_2) +rule.check(nonopt_4, opt_2)