Skip to content

Commit

Permalink
Improve collapse_add_neg simplifcation rule (#355)
Browse files Browse the repository at this point in the history
* Improve collapse_add_neg.py

* fix formatting

---------

Co-authored-by: Manuel Blatt <[email protected]>
  • Loading branch information
rihi and blattm authored Oct 26, 2023
1 parent 1dc15d4 commit 39f0fa3
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from decompiler.pipeline.controlflowanalysis.expression_simplification.rules.rule import SimplificationRule
from decompiler.structures.pseudo import BinaryOperation, Expression, Operation, OperationType, UnaryOperation

Expand All @@ -8,25 +10,26 @@ class CollapseAddNeg(SimplificationRule):
- `e0 + -(e1) -> e0 - e1`
- `e0 - -(e1) -> e0 + e1`
- `-(e0) + e1 -> e1 - e0`
- `-(e0) - e1 -> -(e0 + e1)`
"""

def apply(self, operation: Operation) -> list[tuple[Expression, Expression]]:
if operation.operation not in [OperationType.plus, OperationType.minus]:
return []
if not isinstance(operation, BinaryOperation):
raise TypeError(f"Expected BinaryOperation, got {type(operation)}")
replacement: Optional[Expression] = None
match operation:
case BinaryOperation(operation=OperationType.plus, left=e0, right=UnaryOperation(operation=OperationType.negate, operand=e1)):
replacement = BinaryOperation(OperationType.minus, [e0, e1], operation.type)

case BinaryOperation(operation=OperationType.minus, left=e0, right=UnaryOperation(operation=OperationType.negate, operand=e1)):
replacement = BinaryOperation(OperationType.plus, [e0, e1], operation.type)

case BinaryOperation(operation=OperationType.plus, left=UnaryOperation(operation=OperationType.negate, operand=e0), right=e1):
replacement = BinaryOperation(OperationType.minus, [e1, e0], operation.type)

case BinaryOperation(operation=OperationType.minus, left=UnaryOperation(operation=OperationType.negate, operand=e0), right=e1):
replacement = UnaryOperation(OperationType.negate, [BinaryOperation(OperationType.plus, [e0, e1], operation.type)])

right = operation.right
if not isinstance(right, UnaryOperation) or right.operation != OperationType.negate:
if replacement is None:
return []

return [
(
operation,
BinaryOperation(
OperationType.minus if operation.operation == OperationType.plus else OperationType.plus,
[operation.left, right.operand],
operation.type,
),
)
]
return [(operation, replacement)]
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
BinaryOperation(OperationType.minus, [var_x, UnaryOperation(OperationType.negate, [var_y])]),
[BinaryOperation(OperationType.plus, [var_x, var_y])],
),
(
BinaryOperation(OperationType.plus, [UnaryOperation(OperationType.negate, [var_x]), var_y]),
[BinaryOperation(OperationType.minus, [var_y, var_x])],
),
(
BinaryOperation(OperationType.minus, [UnaryOperation(OperationType.negate, [var_x]), var_y]),
[UnaryOperation(OperationType.negate, [BinaryOperation(OperationType.plus, [var_x, var_y])])],
),
],
)
def test_collapse_add_neg(operation: Operation, result: list[Expression]):
Expand Down

0 comments on commit 39f0fa3

Please sign in to comment.