@@ -15,18 +15,31 @@ var trace = false
15
15
class SimpExpr (simplifier : Expr => (Expr , Boolean )) extends CILVisitor {
16
16
var changedAnything = false
17
17
var count = 0
18
- override def vexpr (e : Expr ) =
19
- val (ne, changed) = simplifier(e)
18
+
19
+ def simplify (e : Expr ) = {
20
+ val (n, changed) = simplifier(e)
21
+
20
22
changedAnything = changedAnything || changed
23
+
24
+ if (changed) logSimp(e, n)
25
+ (n, changed)
26
+ }
27
+
28
+ override def vexpr (e : Expr ) = {
29
+ val e1 = e
30
+ val cbefore = changedAnything
31
+ val (ne, changed) = simplify(e)
21
32
ChangeDoChildrenPost (
22
33
ne,
23
- (e : Expr ) => {
24
- val one = e
25
- val (ne, c) = simplifier(e)
26
- changedAnything = changedAnything || c
27
- ne
34
+ (oe : Expr ) => {
35
+ val (ne2, c) = simplify(oe)
36
+ if (! cbefore && changedAnything && (oe == e1)) {
37
+ throw Exception (s " Intermediate changes but $e1 -> $oe -> $ne2" )
38
+ }
39
+ ne2
28
40
}
29
41
)
42
+ }
30
43
31
44
def apply (e : Expr ) = {
32
45
val ns = SimpExpr (simplifier)
@@ -38,18 +51,17 @@ class SimpExpr(simplifier: Expr => (Expr, Boolean)) extends CILVisitor {
38
51
def sequenceSimp (a : Expr => (Expr , Boolean ), b : Expr => (Expr , Boolean ))(e : Expr ): (Expr , Boolean ) = {
39
52
val (ne1, changed1) = a(e)
40
53
if (ne1 == e && changed1) {
41
- Logger .error( s " ${SimplifyValidation .debugTrace.last}" )
42
- throw Exception (s " No simp $e \n -> $ne1" )
54
+ val change = s " ${SimplifyValidation .debugTrace.last}"
55
+ throw Exception (s " Simplifier $change returned 'changed' for identical expression $e \n -> $ne1" )
43
56
}
44
57
val (ne2, changed2) = b(ne1)
45
58
if (ne2 == ne1 && changed2) {
46
- // throw Exception("No simp")
47
- Logger .error(s " ${SimplifyValidation .debugTrace.last}" )
48
- throw Exception (s " No simp $ne1 \n -> $ne2" )
59
+ val change = SimplifyValidation .debugTrace.takeRight(5 ).map(" " + _ ).mkString(" \n " )
60
+ throw Exception (s " $change\n Simplifier returned 'changed' for identical expression $ne1 \n -> $ne2" )
49
61
}
50
62
if (ne2 == e && (changed1 || changed2)) {
51
- Logger .error( s " ${ SimplifyValidation .debugTrace.last} " )
52
- throw Exception (s " No simp $e \n -> $ne1\n -> $ne2" )
63
+ val change = SimplifyValidation .debugTrace.takeRight( 5 ).map( " " + _ ).mkString( " \n " )
64
+ throw Exception (s " $change \n Simplifier returned 'changed' for identical expression $e \n -> $ne1\n -> $ne2" )
53
65
}
54
66
(ne2, changed1 || changed2)
55
67
}
@@ -234,15 +246,15 @@ def simplifyCmpInequalities(e: Expr): (Expr, Boolean) = {
234
246
case _ => false
235
247
}
236
248
} =>
237
- BinaryExpr (BVADD , r, l)
249
+ logSimp(e, BinaryExpr (BVADD , r, l) )
238
250
239
251
case BinaryExpr (BoolAND , l @ BinaryExpr (BVEQ , _, _), r @ BinaryExpr (relop, _, _))
240
252
if ineqToStrict.contains(relop) || strictIneq.contains(relop) => {
241
- BinaryExpr (BoolAND , r, l)
253
+ logSimp(e, BinaryExpr (BoolAND , r, l) )
242
254
}
243
255
case BinaryExpr (BoolAND , l @ UnaryExpr (BoolNOT , BinaryExpr (BVEQ , _, _)), r @ BinaryExpr (relop, _, _))
244
256
if ineqToStrict.contains(relop) || strictIneq.contains(relop) => {
245
- BinaryExpr (BoolAND , r, l)
257
+ logSimp(e, BinaryExpr (BoolAND , r, l) )
246
258
}
247
259
248
260
case BinaryExpr (BVCOMP , l, r) => {
@@ -636,7 +648,7 @@ def simplifyCmpInequalities(e: Expr): (Expr, Boolean) = {
636
648
UnaryExpr (BoolNOT , BinaryExpr (BVEQ , lhs2, rhs2 : BitVecLiteral ))
637
649
)
638
650
if (ineqToStrict.contains(op) || strictIneq
639
- .contains(op)) && simplifyCond(BinaryExpr (ineqToStrict.get(op).getOrElse(op), rhs, rhs2)) == TrueLiteral
651
+ .contains(op)) && rhs.getType == rhs2.getType && simplifyCond(BinaryExpr (ineqToStrict.get(op).getOrElse(op), rhs, rhs2)) == TrueLiteral
640
652
&& lhs == lhs2 => {
641
653
logSimp(e, l)
642
654
}
@@ -847,27 +859,27 @@ def cleanupExtends(e: Expr): (Expr, Boolean) = {
847
859
var changedAnything = true
848
860
849
861
val res = e match {
850
- case Extract (ed, 0 , body) if size(body).get == ed => ( body)
851
- case ZeroExtend (0 , body) => ( body)
852
- case SignExtend (0 , body) => ( body)
853
- case BinaryExpr (BVADD , body, BitVecLiteral (0 , _)) => ( body)
854
- case BinaryExpr (BVMUL , body, BitVecLiteral (1 , _)) => ( body)
855
- case Repeat (1 , body) => ( body)
856
- case Extract (ed, 0 , ZeroExtend (extension, body)) if (body.getType == BitVecType (ed)) => ( body)
857
- case Extract (ed, 0 , SignExtend (extension, body)) if (body.getType == BitVecType (ed)) => ( body)
862
+ case Extract (ed, 0 , body) if size(body).get == ed => logSimp(e, body)
863
+ case ZeroExtend (0 , body) => logSimp(e, body)
864
+ case SignExtend (0 , body) => logSimp(e, body)
865
+ case BinaryExpr (BVADD , body, BitVecLiteral (0 , _)) => logSimp(e, body)
866
+ case BinaryExpr (BVMUL , body, BitVecLiteral (1 , _)) => logSimp(e, body)
867
+ case Repeat (1 , body) => logSimp(e, body)
868
+ case Extract (ed, 0 , ZeroExtend (extension, body)) if (body.getType == BitVecType (ed)) => logSimp(e, body)
869
+ case Extract (ed, 0 , SignExtend (extension, body)) if (body.getType == BitVecType (ed)) => logSimp(e, body)
858
870
case Extract (ed, 0 , ZeroExtend (exts, body)) if exts + size(body).get >= ed && ed > size(body).get =>
859
- ZeroExtend (ed - size(body).get, body)
871
+ logSimp(e, ZeroExtend (ed - size(body).get, body) )
860
872
861
873
case BinaryExpr (BVEQ , ZeroExtend (x, body), y : BitVecLiteral ) if y.value <= BigInt (2 ).pow(size(body).get) - 1 =>
862
- BinaryExpr (BVEQ , body, BitVecLiteral (y.value, size(body).get))
874
+ logSimp(e, BinaryExpr (BVEQ , body, BitVecLiteral (y.value, size(body).get) ))
863
875
864
876
case BinaryExpr (BVEQ , ZeroExtend (sz, expr), BitVecLiteral (0 , sz2)) =>
865
- BinaryExpr (BVEQ , expr, BitVecLiteral (0 , size(expr).get))
877
+ logSimp(e, BinaryExpr (BVEQ , expr, BitVecLiteral (0 , size(expr).get) ))
866
878
867
879
// compose slices
868
- case Extract (ed1, be1, Extract (ed2, be2, body)) => Extract (ed1 + be2, be1 + be2, (body))
869
- case SignExtend (sz1, SignExtend (sz2, exp)) => SignExtend (sz1 + sz2, exp)
870
- case ZeroExtend (sz1, ZeroExtend (sz2, exp)) => ZeroExtend (sz1 + sz2, exp)
880
+ case Extract (ed1, be1, Extract (ed2, be2, body)) => logSimp(e, Extract (ed1 + be2, be1 + be2, (body) ))
881
+ case SignExtend (sz1, SignExtend (sz2, exp)) => logSimp(e, SignExtend (sz1 + sz2, exp) )
882
+ case ZeroExtend (sz1, ZeroExtend (sz2, exp)) => logSimp(e, ZeroExtend (sz1 + sz2, exp) )
871
883
872
884
// make subs more readable
873
885
// case BinaryExpr(BVADD, x, b: BitVecLiteral) if eval.BitVectorEval.isNegative(b) => {
@@ -878,49 +890,49 @@ def cleanupExtends(e: Expr): (Expr, Boolean) = {
878
890
case BinaryExpr (BVCONCAT , Extract (hi1, lo1, x1), ZeroExtend (ext, Extract (hi2, 0 , x2))) if lo1 == ext + hi2 => {
879
891
val b = " 1" * (hi1 - lo1) ++ (" 0" * ext) ++ " 1" * hi2
880
892
val n = BinaryExpr (BVAND , Extract (hi1, 0 , x2), BitVecLiteral (BigInt (b, 2 ), hi1))
881
- n
893
+ logSimp(e, n)
882
894
}
883
895
884
896
// redundant extends
885
897
// extract extended zero part
886
- case Extract (ed, bg, ZeroExtend (x, expr)) if (bg > size(expr).get) => BitVecLiteral (0 , ed - bg)
898
+ case Extract (ed, bg, ZeroExtend (x, expr)) if (bg > size(expr).get) => logSimp(e, BitVecLiteral (0 , ed - bg) )
887
899
// extract below extend
888
- case Extract (ed, bg, ZeroExtend (x, expr)) if (bg < size(expr).get) && (ed < size(expr).get) => Extract (ed, bg, expr)
889
- case Extract (ed, bg, SignExtend (x, expr)) if (bg < size(expr).get) && (ed < size(expr).get) => Extract (ed, bg, expr)
900
+ case Extract (ed, bg, ZeroExtend (x, expr)) if (bg < size(expr).get) && (ed < size(expr).get) => logSimp(e, Extract (ed, bg, expr) )
901
+ case Extract (ed, bg, SignExtend (x, expr)) if (bg < size(expr).get) && (ed < size(expr).get) => logSimp(e, Extract (ed, bg, expr) )
890
902
891
- case ZeroExtend (ed, Extract (hi, 0 , e)) if size(e).get == hi + ed => BinaryExpr (BVAND , e, BinaryExpr (BVCONCAT , BitVecLiteral (0 , ed), BitVecLiteral (BigInt (2 ).pow(hi)- 1 , hi)))
903
+ case ZeroExtend (ed, Extract (hi, 0 , e)) if size(e).get == hi + ed => logSimp(e, BinaryExpr (BVAND , e, BinaryExpr (BVCONCAT , BitVecLiteral (0 , ed), BitVecLiteral (BigInt (2 ).pow(hi)- 1 , hi) )))
892
904
893
- case BinaryExpr (BVSHL , body, BitVecLiteral (n, _)) if size(body).get <= n => BitVecLiteral (0 , size(body).get)
905
+ case BinaryExpr (BVSHL , body, BitVecLiteral (n, _)) if size(body).get <= n => logSimp(e, BitVecLiteral (0 , size(body).get) )
894
906
895
907
// simplify convoluted bit test
896
908
case BinaryExpr (BVEQ , BinaryExpr (BVSHL , ZeroExtend (n1, body), BitVecLiteral (n, _)), BitVecLiteral (0 , _))
897
909
if n1 == n => {
898
- BinaryExpr (BVEQ , body, BitVecLiteral (0 , size(body).get))
910
+ logSimp(e, BinaryExpr (BVEQ , body, BitVecLiteral (0 , size(body).get) ))
899
911
}
900
912
// assume (!(bvshl8(zero_extend6_2(R3_19[8:6]), 6bv8) == 128bv8));
901
913
case BinaryExpr (
902
914
BVEQ ,
903
915
BinaryExpr (BVSHL , ZeroExtend (n1, body @ Extract (hi, lo, v)), BitVecLiteral (n, _)),
904
916
c @ BitVecLiteral (cval, _)
905
917
) if lo == n && cval >= BigInt (2 ).pow(lo + n.toInt) => {
906
- BinaryExpr (BVEQ , body, Extract (hi + n.toInt, lo + n.toInt, c))
918
+ logSimp(e, BinaryExpr (BVEQ , body, Extract (hi + n.toInt, lo + n.toInt, c) ))
907
919
}
908
920
case BinaryExpr (BVEQ , BinaryExpr (BVSHL , b, BitVecLiteral (n, _)), c @ BitVecLiteral (0 , _)) => {
909
921
// b low bits are all zero due to shift
910
- BinaryExpr (BVEQ , b, BitVecLiteral (0 , size(b).get))
922
+ logSimp(e, BinaryExpr (BVEQ , b, BitVecLiteral (0 , size(b).get) ))
911
923
}
912
924
case BinaryExpr (BVEQ , BinaryExpr (BVSHL , b, BitVecLiteral (n, _)), c @ BitVecLiteral (cval, _))
913
925
if cval != 0 && cval < BigInt (2 ).pow(n.toInt) => {
914
926
// low bits are all zero due to shift, and cval low bits are not zero
915
- FalseLiteral
927
+ logSimp(e, FalseLiteral )
916
928
}
917
929
case BinaryExpr (
918
930
BVEQ ,
919
931
BinaryExpr (BVSHL , ZeroExtend (n1, body @ Extract (hi, lo, v)), BitVecLiteral (n, _)),
920
932
c @ BitVecLiteral (cval, _)
921
933
) if lo == n && cval >= BigInt (2 ).pow(n.toInt) => {
922
934
// extract the part of cval we are testing and remove the shift on the lhs operand
923
- BinaryExpr (BVEQ , body, Extract ((hi - lo) + n.toInt, n.toInt, c))
935
+ logSimp(e, BinaryExpr (BVEQ , body, Extract ((hi - lo) + n.toInt, n.toInt, c) ))
924
936
}
925
937
926
938
// bvnot to bvneg
@@ -997,10 +1009,13 @@ def simplifyExpr(e: Expr): (Expr, Boolean) = {
997
1009
998
1010
case BinaryExpr (BVADD , ed @ SignExtend (sz, UnaryExpr (BVNOT , x)), bo @ BitVecLiteral (bv, sz2))
999
1011
if size(ed).contains(sz2) && ! BitVectorEval .isNegative(bo) =>
1000
- logSimp(e, BinaryExpr (BVADD , UnaryExpr (BVNEG , SignExtend (sz, x)), BitVecLiteral (bv - 1 , sz2)), actual = false )
1012
+ didAnything = false
1013
+ logSimp(e, BinaryExpr (BVADD , UnaryExpr (BVNEG , SignExtend (sz, x)), BitVecLiteral (bv - 1 , sz2)),
1014
+ actual = false )
1001
1015
1002
1016
case BinaryExpr (BVADD , BinaryExpr (BVADD , y, ed @ UnaryExpr (BVNOT , x)), bo @ BitVecLiteral (off, sz2))
1003
1017
if size(ed).contains(sz2) && ! (y.isInstanceOf [BitVecLiteral ]) && ! BitVectorEval .isNegative(bo) =>
1018
+ didAnything = false
1004
1019
logSimp(
1005
1020
e,
1006
1021
BinaryExpr (BVADD , BinaryExpr (BVADD , y, UnaryExpr (BVNEG , x)), BitVecLiteral (off - 1 , sz2)),
@@ -1009,6 +1024,7 @@ def simplifyExpr(e: Expr): (Expr, Boolean) = {
1009
1024
1010
1025
case BinaryExpr (BVADD , BinaryExpr (BVADD , y, ed @ SignExtend (sz, UnaryExpr (BVNOT , x))), BitVecLiteral (off, sz2))
1011
1026
if size(ed).contains(sz2) && ! (y.isInstanceOf [BitVecLiteral ]) =>
1027
+ didAnything = false
1012
1028
logSimp(
1013
1029
e,
1014
1030
BinaryExpr (BVADD , BinaryExpr (BVADD , y, UnaryExpr (BVNEG , SignExtend (sz, x))), BitVecLiteral (off - 1 , sz2)),
@@ -1019,7 +1035,7 @@ def simplifyExpr(e: Expr): (Expr, Boolean) = {
1019
1035
// case BinaryExpr(BVADD, BitVecLiteral(1, _), UnaryExpr(BVNEG, x)) => logSimp(e, UnaryExpr(BVNOT, x))
1020
1036
// case BinaryExpr(BVADD, UnaryExpr(BVNEG, x), BitVecLiteral(c, sz)) => logSimp(e, BinaryExpr(UnaryExpr(BVNOT, x), ))
1021
1037
1022
- case BinaryExpr (BVADD , UnaryExpr (BVNOT , x), BitVecLiteral (1 , _)) => UnaryExpr (BVNEG , x)
1038
+ case BinaryExpr (BVADD , UnaryExpr (BVNOT , x), BitVecLiteral (1 , _)) => logSimp(e, UnaryExpr (BVNEG , x) )
1023
1039
1024
1040
// case BinaryExpr(BVEQ, BinaryExpr(BVADD, x, y: BitVecLiteral), BitVecLiteral(0, _))
1025
1041
// if (eval.BitVectorEval.isNegative(y)) =>
0 commit comments