Skip to content

Commit 9b88719

Browse files
committed
Update rewrite rules
Update MOre te
1 parent 5633a8a commit 9b88719

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

src/EVM/Expr.hs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,9 +1073,6 @@ simplify e = if (mapExpr go e == e)
10731073
-- literal addresses
10741074
go (WAddr (LitAddr a)) = Lit $ into a
10751075

1076-
-- XOR normalization
1077-
go (Xor a b) = EVM.Expr.xor a b
1078-
10791076
-- simple div/mod/add/sub
10801077
go (Div o1@(Lit _) o2@(Lit _)) = EVM.Expr.div o1 o2
10811078
go (SDiv o1@(Lit _) o2@(Lit _)) = EVM.Expr.sdiv o1 o2
@@ -1104,7 +1101,6 @@ simplify e = if (mapExpr go e == e)
11041101
-- Notice: all Add is normalized, hence the 1st argument is
11051102
-- expected to be Lit, if any. Hence `orig` needs to be the
11061103
-- 2nd argument for Add. However, Sub is not normalized
1107-
go (Add (Lit x) (Add (Lit y) orig)) = add (Lit (x+y)) orig
11081104
-- add + sub NOTE: every combination of Sub is needed (2)
11091105
go (Add (Lit x) (Sub (Lit y) orig)) = sub (Lit (x+y)) orig
11101106
go (Add (Lit x) (Sub orig (Lit y))) = add (Lit (x-y)) orig
@@ -1117,18 +1113,27 @@ simplify e = if (mapExpr go e == e)
11171113
go (Sub (Lit x) (Add (Lit y) orig)) = sub (Lit (x-y)) orig
11181114
go (Sub (Add (Lit x) orig) (Lit y) ) = add (Lit (x-y)) orig
11191115

1116+
-- Add+Add / Mul+Mul / Xor+Xor simplifications, taking
1117+
-- advantage of associativity and commutativity
1118+
-- Since Lit is smallest in the ordering, it will always be the first argument
1119+
-- hence these will collect Lits. See `simp-assoc..` tests
1120+
go (Add (Lit a) (Add (Lit b) x)) = add (Lit (a+b)) x
1121+
go (Mul (Lit a) (Mul (Lit b) x)) = mul (Lit (a*b)) x
1122+
go (Xor (Lit a) (Xor (Lit b) x)) = EVM.Expr.xor (Lit (Data.Bits.xor a b)) x
1123+
go (Add a (Add b c)) = add (l !! 0) (add (l !! 1) (l !! 2))
1124+
where l = sort [a, b, c]
1125+
go (Mul a (Mul b c)) = mul (l !! 0) (mul (l !! 1) (l !! 2))
1126+
where l = sort [a, b, c]
1127+
go (Xor a (Xor b c)) = x (l !! 0) (x (l !! 1) (l !! 2))
1128+
where l = sort [a, b, c]
1129+
x = EVM.Expr.xor
1130+
11201131
-- redundant add / sub
11211132
go (Sub (Add a b) c)
11221133
| a == c = b
11231134
| b == c = a
11241135
| otherwise = sub (add a b) c
11251136

1126-
-- Add is associative. We are doing left-growing trees because LIT is
1127-
-- arranged to the left. This way, they accumulate in all combinations.
1128-
-- See `sim-assoc-add` test cases in test.hs
1129-
go (Add a (Add b c)) = add (add a b) c
1130-
go (Add (Add (Lit a) x) (Lit b)) = add (Lit (a+b)) x
1131-
11321137
-- add / sub identities
11331138
go (Add a b)
11341139
| b == (Lit 0) = a
@@ -1139,6 +1144,9 @@ simplify e = if (mapExpr go e == e)
11391144
| b == (Lit 0) = a
11401145
| otherwise = sub a b
11411146

1147+
-- XOR normalization
1148+
go (Xor a b) = EVM.Expr.xor a b
1149+
11421150
-- SHL / SHR by 0
11431151
go (SHL a v)
11441152
| a == (Lit 0) = v
@@ -1192,11 +1200,6 @@ simplify e = if (mapExpr go e == e)
11921200
(Lit 0, _) -> Lit 0
11931201
_ -> EVM.Expr.min a b
11941202

1195-
-- Mul is associative. We are doing left-growing trees because LIT is
1196-
-- arranged to the left. This way, they accumulate in all combinations.
1197-
-- See `sim-assoc-add` test cases in test.hs
1198-
go (Mul a (Mul b c)) = mul (mul a b) c
1199-
go (Mul (Mul (Lit a) x) (Lit b)) = mul (Lit (a*b)) x
12001203

12011204
-- Some trivial mul eliminations
12021205
go (Mul a b) = case (a, b) of

test/test.hs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -559,11 +559,11 @@ tests = testGroup "hevm"
559559
let simp = Expr.simplifyProp $ PLT (Max (Lit 5) (BufLength (AbstractBuf "txdata"))) (Lit 99)
560560
assertEqualM "max-buflength rules" simp $ PLT (BufLength (AbstractBuf "txdata")) (Lit 99)
561561
, test "simp-assoc-add1" $ do
562-
let simp = Expr.simplify $ Add (Var "a") (Add (Var "b") (Var "c"))
563-
assertEqualM "assoc rules" simp $ Add (Add (Var "a") (Var "b")) (Var "c")
562+
let simp = Expr.simplify $ Add (Add (Var "c") (Var "a")) (Var "b")
563+
assertEqualM "assoc rules" simp $ Add (Var "a") (Add (Var "b") (Var "c"))
564564
, test "simp-assoc-add2" $ do
565-
let simp = Expr.simplify $ Add (Lit 1) (Add (Var "b") (Var "c"))
566-
assertEqualM "assoc rules" simp $ Add (Add (Lit 1) (Var "b")) (Var "c")
565+
let simp = Expr.simplify $ Add (Add (Lit 1) (Var "c")) (Var "b")
566+
assertEqualM "assoc rules" simp $ Add (Lit 1) (Add (Var "b") (Var "c"))
567567
, test "simp-assoc-add3" $ do
568568
let simp = Expr.simplify $ Add (Lit 1) (Add (Lit 2) (Var "c"))
569569
assertEqualM "assoc rules" simp $ Add (Lit 3) (Var "c")
@@ -578,16 +578,22 @@ tests = testGroup "hevm"
578578
assertEqualM "assoc rules" simp $ Lit 10
579579
, test "simp-assoc-add-7" $ do
580580
let simp = Expr.simplify $ Add (Var "a") (Add (Var "b") (Lit 2))
581-
assertEqualM "assoc rules" simp $ Add (Add (Lit 2) (Var "a")) (Var "b")
581+
assertEqualM "assoc rules" simp $ Add (Lit 2) (Add (Var "a") (Var "b"))
582582
, test "simp-assoc-add8" $ do
583583
let simp = Expr.simplify $ Add (Add (Var "a") (Add (Lit 0x2) (Var "b"))) (Add (Var "c") (Add (Lit 0x2) (Var "d")))
584-
assertEqualM "assoc rules" simp $ Add (Add (Add (Add (Lit 0x4) (Var "a")) (Var "b")) (Var "c")) (Var "d")
584+
assertEqualM "assoc rules" simp $ Add (Lit 4) (Add (Var "a") (Add (Var "b") (Add (Var "c") (Var "d"))))
585585
, test "simp-assoc-mul1" $ do
586-
let simp = Expr.simplify $ Mul (Var "a") (Mul (Var "b") (Var "c"))
587-
assertEqualM "assoc rules" simp $ Mul (Mul (Var "a") (Var "b")) (Var "c")
586+
let simp = Expr.simplify $ Mul (Mul (Var "b") (Var "a")) (Var "c")
587+
assertEqualM "assoc rules" simp $ Mul (Var "a") (Mul (Var "b") (Var "c"))
588588
, test "simp-assoc-mul2" $ do
589589
let simp = Expr.simplify $ Mul (Lit 2) (Mul (Var "a") (Lit 3))
590590
assertEqualM "assoc rules" simp $ Mul (Lit 6) (Var "a")
591+
, test "simp-assoc-xor1" $ do
592+
let simp = Expr.simplify $ Xor (Lit 2) (Xor (Var "a") (Lit 3))
593+
assertEqualM "assoc rules" simp $ Xor (Lit 1) (Var "a")
594+
, test "simp-assoc-xor2" $ do
595+
let simp = Expr.simplify $ Xor (Lit 2) (Xor (Var "b") (Xor (Var "a") (Lit 3)))
596+
assertEqualM "assoc rules" simp $ Xor (Lit 1) (Xor (Var "a") (Var "b"))
591597
, test "simp-zero-write-extend-buffer-len" $ do
592598
let
593599
expr = BufLength $ CopySlice (Lit 0) (Lit 0x10) (Lit 0) (AbstractBuf "buffer") (ConcreteBuf "bimm")
@@ -1508,7 +1514,10 @@ tests = testGroup "hevm"
15081514
|]
15091515
let sig = Just (Sig "fun(uint256,uint256)" [AbiUIntType 256, AbiUIntType 256])
15101516
(_, k) <- withDefaultSolver $ \s -> checkAssert s defaultPanicCodes c sig [] defaultVeriOpts
1511-
putStrLnM $ "Ret: " <> (show k)
1517+
let numErrs = sum $ map (fromEnum . isError) k
1518+
assertEqualM "number of errors (i.e. copySlice issues) is 1" 1 numErrs
1519+
let errStrings = mapMaybe EVM.SymExec.getError k
1520+
assertEqualM "All errors are from copyslice" True $ all ("CopySlice" `List.isInfixOf`) errStrings
15121521
,
15131522
test "symbolic-copyslice" $ do
15141523
Just c <- solcRuntime "MyContract"
@@ -4691,11 +4700,11 @@ tests = testGroup "hevm"
46914700
putStrLnM "------------- END -----------------"
46924701
Just aPrgm <- liftIO $ yul "" $ T.pack $ unlines filteredASym
46934702
Just bPrgm <- liftIO $ yul "" $ T.pack $ unlines filteredBSym
4694-
procs <- liftIO $ getNumProcessors
4695-
withSolvers CVC5 (unsafeInto procs) 1 (Just 100) $ \s -> do
4703+
procs <- liftIO getNumProcessors
4704+
withSolvers Bitwuzla (unsafeInto procs) 1 (Just 100) $ \s -> do
46964705
calldata <- mkCalldata Nothing []
46974706
(res, _) <- equivalenceCheck s aPrgm bPrgm opts calldata False
4698-
end <- liftIO $ getCurrentTime
4707+
end <- liftIO getCurrentTime
46994708
case any isCex res of
47004709
False -> liftIO $ do
47014710
print $ "OK. Took " <> (show $ diffUTCTime end start) <> " seconds"

0 commit comments

Comments
 (0)