Skip to content

bugc: jump optimization drops an inlined function's invoke or return #382

Open

Description

@gnidan

At -O 2, an inlined function can lose its invoke or its return marker when jump optimization folds the empty block that carries it.

The inliner puts the invoke on the body's first instruction, and the return on its last one. When the block it reaches has no instruction, the marker rides that block's terminator. JumpOptimizationStep then redirects jumps (and branches) around empty, phi-less blocks that end in a jump, and removes them once nothing reaches them, with the marker on their terminator.

Invoke lost (the body's entry block is empty and jumps to a loop header):

name LoopFirst;
define {
  function f(n: uint256) -> uint256 {
    for (let i = n; i > 5; i = i - 1) {
      r = r + 1;
    }
    return n + 1;
  };
}
storage { [0] r: uint256; [1] s: uint256; }
create { s = 9; }
code { let v = s; r = f(v) + v; }

The runtime program has one return for f and no invoke.

Return lost (the loop's exit block is empty, and the loop header's branch now skips it):

name LoopLast;
define {
  function f(n: uint256) -> uint256 {
    let acc = 0;
    for (let i = 0; i < n; i = i + 1) {
      acc = acc + i;
    }
    return acc;
  };
}
storage { [0] r: uint256; [1] s: uint256; }
create { s = 3; }
code { r = f(s); }

The runtime program has one invoke for f and no return.

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