| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
| |
Division and remainder do not have an implicit trap if the
right-hand side is a constant and not one of the dangerous
values there.
Also refactor ignoreImplicitTrap handling for clarity.
|
| |
|
|
|
| |
Move the checks for most unoptimizable expression types out into visitExpression and simplify some other code.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We can still make x * -1.0 cheaper for non-fastMath mode as:
x * -1.0 -> -0.0 - x
Should at least help baseline compilers.
Also it could enable further optimizations, e.g.:
a + b * -1
a + (-0.0 - b)
(a - 0.0) - b
a - b
|
|
|
| |
We can only pack memory if we know it is zero-filled before us.
|
| |
|
|
|
|
|
| |
Selectify turns an if-else into a select where possible. Previously we abandoned
hope if any part of the if had a side effect. But it's fine for the condition to have a
side effect, so long as moving it to the end doesn't invalidate the arms.
|
|
|
|
|
|
|
| |
Make select cost more realistic - it should be as good as a jmp, as in an if.
Add missing child visiting.
Shorten repetitive cases in switches.
|
| |
|
|
|
|
|
|
|
| |
Specifically, pick a simple positive canonical NaN as the NaN output, when the output
is a NaN. This is the same as what tools like wabt do.
This fixes a testcase found by the fuzzer on #3289 but it was not that PR's fault.
|
|
|
| |
Fixed bug in memory64-lowering pass for memory.size/grow
|
|
|
|
|
| |
`C1 - (x + C2)` -> `(C1 - C2) - x`
`C1 - (x - C2)` -> `(C1 + C2) - x`
`C1 - (C2 - x)` -> `x + (C1 - C2)`
|
|
|
|
| |
Without this, we might think a function has no global uses if the only
global use of it is the start.
|
|
|
|
|
|
| |
Emscripten no longer needs this information as of
https://github.com/emscripten-core/emscripten/pull/12643.
This also removes the need to export __data_end.
|
| |
|
|
|
| |
Followup to #3276
|
| |
|
|
|
|
|
|
|
|
| |
Fixes a fuzz bug that was triggered by
https://github.com/WebAssembly/binaryen/pull/3015#issuecomment-718001620
but was actually a pre-existing bug in pow2, that that PR just happened
to uncover.
|
|
|
|
|
|
|
| |
Including saturating, rounding Q15 multiplication as proposed in
https://github.com/WebAssembly/simd/pull/365 and extending multiplications as
proposed in https://github.com/WebAssembly/simd/pull/376. Since these are just
prototypes, skips adding them to the C or JS APIs and the fuzzer, as well as
implementing them in the interpreter.
|
| |
|
|
|
| |
But only when doing so doesn't require adding a new local.
|
| |
|
|
|
| |
Split off from #3264
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously when we processed a block for example, we'd do this:
;; start is here
(block (result type)
;; end is here
.. contents ..
)
;; end delimiter is here
Not how this represents the block's start and end as the "header", and
uses an extra delimiter to mark the end.
I think this is wrong, and was an attempt to handle some offsets from
LLVM that otherwise made no sense, ones at the end of the "header".
But it turns out that this makes us completely incorrect on some things
where there is a low/high pc pair, and we need to understand that the
end of a block is at the end opcode at the very end, and not the end of
the header. This PR changes us to do that, i.e.
;; start is here
(block (result type)
.. contents ..
)
;; end is here
This fixes a testcase already in the test suite,
test/passes/fib_nonzero-low-pc_dwarf.bin.txt
where you can see that lexical block now has a valid value for the end, and
not a 0 (the proper scope extends all the way to the end of the big block in
that function, and is now the same in the DWARF before and after we
process it). test/passes/fannkuch3_dwarf.bin.txt is also improved by
this.
To implement this, this removes the BinaryLocations::End delimeter. After
this we just need one type of delimiter actually, but I didn't refactor that any
more to keep this PR small (see TODO).
This removes an assertion in writeDebugLocationEnd() that is no longer
valid: the assert ensures that we wrote an end only if there was a 0 for
the end, but for a control flow structure, we write the end of the "header"
automatically like for any expression, and then overwrite it later when we
finish writing the children and the end marker. We could in theory special-case
control flow structures to avoid the first write, but it would add more complexity.
This uncovered what appears to be a possible bug in our debug_line
handling, see test/passes/fannkuch3_manyopts_dwarf.bin.txt. That needs
to be looked into more, but I suspect that was invalid info from when we
looked at the end of the "header" of control flow structures. Note that there
was one definite bug uncovered here, fixed by the extra
} else if (locationUpdater.hasOldExprEnd(oldAddr)) {
that is added here, which was definitely a bug.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|