Inefficient code generation for empty dynamic storage array assignment in IR pipeline
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 21
Description
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:
```solidity
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.
Contributor guide
Research direction
Start by reproducing the contract in the issue with the --via-ir and legacy pipelines, then compare their storage traces and generated bytecode. Trace the dynamic storage-array copy path to confirm the extra SLOAD occurs before the empty-length check; done means the redundant read is absent while the assignment remains correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, solidity
- Domain
- blockchain, compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100