Skip to content

Commit

Permalink
BinaryOp: Fix a bug that would lead to one of the operands becoming N…
Browse files Browse the repository at this point in the history
…one after replacing. (#242)

* BinaryOp: Fix a bug that would lead to one of the operands becoming None after replacing.
  • Loading branch information
ltfish authored Sep 26, 2024
1 parent dfa3129 commit 058d9ce
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 24 deletions.
45 changes: 32 additions & 13 deletions ailment/converter_vex.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,13 @@ def Binop(expr, manager):
operands[1] = Const(operands[1].idx, None, (1 << op1_bits) - op1_val, op1_bits)

signed = False
vector_count = None
vector_size = None
if op._vector_count is not None and op._vector_size is not None:
# SIMD conversions
op_name += "V" # vectorized
vector_count = op._vector_count
vector_size = op._vector_size
elif op_name in {"CmpLE", "CmpLT", "CmpGE", "CmpGT", "Div", "DivMod", "Mod", "Mul", "Mull"}:
if op.is_signed:
signed = True
Expand Down Expand Up @@ -311,6 +315,8 @@ def Binop(expr, manager):
vex_block_addr=manager.block_addr,
vex_stmt_idx=manager.vex_stmt_idx,
bits=bits,
vector_count=vector_count,
vector_size=vector_size,
**extra_kwargs,
)

Expand Down Expand Up @@ -553,11 +559,23 @@ def CAS(idx, stmt: pyvex.IRStmt.CAS, manager):
}[ty]
dataHi = VEXExprConverter.convert(stmt.dataHi, manager)
dataLo = VEXExprConverter.convert(stmt.dataLo, manager)
data = BinaryOp(idx, "Concat", (dataHi, dataLo), False)
data = BinaryOp(manager.next_atom(), "Concat", (dataHi, dataLo), False)

expdHi = Convert(idx, widen_from_bits, widen_to_bits, False, VEXExprConverter.convert(stmt.dataHi, manager))
expdLo = Convert(idx, widen_from_bits, widen_to_bits, False, VEXExprConverter.convert(stmt.dataLo, manager))
expd = BinaryOp(idx, "Concat", (expdHi, expdLo), False)
expdHi = Convert(
manager.next_atom(),
widen_from_bits,
widen_to_bits,
False,
VEXExprConverter.convert(stmt.dataHi, manager),
)
expdLo = Convert(
manager.next_atom(),
widen_from_bits,
widen_to_bits,
False,
VEXExprConverter.convert(stmt.dataLo, manager),
)
expd = BinaryOp(manager.next_atom(), "Concat", (expdHi, expdLo), False)
else:
narrow_to_bits = widen_to_bits = None
data = VEXExprConverter.convert(stmt.dataLo, manager)
Expand All @@ -579,9 +597,9 @@ def CAS(idx, stmt: pyvex.IRStmt.CAS, manager):
size,
stmt.endness,
)
cmp = BinaryOp(idx, "CmpEQ", (val, expd), False)
cmp = BinaryOp(manager.next_atom(), "CmpEQ", (val, expd), False)
store = Store(
idx,
manager.next_atom(),
addr.copy(),
data,
size,
Expand All @@ -594,21 +612,22 @@ def CAS(idx, stmt: pyvex.IRStmt.CAS, manager):
stmts.append(store)

if double:
val_shifted = BinaryOp(idx, "Shr", (val, narrow_to_bits), False)
valHi = Convert(idx, widen_to_bits, narrow_to_bits, False, val_shifted)
valLo = Convert(idx, widen_to_bits, narrow_to_bits, False, val)
narrow_to_bits_con = Const(manager.next_atom(), None, narrow_to_bits, 8)
val_shifted = BinaryOp(manager.next_atom(), "Shr", [val, narrow_to_bits_con], False)
valHi = Convert(manager.next_atom(), widen_to_bits, narrow_to_bits, False, val_shifted)
valLo = Convert(manager.next_atom(), widen_to_bits, narrow_to_bits, False, val)

wrtmp_0 = Assignment(
idx,
Tmp(idx, None, stmt.oldLo, narrow_to_bits),
manager.next_atom(),
Tmp(manager.next_atom(), None, stmt.oldLo, narrow_to_bits),
valLo,
ins_addr=manager.ins_addr,
vex_block_addr=manager.block_addr,
vex_stmt_idx=manager.vex_stmt_idx,
)
wrtmp_1 = Assignment(
idx,
Tmp(idx, None, stmt.oldHi, narrow_to_bits),
Tmp(manager.next_atom(), None, stmt.oldHi, narrow_to_bits),
valHi,
ins_addr=manager.ins_addr,
vex_block_addr=manager.block_addr,
Expand All @@ -619,7 +638,7 @@ def CAS(idx, stmt: pyvex.IRStmt.CAS, manager):
else:
wrtmp = Assignment(
idx,
Tmp(idx, None, stmt.oldLo, size),
Tmp(manager.next_atom(), None, stmt.oldLo, size),
val,
ins_addr=manager.ins_addr,
vex_block_addr=manager.block_addr,
Expand Down
25 changes: 14 additions & 11 deletions ailment/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,8 @@ class BinaryOp(Op):
"rounding_mode",
"from_bits", # for divmod
"to_bits", # for divmod
"vector_count",
"vector_size",
)

OPSTR_MAP = {
Expand Down Expand Up @@ -791,10 +793,12 @@ def __init__(
variable=None,
variable_offset=None,
bits=None,
floating_point=False,
rounding_mode=None,
from_bits=None,
to_bits=None,
floating_point: bool = False,
rounding_mode: str | None = None,
from_bits: int | None = None,
to_bits: int | None = None,
vector_count: int | None = None,
vector_size: int | None = None,
**kwargs,
):
depth = (
Expand Down Expand Up @@ -841,7 +845,9 @@ def __init__(
self.variable = variable
self.variable_offset = variable_offset
self.floating_point = floating_point
self.rounding_mode = rounding_mode
self.rounding_mode: str | None = rounding_mode
self.vector_count = vector_count
self.vector_size = vector_size

self.from_bits = from_bits
self.to_bits = to_bits
Expand Down Expand Up @@ -924,24 +930,21 @@ def replace(self, old_expr, new_expr):
else:
r1, replaced_operand_1 = False, None

r2, replaced_rm = False, None
if self.rounding_mode is not None:
if self.rounding_mode == old_expr:
r2 = True
replaced_rm = new_expr
elif isinstance(self.rounding_mode, Expression):
r2, replaced_rm = self.rounding_mode.replace(old_expr, new_expr)
else:
r2, replaced_rm = False, None

if r0 or r1:
return True, BinaryOp(
self.idx,
self.op,
[replaced_operand_0, replaced_operand_1],
[replaced_operand_0 if r0 else self.operands[0], replaced_operand_1 if r1 else self.operands[1]],
self.signed,
bits=self.bits,
floating_point=self.floating_point,
rounding_mode=self.rounding_mode,
rounding_mode=replaced_rm if r2 else self.rounding_mode,
from_bits=self.from_bits,
to_bits=self.to_bits,
**self.tags,
Expand Down

0 comments on commit 058d9ce

Please sign in to comment.