summaryrefslogtreecommitdiff
path: root/test/passes
Commit message (Collapse)AuthorAgeFilesLines
* Use non-nullable ref.cast for non-nullable input (#5335)Thomas Lively2022-12-091-2/+2
| | | | | | | | | | | | We switched from emitting the legacy `ref.cast_static` instruction to emitting `ref.cast null` in #5331, but that wasn't quite correct. The legacy instruction had polymorphic typing so that its output type was nullable if and only if its input type was nullable. In contrast, `ref.cast null` always has a a nullable output type. Fix our output by instead emitting non-nullable `ref.cast` if the output should be non-nullable. Parse `ref.cast` in binary and text forms as well. Since the IR can only represent the legacy polymorphic semantics, disallow unsupported casts from nullable to non-nullable references or vice versa for now.
* Allow casting to basic heap types (#5332)Thomas Lively2022-12-082-23/+10
| | | | | | | The standard casting instructions now allow casting to basic heap types, not just user-defined types, but they also require that the intended type and argument type have a common supertype. Update the validator to use the standard rules, update the binary parser and printer to allow basic types, and update the tests to remove or modify newly invalid test cases.
* Add standard versions of WasmGC casts (#5331)Thomas Lively2022-12-072-26/+26
| | | | | | | We previously supported only the non-standard cast instructions introduced when we were experimenting with nominal types. Parse the names and opcodes of their standard counterparts and switch to emitting the standard names and opcodes. Port all of the tests to use the standard instructions, but add additional tests showing that the non-standard versions are still parsed correctly.
* Update tests ahead of transition from `data` to `struct` (#5320)Thomas Lively2022-12-075-229/+31
| | | | | | | | | | The upstream WasmGC spec has removed `data` and introduced `struct`. To make the migration easier, we have been supporting `struct` as an `alias` for `data` and `structref` as an alias for `dataref`. Update the tests to prefer the `struct` aliases over `data` for test input to make the future migration easier. Also update some tests that had stale comments about ref.null types being updated and remove some tests for instructions like br_on_data and ref.as_data that do not make sense without a `data` type.
* [Wasm GC] Implement closed-world flag (#5303)Alon Zakai2022-11-301-11/+7
| | | | | | | | | | | | | With this change we default to an open world, that is, we do the safe thing by default: we no longer assume a closed world. Users that want a closed world must pass --closed-world. Atm we just do not run passes that assume a closed world. (We might later refine them to find which types don't escape and only optimize those.) The RemoveUnusedModuleElements is an exception in that the closed-world flag influences one part of its operation, but not the rest. Fixes #5292
* [NFC] Avoid unneeded work in GTO (#5304)Alon Zakai2022-11-301-4/+1
| | | | | As noticed in #5303, the test changes here are because we did unnecessary work which created a new rec group, which then led to a rec group being printed out.
* Change the default type system to isorecursive (#5239)Thomas Lively2022-11-2324-439/+445
| | | | | | | | | | This makes Binaryen's default type system match the WasmGC spec. Update the way type definitions without supertypes are printed to reduce the output diff for MVP tests that do not involve WasmGC. Also port some type-builder.cpp tests from test/example to test/gtest since they needed to be rewritten to work with isorecursive type anyway. A follow-on PR will remove equirecursive types completely.
* Revert "Revert "Make `call_ref` type annotations mandatory (#5246)" (#5265)" ↵Thomas Lively2022-11-162-3/+3
| | | | | (#5266) This reverts commit 570007dbecf86db5ddba8d303896d841fc2b2d27.
* Revert "Make `call_ref` type annotations mandatory (#5246)" (#5265)Thomas Lively2022-11-162-3/+3
| | | | | This reverts commit b2054b72b7daa89b7ad161c0693befad06a20c90. It looks like the necessary V8 change has not rolled out everywhere yet.
* Make `call_ref` type annotations mandatory (#5246)Thomas Lively2022-11-152-3/+3
| | | | They were optional for a while to allow users to gracefully transition to using them, but now make them mandatory to match the upstream WasmGC spec.
* Update default features to match new llvm defaults (#5212)Sam Clegg2022-11-034-34/+30
| | | See: https://reviews.llvm.org/D125728
* Parse and emit `array.len` without a type annotation (#5151)Thomas Lively2022-10-181-2/+2
| | | Test that we can still parse the old annotated form as well.
* Implement `array` basic heap type (#5148)Thomas Lively2022-10-181-33/+37
| | | | | | | | | `array` is the supertype of all defined array types and for now is a subtype of `data`. (Once `data` becomes `struct` this will no longer be true.) Update the binary and text parsing of `array.len` to ignore the obsolete type annotation and update the binary emitting to emit a zero in place of the old type annotation and the text printing to print an arbitrary heap type for the annotation. A follow-on PR will add support for the newer unannotated version of `array.len`.
* Implement bottom heap types (#5115)Thomas Lively2022-10-077-60/+60
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | These types, `none`, `nofunc`, and `noextern` are uninhabited, so references to them can only possibly be null. To simplify the IR and increase type precision, introduce new invariants that all `ref.null` instructions must be typed with one of these new bottom types and that `Literals` have a bottom type iff they represent null values. These new invariants requires several additional changes. First, it is now possible that the `ref` or `target` child of a `StructGet`, `StructSet`, `ArrayGet`, `ArraySet`, or `CallRef` instruction has a bottom reference type, so it is not possible to determine what heap type annotation to emit in the binary or text formats. (The bottom types are not valid type annotations since they do not have indices in the type section.) To fix that problem, update the printer and binary emitter to emit unreachables instead of the instruction with undetermined type annotation. This is a valid transformation because the only possible value that could flow into those instructions in that case is null, and all of those instructions trap on nulls. That fix uncovered a latent bug in the binary parser in which new unreachables within unreachable code were handled incorrectly. This bug was not previously found by the fuzzer because we generally stop emitting code once we encounter an instruction with type `unreachable`. Now, however, it is possible to emit an `unreachable` for instructions that do not have type `unreachable` (but are known to trap at runtime), so we will continue emitting code. See the new test/lit/parse-double-unreachable.wast for details. Update other miscellaneous code that creates `RefNull` expressions and null `Literals` to maintain the new invariants as well.
* Simplify and fix heap type counting (#5110)Thomas Lively2022-10-041-1/+1
| | | | | Annotations on array.get and array.set were not being counted and the code could generally be simplified since `count` already ignores types that don't need to be counted.
* Memory64Lowering: Ignore data segments with non-const iniital offset (#5074)Sam Clegg2022-09-282-0/+5
| | | | This is the case for dynamic linking where the segment offset are derived from he `__memory_base` import.
* Emit call_ref with a type annotation (#5079)Thomas Lively2022-09-231-1/+1
| | | | | | | Emit call_ref instructions with type annotations and a temporary opcode. Also implement support for parsing optional type annotations on call_ref in the text and binary formats. This is part of a multi-part graceful update to switch Binaryen and all of its users over to using the type-annotated version of call_ref without there being any breakage.
* Correctly handle escapes in string constants (#5070)Thomas Lively2022-09-221-3/+3
| | | | | | | Previously when we parsed `string.const` payloads in the text format we were using the text strings directly instead of un-escaping them. Fix that parsing, and while we're editing the code, also add support for the `\r` escape allowed by the spec. Remove a spurious nested anonymous namespace and spurious `static`s in Print.cpp as well.
* [OptimizeInstructions] Simplify add / sub with negative on LHS or RHS for ↵Max Graey2022-09-201-51/+10
| | | | | | | | | floating points (#5034) ``` (-x) + y -> y - x x + (-y) -> x - y x - (-y) -> x + y ```
* Vacuum: Ignore effects at the entire function scope when possible (#5053)Alon Zakai2022-09-192-4/+9
| | | | | | | | | | | | | | | Recently we added logic to ignore effects that don't "escape" past the function call. That is, e.g. local.set only affects the current function scope, and once the call stack is unwound it no longer matters as an effect. This moves that logic to a shared place, and uses it in the core Vacuum logic. The new constructor in EffectAnalyzer receives a function and then scans it as a whole. This works just like e.g. scanning a Block as a whole (if we see a break in the block, that has an effect only inside it, and the Block + children doesn't have a branch effect). Various tests are updated so they don't optimize away trivially, by adding new return values for them.
* Effects: Clarify trap effect meaning, and consider infinite loops to trap ↵Alon Zakai2022-09-161-2/+6
| | | | | | | | | | | | | | | | | | | | | due to timeout (#5039) I think this simplifies the logic behind what we consider to trap. Before we had kind of a hack in visitLoop that now has a more clear reasoning behind it: we consider as trapping things that trap in all VMs all the time, or will eventually. So a single allocation doesn't trap, but an unbounded amount can, and an infinite loop is considered to trap as well (a timeout in a VM will be hit eventually, somehow). This means we cannot optimize way a trivial infinite loop with no effects in it, while (1) {} But we can optimize it out in trapsNeverHappen mode. In any event, such a loop is not a realistic situation; an infinite loop with some other effect in it, like a call to an import, will not be optimized out, of course. Also clarify some other things regarding traps and trapsNeverHappen following recent discussions in https://github.com/emscripten-core/emscripten/issues/17732 Specifically, TNH will never be allowed to remove calls to imports.
* wasm2js: Don't assume that `env.abort` can always be impored. (#5049)Sam Clegg2022-09-161-0/+2
| | | | | | This import was being injected and then used to implement trapping. Rather than injecting an import that doesn't exist in the original module we instead use the existing mechanism to implement this as an internal helper.
* [OptimizeInstructions] More canonizations for floating points (#5033)Max Graey2022-09-151-24/+4
| | | | | | | | x - C -> x + (-C) min(C, x) -> min(x, C) max(C, x) -> max(x, C) And remove redundant rules
* OptimizeInstructions: Use min/max bits in comparisons (#5035)Alon Zakai2022-09-131-4/+1
| | | | | | | When we see e.g. x < y and x has fewer bits set, we can infer a result. Helps #5010. As mentioned there, this is one of the top superoptimizer findings. On j2wasm it ends up removing a few hundred binary operations for example.
* [OptimizeInstructions] Simplify floating point ops with NaN on right side ↵Max Graey2022-09-121-8/+2
| | | | | | | | | | | | | | | | | | | (#4985) x + nan -> nan' x - nan -> nan' x * nan -> nan' x / nan -> nan' min(x, nan) -> nan' max(x, nan) -> nan' where nan' is canonicalized nan of rhs x != nan -> 1 x == nan -> 0 x >= nan -> 0 x <= nan -> 0 x > nan -> 0 x < nan -> 0
* Remove typed-function-references feature (#5030)Thomas Lively2022-09-092-34/+36
| | | | | | | | | | | | | | | | In practice typed function references will not ship before GC and is not independently useful, so it's not necessary to have a separate feature for it. Roll the functionality previously enabled by --enable-typed-function-references into --enable-gc instead. This also avoids a problem with the ongoing implementation of the new GC bottom heap types. That change will make all ref.null instructions in Binaryen IR refer to one of the bottom heap types. But since those bottom types are introduced in GC, it's not valid to emit them in binaries unless unless GC is enabled. The fix if only reference types is enabled is to emit (ref.null func) instead of (ref.null nofunc), but that doesn't always work if typed function references are enabled because a function type more specific than func may be required. Getting rid of typed function references as a separate feature makes this a nonissue.
* Update fuzzer to newer GC spec regarding JS interop (#4965)Alon Zakai2022-08-311-30/+30
| | | | Do not export functions that have types not allowed in the rules for JS interop. Only very few GC types can be on the JS boundary atm.
* [Wasm GC] Support non-nullable locals in the "1a" form (#4959)Alon Zakai2022-08-311-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An overview of this is in the README in the diff here (conveniently, it is near the top of the diff). Basically, we fix up nn locals after each pass, by default. This keeps things easy to reason about - what validates is what is valid wasm - but there are some minor nuances as mentioned there, in particular, we ignore nameless blocks (which are commonly added by various passes; ignoring them means we can keep more locals non-nullable). The key addition here is LocalStructuralDominance which checks which local indexes have the "structural dominance" property of 1a, that is, that each get has a set in its block or an outer block that precedes it. I optimized that function quite a lot to reduce the overhead of running that logic after each pass. The overhead is something like 2% on J2Wasm and 0% on Dart (0%, because in this mode we shrink code size, so there is less work actually, and it balances out). Since we run fixups after each pass, this PR removes logic to manually call the fixup code from various places we used to call it (like eh-utils and various passes). Various passes are now marked as requiresNonNullableLocalFixups => false. That lets us skip running the fixups after them, which we normally do automatically. This helps avoid overhead. Most passes still need the fixups, though - any pass that adds a local, or a named block, or moves code around, likely does. This removes a hack in SimplifyLocals that is no longer needed. Before we worked to avoid moving a set into a try, as it might not validate. Now, we just do it and let fixups happen automatically if they need to: in the common code they probably don't, so the extra complexity seems not worth it. Also removes a hack from StackIR. That hack tried to avoid roundtrip adding a nondefaultable local. But we have the logic to fix that up now, and opts will likely keep it non-nullable as well. Various tests end up updated here because now a local can be non-nullable - previous fixups are no longer needed. Note that this doesn't remove the gc-nn-locals feature. That has been useful for testing, and may still be useful in the future - it basically just allows nn locals in all positions (that can't read the null default value at the entry). We can consider removing it separately. Fixes #4824
* Make `i31ref` and `dataref` nullable (#4843)Thomas Lively2022-08-265-12/+12
| | | | | | | Match the latest version of the GC spec. This change does not depend on V8 changing its interpretation of the shorthands because we are still temporarily not emitting the binary shorthands, but all Binaryen users will have to update their interpretations along with this change if they use the text or binary shorthands.
* Adding Multi-Memories Wasm Feature (#4968)Ashley Nelson2022-08-251-0/+1
| | | Adding multi-memories to the the list of wasm-features.
* Separate `func` into a separate type hierarchy (#4955)Thomas Lively2022-08-226-40/+44
| | | | | Just like `extern` is no longer a subtype of `any` in the new GC type system, `func` is no longer a subtype of `any`, either. Make that change in our type system implementation and update tests and fuzzers accordingly.
* RemoveUnusedBrs: Remove final block nops in all cases (#4954)Alon Zakai2022-08-221-13/+0
| | | | | | | | | | | | | | | | | | | | This fixes what looks like it might be a regression in #4943. It's not actually an issue since it just affects wat files, but it did uncover an existing inefficiency. The situation is this: (block .. (br $somewhere) (nop) ) Removing such a nop is always helpful, as the pass might see that that br goes to where control flow is going anyhow, and the nop would confuse it. We used to remove such nops only when the block had a name, which is why wat testcases looks optimal, but we were actually doing the less-efficient thing on real-world code. It was a minor inefficiency, though, as the nop is quickly removed by later passes anyhow. Still, the fix is trivial (to always remove such nops, regardless of a name on the block or not).
* Avoid adding new unneeded names to blocks in text roundtripping (#4943)Alon Zakai2022-08-2225-314/+271
| | | | | | | | | | | | | | | | | | | | | | | Previously the wat parser would turn this input: (block (nop) ) into something like this: (block $block17 (nop) ) It just added a name all the time, in case the block is referred to by an index later even though it doesn't have a name. This PR makes us rountrip more precisely by not adding such names: if there was no name before, and there is no break by index, then do not add a name. In addition, this will be useful for non-nullable locals since whether a block has a name or not matters there. Like #4912, this makes us more regular in our usage of block names.
* Restore the `extern` heap type (#4898)Thomas Lively2022-08-176-46/+45
| | | | | | | The GC proposal has split `any` and `extern` back into two separate types, so reintroduce `HeapType::ext` to represent `extern`. Before it was originally removed in #4633, externref was a subtype of anyref, but now it is not. Now that we have separate heaptype type hierarchies, make `HeapType::getLeastUpperBound` fallible as well.
* Mutli-Memories Support in IR (#4811)Ashley Nelson2022-08-1711-7/+29
| | | | | | | This PR removes the single memory restriction in IR, adding support for a single module to reference multiple memories. To support this change, a new memory name field was added to 13 memory instructions in order to identify the memory for the instruction. It is a goal of this PR to maintain backwards compatibility with existing text and binary wasm modules, so memory indexes remain optional for memory instructions. Similarly, the JS API makes assumptions about which memory is intended when only one memory is present in the module. Another goal of this PR is that existing tests behavior be unaffected. That said, tests must now explicitly define a memory before invoking memory instructions or exporting a memory, and memory names are now printed for each memory instruction in the text format. There remain quite a few places where a hardcoded reference to the first memory persist (memory flattening, for example, will return early if more than one memory is present in the module). Many of these call-sites, particularly within passes, will require us to rethink how the optimization works in a multi-memories world. Other call-sites may necessitate more invasive code restructuring to fully convert away from relying on a globally available, single memory pointer.
* Port test/passes/legalize-js-interface* to lit (#4903)Sam Clegg2022-08-126-291/+0
| | | | | Also, add support for the `--binaryen-bin` flag to `scripts/port_passes_tests_to_lit.py`. This is needed for folks who don't do in-tree builds.
* Remove RTTs (#4848)Thomas Lively2022-08-055-368/+97
| | | | | | | RTTs were removed from the GC spec and if they are added back in in the future, they will be heap types rather than value types as in our implementation. Updating our implementation to have RTTs be heap types would have been more work than deleting them for questionable benefit since we don't know how long it will be before they are specced again.
* Remove basic reference types (#4802)Thomas Lively2022-07-201-26/+24
| | | | | | | | | Basic reference types like `Type::funcref`, `Type::anyref`, etc. made it easy to accidentally forget to handle reference types with the same basic HeapTypes but the opposite nullability. In principle there is nothing special about the types with shorthands except in the binary and text formats. Removing these shorthands from the internal type representation by removing all basic reference types makes some code more complicated locally, but simplifies code globally and encourages properly handling both nullable and non-nullable reference types.
* [Strings] Add feature flag for Strings proposal (#4766)Alon Zakai2022-06-301-0/+1
|
* First class Data Segments (#4733)Ashley Nelson2022-06-2111-27/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Updating wasm.h/cpp for DataSegments * Updating wasm-binary.h/cpp for DataSegments * Removed link from Memory to DataSegments and updated module-utils, Metrics and wasm-traversal * checking isPassive when copying data segments to know whether to construct the data segment with an offset or not * Removing memory member var from DataSegment class as there is only one memory rn. Updated wasm-validator.cpp * Updated wasm-interpreter * First look at updating Passes * Updated wasm-s-parser * Updated files in src/ir * Updating tools files * Last pass on src files before building * added visitDataSegment * Fixing build errors * Data segments need a name * fixing var name * ran clang-format * Ensuring a name on DataSegment * Ensuring more datasegments have names * Adding explicit name support * Fix fuzzing name * Outputting data name in wasm binary only if explicit * Checking temp dataSegments vector to validateBinary because it's the one with the segments before we processNames * Pass on when data segment names are explicitly set * Ran auto_update_tests.py and check.py, success all around * Removed an errant semi-colon and corrected a counter. Everything still passes * Linting * Fixing processing memory names after parsed from binary * Updating the test from the last fix * Correcting error comment * Impl kripken@ comments * Impl tlively@ comments * Updated tests that remove data print when == 0 * Ran clang format * Impl tlively@ comments * Ran clang-format
* Include globals when collecting module types (#4717)Thomas Lively2022-06-101-1/+1
| | | | Otherwise when a type is only used on a global, it will be incorrectly omitted from the output.
* Restore and fix SpillPointers pass (#4570)Alon Zakai2022-06-062-0/+1631
| | | | | | | | We have some possible use cases for this pass, and so are restoring it. This reverts the removal in #3261, fixes compile errors in internal API changes since then, and flips the direction of the stack for the wasm backend.
* [GC Fuzzing] Avoid non-nullable eqref without GC (#4675)Alon Zakai2022-05-181-28/+34
| | | | | | With only reference types but not GC, we cannot easily create a constant for eqref for example. Only GC adds i31.new etc. To avoid assertions in the fuzzer, avoid randomly picking (ref eq) etc., that is, keep it nullable so that we can emit a (ref.null eq) if we need a constant value of that type.
* [Fuzzer] Fix another reference types vs gc types issue (#4647)Alon Zakai2022-05-061-39/+27
| | | | | | | | | | Diff without whitespace is smaller. We can't emit HeapType::data without GC. Fixing that by switching to func, another problem was uncovered: makeRefFuncConst had a TODO to handle the case where we need a function to refer to but have created none yet. In fact that TODO was done at the end of the function. Fix up the logic in between to actually get there.
* Fix fuzzer's choosing of reference types (#4642)Alon Zakai2022-05-051-32/+37
| | | | | | * Don't emit "i31" or "data" if GC is not enabled, as only the GC feature adds those. * Don't emit "any" without GC either. While it is allowed, fuzzer limitations prevent this atm (see details in comment - it's fixable).
* Remove externref (#4633)Thomas Lively2022-05-045-52/+49
| | | | | | Remove `Type::externref` and `HeapType::ext` and replace them with uses of anyref and any, respectively, now that we have unified these types in the GC proposal. For backwards compatibility, continue to parse `extern` and `externref` and maintain their relevant C API functions.
* Replace 64K sparse matrix testcase with 8K (#4635)Alon Zakai2022-05-033-2/+2
| | | | Helps #4632: This makes it take 4 seconds instead of 5 minutes.
* Lift the restriction in liveness-traversal.h that supported max 65535 locals ↵juj2022-04-283-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | in a function. (#4567) * Lift the restriction in liveness-traversal.h that supported max 65535 locals in a function. * Lint * Fix typo * Fix static * Lint * Lint * Lint * Add needed canRun function * lint * Use either a sparse or a dense matrix for tracking liveness copies, depending on the locals count. * Lint * Fix lint * Lint * Implement sparse_square_matrix class and use that as a backing. * Lint * Lint * Lint #includes * Lint * Lint includes * Remove unnecessary code * Fix canonical accesses to copies matrix * Lint * Add missing variable update * Remove canRun() function * Address review * Update expected test results * Update test name * Add asserts to sparse_square_matrix set and get functions that they are not out of bound. * Lint includes * Update test expectation * Use .clear() + .resize() to reset totalCopies vector
* RemoveUnusedModuleElements: Track CallRef/RefFunc more precisely (#4621)Alon Zakai2022-04-282-22/+0
| | | | | | | | | | | | | | | | | | If we see (ref.func $foo) that does not mean that $foo is reachable - we must also see a (call_ref ..) of the proper type. Only after seeing both should we mark the function as reachable, which this PR does. This adds some complexity as we need to track intermediate state as we go, since we could see the RefFunc before the CallRef or vice versa. We also need to handle the case of a RefFunc without a CallRef properly: We cannot remove the function, as the RefFunc must refer to it, but at least we can empty out the body since we know it is never reached. This removes an old wasm-opt test which is now superseded by a new lit test. On J2Wasm output this removes 3% of all functions, which account for 2.5% of total code size.
* Port memory-packing tests to lit (#4559)Thomas Lively2022-04-014-2146/+0
|