| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously the fuzzer constructed a new random valid wasm file from
scratch. The new --initial-fuzz=FILENAME option makes it start from
an existing wasm file, and then add random contents on top of that. It
also randomly modifies the existing contents, for example tweaking
a Const, replacing some nodes with other things of the same type, etc.
It also has a chance to replace a drop with a logging (as some of our
tests just drop a result, and we match the optimized output's wasm
instead of the result; by logging, the fuzzer can check things).
The goal is to find bugs by using existing hand-written testcases as
a basis. This PR uses the test suite's testcases as initial fuzz contents.
This can find issues as they often check for corner cases - they are
designed to be "interesting", which random data may be less likely
to find.
This has found several bugs already, see recent fuzz fixes. I mentioned
the first few on Twitter but past 4 I stopped counting...
https://twitter.com/kripken/status/1314323318036602880
This required various changes to the fuzzer's generation to account
for the fact that there can be existing functions and so forth before
it starts to run, so it needs to avoid collisions and so forth.
|
|
|
|
|
|
| |
As proposed in https://github.com/WebAssembly/simd/pull/379. Since this
instruction is still being evaluated for inclusion in the SIMD proposal, this PR
does not add support for it to the C/JS APIs or to the fuzzer. This PR also
performs a drive-by fix for unrelated instructions in c-api-kitchen-sink.c
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The DCE pass is one of the oldest in binaryen, and had quite a lot of
cruft from the changes in unreachability and other stuff in wasm and
binaryen's history. This PR rewrites it from scratch, making it about
1/3 the size.
I noticed this when looking for places to use code autogeneration.
The old version had annoying boilerplate, while the new one avoids
any need for it.
There may be noticeable differences, as the old pass did more than
it needed to. It overlapped with remove-unused-names for some
reason I don't remember. The new pass leaves that to the other
pass to do. I added another run of remove-unused-names to avoid
noticeable differences in optimized builds, but you can see
differences in the testcases that only run DCE by itself. (The test
differences in this PR are mostly whitespace.)
(The overlap is that if a block ended up not needed, that is, all
branches to it were removed, the old DCE would remove the block.)
This pass is about 15% faster than the old version. However, when
adding another run of remove-unused-names the difference
basically vanishes, so this isn't a speedup.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
| |
This change makes matchers in OptimizeInstructions more compact and readable by
removing the explicit `Abstract::` namespace from individual operations. In some
cases, this makes multi-line matcher expressions fit on a single line.
This change is only possible because it also adds an explicit "RMW" prefix to
each element of the `AtomicRMWOp` enumeration. Without that, their names
conflicted with the names of Abstract ops.
|
| |
|
|
|
|
|
| |
Extend ZeroRemover and optimizeAddedConstants to handle 64-bit integers as well.
Use Literal.makeFromInt64 to make this easier.
|
|
|
|
| |
This is necessary for cases where the input has an export name that
needs mangling, like a name with - (common in the spec test suite).
|
| |
|
|
|
|
|
|
|
|
| |
This avoids it printing a warning and doing nothing for them.
It also increases coverage, for checking 64-bit return values, but any such
bug would have already been found already, I think (as we ignored the
high bits), so likely the fuzzer is not emitting such things when running JS
at least.
|
| |
|
|
|
|
|
|
|
| |
These instructions are proposed in https://github.com/WebAssembly/simd/pull/350.
This PR implements them throughout Binaryen except in the C/JS APIs and in the
fuzzer, where it leaves TODOs instead. Right now these instructions are just
being implemented for prototyping so adding them to the APIs isn't critical and
they aren't generally available to be fuzzed in Wasm engines.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#3271)
log_execution can be useful to run on a fuzz testcase for debugging purposes. This
adds support to --fuzz-exec for printing out those values.
IOW, this PR allows the following debugging flow: you run
wasm-opt --log-execution
on the wasm, then run it in the fuzzer,
wasm-opt --fuzz-exec[-before]
and you get that logging printed out (showing where we enter functions, exit them,
etc.).
Also, in general --fuzz-exec ignores unknown imports (so that it can be run on more wasm
files, for at least some fuzz testing there). This also adds a warning in that case, so it
is less surprising (the behavior does not change in this PR).
|
|
|
|
|
|
|
|
| |
We checked if the type matches when deciding if two locals are equivalent,
but if the type didn't match, we forgot to reset any previously equivalent
things. So we thought something was equivalent when it wasn't, see the
reduced testcase.
Fixes #3266
|
|
|
|
| |
Move the tweak function to an outer location, and call it from mutate() with
some probability.
|
|
|
|
|
|
|
|
|
| |
And associated stack.h. The current stack.h clearly doesn't work with
the llvm back as it assumes the stack grows up, which means non of these
has been working or used in a long time.
Rather than trying to fix this unused features its probably cleaner to
just remove it for now and restore it rom git history if its someone
that anyone actually wants to use in the future.
|
| |
|
|
|
|
|
|
|
|
|
| |
Such a collision can happen if we run the pass twice, and somehow it finds
more to optimize.
To make this easy, add a general utility for getting a unique name based on
a root + a numeric suffix to avoid collisions.
Fixes the second testcase in #3225
|
|
|
|
|
| |
We may fix this eventually, but it appears to not be urgent. For now at least
show a warning so toolchains have a chance to see there is something
they should fix.
|
|
|
|
| |
usages too (#3254)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#3253)
validateGlobally means that we can't do lookups on the module. A few places
were missing that, or had it wrong. I think the reason for the wrong usages is
that we used to have types on the module, and then removed that, so more is
now validatable actually.
This uncovered a real bug, where i64-to-32 would ignore an unreachable
parameter of a call_indirect. That's bad, since if the type is i64, we need
to replace it with two parameters. To fix that, just handle unreachability
there, using the existing logic (which skips the call_indirect entirely in
this case).
|
|
|
| |
Such a reference may mean we cannot remove a function after inlining it.
|
|
|
|
|
|
|
|
|
|
| |
i32(bool(x)) != 0 ==> i32(bool(x))
i64(bool(x)) & 1 ==> i64(bool(x))
Also:
* clean up related matching rules in optimizeWithConstantOnRight
* add more explanations about isPowerOf2Float & rename to
isPowerOfTwoInvertibleFloat
|
|
|
|
| |
The use of these passes was removed on the emscripten side
in https://github.com/emscripten-core/emscripten/pull/12536.
|
|
|
|
|
|
|
|
|
| |
When set, we can assume an imported memory was not modified before us.
That lets us assume it is all zeros and so we can optimize out zeros from
memory segments.
This does not actually do anything with the flag, just adds it. This is to avoid
a rolling problem. Next emscripten can emit it without erroring, and then we
can start to use it.
|
|
|
|
|
| |
These days we always export the table, except in the
case of dynamic linking, and even then we use the name
`__indirect_function_table`.
|
|
|
|
|
|
|
| |
This flag disables the features of `wasm-emscripten-finalize`
the replace the mutable global import of `__stack_pointer`.
See the corresponding emscripten change that depends on this
one: https://github.com/emscripten-core/emscripten/pull/12536
|
|
|
|
|
|
|
| |
Internalizing of the stack pointer is only needed in legacy
PIC mode, since in the new PIC mode we support mutable globals.
Also the additional ASSIGN_GOT_ENTRIES function only exists
in support of the legacy mode.
|
|
|
|
| |
Fixes: #3226
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I believe originally wasm did not allow overlapping segments, that is, where
one memory segment tramples the data from a previous one. But then the
spec changed its mind and we allowed it. Binaryen seems to have assumed
the original case, and not checked for trampling.
If there is a chance of trampling, we cannot optimize out zeros - the zero
may have an effect if it tramples data from a previous segment. This does
not occur in practice in LLVM output, which is why this wasn't a problem
so far, I think.
An existing testcase hit this issue, so I split it up.
|
|
|
|
| |
We can't validate or print out the wasm in that case, but at least
logging the names as they run can help debug some situations.
|
|
|
|
|
|
|
|
|
| |
The s-parser was assigning numbers names per-type where as
the binaryn reader was using the global import count as the
number to append.
This change switches to use per-element count which I think
it preferable as it increases the stability of the auto-generated
names. e.g. memory is now always named `$mimport0`.
|
|
|
|
|
|
|
|
|
|
|
| |
This PR fixes a bug in which the segment index of a memory.init instruction was
incorrect in some circumstances. Specifically, the first segment index used in
output memory.init instructions was always the index of the first segment
created from splitting up the corresponding input segment. This was incorrect
when the input memory.init had an offset that caused it to skip over that first
emitted segment so that the first output memory.init should have referred to a
subsequent output segment.
Fixes #3225.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
| |
wasm-ld now does this better than binaryen and does
it by default when linking and executable and optionally
with `-Bsymbolic` when linking a shared library.
See https://reviews.llvm.org/D89152
|
|
|
|
| |
This pass will convert a module with 64-bit loads and stores accessing a 64-bit memory to a regular 32-bit one.
Pointers remain 64-bit but are truncated just before use.
|
|
|
| |
According to the WebAssembly spec, Wasm is an abbreviation, not an acronym.
|
|
|
|
|
|
|
|
| |
`(uint32_t)x / C` --> `x >= C`, where `C > 2^31`
`(uint32_t)x / -1` --> `x != -1`
and for `shrinkLevel == 0`:
`(uint64_t)x / C` --> `uint64_t(x >= C)`, where `C > 2^63`
`(uint64_t)x / -1` --> `x != -1`
|
|
|
|
|
| |
growMemory() now also returns whether we succeeded.
Without this it could eventually start to swap etc., which is annoying.
|
|
|
|
|
|
|
|
|
| |
That global is for internal use. If we emit random sets to it, we could prevent
it from doing its job of preventing an infinite loop (normally it decreases each
time a loop runs or we recurse, until we reach 0 - if we set it to a nonzero
value in that code, that would be bad).
Random gets are less of a problem, but may be confusing when debugging
a testcase.
|
|
|
| |
Mentioning if it's a memory or a table segment is convenient.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Now that we are renaming invoke wrappers and `emscripten_longjmp_jmpbuf`
in the wasm backend, this deletes all related renaming routines and
relevant tests. Depends on #3192.
Addresses: #3043 and #3081
Companions:
https://reviews.llvm.org/D88697
emscripten-core/emscripten#12399
|
|
|
|
|
|
| |
(#3220)
We turn a br_table with a single target into a br, but we reverse the order of the
condition and the value when doing so, which we forgot to take into account.
|
|
|
| |
When there are two versions of a function, one handling tuples and the other handling non-tuple values, the previous naming convention was to have "Single" in the name of the non-tuple handling function. This PR simplifies the convention and shortens function names by making the names plural for the tuple-handling version and singular for the non-tuple-handling version.
|
|
|
|
|
|
|
| |
fixLabels() in the fuzzer looks for invalid labels and fixes them up,
after doing some random changes to existing wasm (which checks
for types while doing so, but it may invalidate labels if we remove the
target of a branch, for example). This adds trivial support for
BrOnExn and Try there.
|