Skip to content

[BranchHints] Fuzz branch hints #7704

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

kripken
Copy link
Member

@kripken kripken commented Jul 9, 2025

Add two helper passes, one to delete specific branch hints by their
instrumentation ID (as added by InstrumentBranchHints), and one to
remove all instrumentation. The new fuzzer then

  • Adds random branch hints
  • Instruments them and runs that to see the output
  • Delete all incorrect hints
  • Remove all instrumentation, leaving a wasm with correct hints only
  • Optimize
  • Add new instrumentation and run that to see the output

The idea is that once we have a wasm with only correct hints, the
optimizer is allowed to remove some (e.g. in DCE), but it should
never emit an invalid branch hint (e.g. by forgetting to flip a hint
when it flips an if).

@kripken kripken requested a review from tlively July 9, 2025 16:04
@kripken
Copy link
Member Author

kripken commented Jul 9, 2025

(This will wait to land until all optimizations are fixed up.)

Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

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

Nice! I'm glad this works.

// A map of expressions to their parents, so we can identify the pattern.
std::unique_ptr<Parents> parents;

Sub* getSub() { return (Sub*)this; }
Copy link
Member

Choose a reason for hiding this comment

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

Our usual pattern (although we're not entirely consistent) is to return a reference and call this self.

Suggested change
Sub* getSub() { return (Sub*)this; }
Sub& self() { return *static_cast<Sub*>(this); }

if (!get) {
return {};
}
auto& sets = getSub()->localGraph->getSets(get);
Copy link
Member

Choose a reason for hiding this comment

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

Can we skip the getSub() (or self()) here, given that localGraph is a member of the current class?

auto id = info->call->operands[0]->template cast<Const>()->value.geti32();
if (idsToDelete.count(id)) {
// Remove the branch hint.
getFunction()->codeAnnotations[curr].branchLikely = {};
Copy link
Member

Choose a reason for hiding this comment

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

Is it worth deleting the expression out of the map if there are no annotations remaining? Perhaps we could have some helper functions for managing that.

Comment on lines +357 to +359
// Replace the instrumented condition with the original one (swap so that
// the IR remains valid; the other use of the local will not matter, as we
// remove the logging calls).
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure I understand the comment here. What IR is remaining valid because of the swap? What would go wrong if we did a replaceCurrent(info->originalCondition)?

Edit: Oh, is it because the logging calls might not be nested under curr?

# where the three integers are: ID, predicted, actual.
all_ids = set()
bad_ids = set()
LEI_LOG_BRANCH = '[LoggingExternalInterface log-branch'
Copy link
Member

Choose a reason for hiding this comment

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

I think this would be a clearer name. I took a break in the middle of reviewing and when I came back and read the code below, I had no idea what LEI stood for :)

Suggested change
LEI_LOG_BRANCH = '[LoggingExternalInterface log-branch'
LOG_BRANCH_PREFIX = '[LoggingExternalInterface log-branch'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants