UnusedStoreEliminator may incorrectly remove `mstore`s if its input is not in pseudo-SSA form
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 21
Description
## Description
When custom optimization sequence lacks `a` step (`SSATransfor`) before `S`, the later removes `mstore` which should not be removed. It changes expected behaviour.
## Environment
- Compiler version: 0.8.33
- Compilation pipeline (legacy, IR, EOF): IR
- Target EVM version (as per compiler settings):
- Framework/IDE (e.g. Foundry, Hardhat, Remix):
- EVM execution environment / backend / blockchain client:
- Operating system:
## Steps to Reproduce
```solidity
contract UnusedStoreEliminatorNoSSA_SolidityPoC {
function run() external pure returns (bytes32) {
assembly {
let x := calldataload(4)
let a := add(x, 32)
x := add(x, 32)
let b := x
let outLen := 32
mstore(a, 0xAA)
return(b, outLen)
}
}
}
```
Command:
`./build/solc/solc --via-ir --optimize --yul-optimizations "S:" --ir-optimized test.sol`
Output:
```
....
/// @ast-id 7 @src 0:54:344 "function run() external pure returns (bytes32) {..."
function fun_run() -> var
{
/// @src 0:92:99 "bytes32"
let zero_bytes32 := zero_value_for_split_bytes32()
var := zero_bytes32
/// @src 0:111:338 "assembly {..."
let usr$x := calldataload(4)
let usr$a := add(usr$x, 32)
usr$x := add(usr$x, 32)
let usr$b := usr$x
let usr$outLen := 32
return(usr$b, usr$outLen)
}
.....
```
On the other hand, when we run it with `aS:` sequence:
Command:
`./build/solc/solc --via-ir --optimize --yul-optimizations "aS:" --ir-optimized test.sol`
Output:
```
....
/// @ast-id 7 @src 0:54:344 "function run() external pure returns (bytes32) {..."
function fun_run() -> var
{
/// @src 0:92:99 "bytes32"
let zero_bytes32 := zero_value_for_split_bytes32()
let var_ := zero_bytes32
var := var_
/// @src 0:111:338 "assembly {..."
let usr$x := calldataload(4)
let usr$x_1 := usr$x
let usr$a := add(usr$x, 32)
let usr$x_2 := add(usr$x, 32)
usr$x_1 := usr$x_2
let usr$b := usr$x_2
let usr$outLen := 32
mstore(usr$a, 0xAA) // IMPORTANT `mstore` removed when `a` step is not done before `S`
return(usr$b, usr$outLen)
}
.....
```
Contributor guide
Assessment
This issue has not been assessed yet.