Skip to content

Inefficient code generation for empty dynamic storage array assignment in IR pipeline #16307

@lum7na

Description

@lum7na

When assigning a newly pushed (and thus empty) dynamic storage array to another, the IR-based pipeline (--via-ir) generates less efficient code compared to the legacy pipeline.

We discovered this inefficiency by analyzing the storage trace of the following contract:

contract C {
    int8[][] array;

    function s() public {
        array.push() = array.push();
    }
}

The trace shows that the IR pipeline generates an extra, unnecessary SLOAD operation. This operation attempts to read the first data element from the source array (the right-hand side array.push()), even though the array's length is zero.

The legacy pipeline correctly deduces that the source array is empty and avoids accessing its data area altogether, resulting in more optimized bytecode.

The IR pipeline appears to use a more generic array copy mechanism that calculates the data area's starting address (keccak256(keccak256(p))) and performs a read before checking the array's length. This leads to a redundant storage read and unnecessary gas consumption.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions