Skip to content

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
Copy link
Member Author

kripken commented Jul 22, 2025

This should now be ready for review: feedback so far addressed, and necessary fixes so this actually works, namely:

  • We decided to merge code with different branch hints, like LLVM. This is a problem for the fuzzer, and the best idea I have is to skip some passes entirely (ones that don't handle brs/ifs anyhow, so we don't need to fuzz them), and add a flag for others that we want to still fuzz.
  • Handle some corner cases with trapping in the fuzzer etc. (see comments there).

Comment on lines 1939 to 1940
# * HeapStoreOptimization moves struct.sets closer to struct.news.
'--skip-pass=heap-store-optimization',
Copy link
Member

Choose a reason for hiding this comment

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

Can you elaborate in the comment on how this affects branch hints?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done. (It's the same reason as LICM, above.)

;; CHECK-NEXT: )
;; CHECK-NEXT: (f32.const 0)
;; CHECK-NEXT: )
(func $different (param $x i32) (param $y i32) (result f32)
Copy link
Member

Choose a reason for hiding this comment

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

It might be interesting to have the reversed test as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added.

;; NO_FO-NEXT: )
;; NO_FO-NEXT: )
(func $yes-fold (param $x i32) (param $y i32)
;; Now the hints match, so we definitely fold (without the flag).
Copy link
Member

Choose a reason for hiding this comment

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

Would it be worth having the flag only disable folding when the metadata is different?

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess that would show the fuzzer finds no issues when folding identical metadata, but I'm not sure it's worth the complexity in the code to be that precise. We know that is safe to do, so it would only be checking that we wrote that condition on the flag properly.

@kripken
Copy link
Member Author

kripken commented Jul 23, 2025

After 100K iterations I was fairly confident, but the fuzzer found that optimize-instructions reorders, so we need to prevent that too, with the flag.

// As neverFold, but for reordering code. If we move a branch hint around code
// that might trap, and the trap happens later, the branch hint might start to
// execute, and it could be wrong.
bool neverReorder;
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 merge these two bools just like we merge the flag? They're always the same, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I just thought it reads a little simpler in each place in the code, "if (!neverFold) fold()" as opposed to "if (!neverFoldOrSomethingElse) fold()" - ?

Copy link
Member

Choose a reason for hiding this comment

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

Fair enough 👍

@kripken
Copy link
Member Author

kripken commented Jul 24, 2025

Fuzzer found another (trivial) source of issues in RemoveUnusedBrs (edit: just for fuzzing)

@kripken
Copy link
Member Author

kripken commented Jul 25, 2025

135K iterations of this without any issues. There might be findings in the future, but given we'll be fuzzing this at 0.1 the speed I have been locally, I don't think it will be disruptive.

@kripken kripken merged commit a03f002 into WebAssembly:main Jul 25, 2025
17 checks passed
@kripken kripken deleted the fuzz.branch.hints branch July 25, 2025 17:19
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