Skip to content

bugc: for-loops revert at optimization level 3 #292

Description

@gnidan

A for-loop that computes the correct result at optimization levels 0, 1, and 2 reverts at level 3.

name Loop;

storage {
  r: uint256;
}

code {
  let s = 0;
  for (let i = 1; i <= 5; i = i + 1) {
    s = s + i;
  }
  r = s;
}

This stores 15 at levels 0 through 2 and reverts at level 3.

The failure is specific to loops at level 3. Recursion (tail, mutual, tree), if/else diamonds, and multi-predecessor return blocks all execute correctly at every level; only loops regress, and only at 3. The revert, rather than a wrong value, points at a malformed stack.

Level 3 is where the loop is both TCO'd into a back-edge and then run through block-merging and inlining. Levels 0 through 2 lower the same loop correctly, so the defect is in how those passes reshape the loop's CFG. Working hypothesis: block-merging across the TCO loop header and back-edge relocates or drops the phi copies or the stack canonicalization, leaving the runtime stack inconsistent on the back-edge. Pinning the pass needs a level-3 step trace.

This is pre-existing and independent of the canonical stack-discipline change in #283 (verified: the revert reproduces without it), and it has a distinct root from #275. Found while writing the behavioral tests for #283; this is the remaining piece of #275's third checkpoint.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions