Skip to content

SSA-CFG: Fix detection of equivalent instructions in Outliner#16768

Draft
blishko wants to merge 1 commit into
developfrom
ssa-cfg-fix-outliner
Draft

SSA-CFG: Fix detection of equivalent instructions in Outliner#16768
blishko wants to merge 1 commit into
developfrom
ssa-cfg-fix-outliner

Conversation

@blishko

@blishko blishko commented May 22, 2026

Copy link
Copy Markdown
Contributor

In the helper we use to check if arguments of two instructions are equivalent, we would say that two instructions are equivalent if they have the same index.
This is, however, not correct, as the two instructions can come from two different CFGs. Thus, same indices does not mean they refer to the same instruction.

We fixed the check instead to

  • Check if we have proven equivalence before; or
  • The two instructions refer to the same literal

In the helper we use to check if arguments of two instructions are
equivalent, we would say that two instructions are equivalent if they
have the same index.
This is, however, not correct, as the two instructions can come from two
different CFGs. Thus, same indices does not mean they refer to the same
instruction.

We fixed the check instead to
- Check if we have proven equivalence before; or
- The two instructions refer to the same literal
@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown

This pull request is stale because it has been open for 14 days with no activity.
It will be closed in 7 days unless the stale label is removed.

@github-actions github-actions Bot added the stale The issue/PR was marked as stale because it has been open for too long. label Jun 6, 2026
@blishko blishko added experimental and removed stale The issue/PR was marked as stale because it has been open for too long. labels Jun 6, 2026

@clonker clonker left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your fix works but the component is still a bit broken. We should generally define tests for optimizer passes.

Comment on lines 194 to 195
if (inst1.opcode == InstOpcode::BuiltinCall && cfg1.builtinPayload(iid1).builtin != cfg2.builtinPayload(iid2).builtin)
return false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Different issue here, this does not treat literal/immediate arguments of the builtins properly. Eg two verbatim blocks with different bytecode would be deduplicated. We should add something like

if (inst1.opcode == InstOpcode::BuiltinCall && !sameLiteralArguments(cfg1.builtinPayload(iid1).literalArguments, cfg2.builtinPayload(iid2).literalArguments))
	return false;

underneath the builtin payload check. Or have a helper function that compares builtins and use that for both: compare builtin handle and, for literal args, Literal::kind and Literal::value.

}
case InstOpcode::Projection:
{
instMapping.insert({iid1.value, iid2.value});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This relies on the implicit invariant that the nth projection on cfg1 pairs with the nth projection on cfg2. We could harden it a bit:

Suggested change
yulAssert(cfg1.projectionIndex(iid1) == cfg2.projectionIndex(iid2));
instMapping.insert({iid1.value, iid2.value});

@blishko

blishko commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

It seems to me this needs some more thought.
I suggest we disable the outliner for now and get back to it once we get more important things out of the way.

@blishko blishko marked this pull request as draft June 8, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants