about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/expression/simplifications_common.py9
-rw-r--r--test/expression/simplifications.py9
2 files changed, 16 insertions, 2 deletions
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index 6eb5e804..6840a0ac 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -212,10 +212,15 @@ def simp_cst_propagation(e_s, expr):
         args0 = args[0].args[0]
         args = [args0, args1]
 
-    # A >> X >> Y  =>  A >> (X+Y)
+    # A >> X >> Y  =>  A >> (X+Y) if X + Y does not overflow
+    # To be sure, only consider the simplification when X.msb and Y.msb are 0
     if (op_name in ['<<', '>>'] and
         args[0].is_op(op_name)):
-        args = [args[0].args[0], args[0].args[1] + args[1]]
+        X = args[0].args[1]
+        Y = args[1]
+        if (e_s(X.msb()) == ExprInt(0, 1) and
+            e_s(Y.msb()) == ExprInt(0, 1)):
+            args = [args[0].args[0], X + Y]
 
     # ((A & A.mask)
     if op_name == "&" and args[-1] == expr.mask:
diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py
index 8799191b..5a223f7c 100644
--- a/test/expression/simplifications.py
+++ b/test/expression/simplifications.py
@@ -77,6 +77,9 @@ d = ExprId('d', 32)
 e = ExprId('e', 32)
 f = ExprId('f', size=64)
 
+b_msb_null = b[:31].zeroExtend(32)
+c_msb_null = c[:31].zeroExtend(32)
+
 m = ExprMem(a)
 s = a[:8]
 
@@ -377,6 +380,12 @@ to_test = [(ExprInt(1, 32) - ExprInt(1, 32), ExprInt(0, 32)),
     ((ExprMem(ExprCond(a, b, c)),ExprCond(a, ExprMem(b), ExprMem(c)))),
     (ExprCond(a, i0, i1) + ExprCond(a, i0, i1), ExprCond(a, i0, i2)),
 
+    (a << b << c, a << b << c), # Left unmodified
+    (a << b_msb_null << c_msb_null,
+     a << (b_msb_null + c_msb_null)),
+    (a >> b >> c, a >> b >> c), # Left unmodified
+    (a >> b_msb_null >> c_msb_null,
+     a >> (b_msb_null + c_msb_null)),
 ]
 
 for e_input, e_check in to_test: