234 Commits

Author SHA1 Message Date
Alex Crichton 1898b8c771 Run all *.wast tests in fuzzing (#8121)
* Run all `*.wast` tests in fuzzing

Currently we have a `spectest` fuzzer which uses fuzz input to generate
an arbitrary configuration for Wasmtime and then executes the spec test.
This ensures that no matter the configuration Wasmtime can pass spec
tests. This commit expands this testing to include all `*.wast` tests we
have in this repository. While we don't have a ton we still have some
significant ones like in #8118 which will only reproduce when turning
knobs on CPU features.

* Fix CLI build

* Fix wast testing
2024-03-13 20:39:03 +00:00
Alex Crichton 9ce3ffe15e Update some CI dependencies (#7983)
* Update some CI dependencies

* Update to the latest nightly toolchain
* Update mdbook
* Update QEMU for cross-compiled testing
* Update `cargo nextest` for usage with MIRI

prtest:full

* Remove lots of unnecessary imports

* Downgrade qemu as 8.2.1 seems to segfault

* Remove more imports

* Remove unused winch trait method

* Fix warnings about unused trait methods

* More unused imports

* More unused imports
2024-02-22 23:54:03 +00:00
Jamey Sharp caa555f8f5 cranelift: Enable "chaos mode" in egraph pass (#7968)
First of all, thread a "chaos mode" control-plane into Context::optimize
and from there into EgraphPass, OptimizeCtx, and Elaborator.

In this commit we use the control-plane to change the following
behaviors in ways which shouldn't cause incorrect results:

- Dominator-tree block traversal order for both the rule application and
  elaboration passes
- Order of evaluating optimization alternatives from `simplify`
- Choose worst values instead of best in each eclass

Co-authored-by: L. Pereira <lpereira@fastly.com>
2024-02-20 22:26:21 +00:00
Alex Crichton 353dc27389 Fully enable Winch in the differential fuzzer (#7932)
This commit fully enables usage of Winch in the `differential` fuzzer
against all other engines with no special cases. I attempted enabling
winch for the other fuzzers as well but Winch doesn't currently
implement all methods for generating various trampolines required so
it's currently only limited to the `differential` fuzzer.

This adds Winch as an "engine" and additionally ensures that when
configured various wasm proposals are disabled that Winch doesn't
support (similar to how enabling `wasmi` disables proposals that `wasmi`
doesn't support).

This does reduce fuzzing of Winch slightly in that the reference-types
proposal is completely disabled for Winch rather than half-enabled where
Winch doesn't implement `externref` operations yet but does implement
`funcref` operations. This, however, enables integrating it more cleanly
into the rest of the fuzzing infrastructure with fewer special cases.
2024-02-14 15:10:32 +00:00
Alex Crichton 04c03b31b7 Update the wasm-tools family of crates (#7921)
* Update the wasm-tools family of crates

Pulling in some updates to improve how WIT is managed in this
repository. No changes just yet, however, just pulling in the updates
first.

* Fix tests

* Fix fuzzer build
2024-02-12 23:22:16 +00:00
Nick Fitzgerald 15e5cf088c Fix warnings on nightly (#7904) 2024-02-09 17:54:11 +00:00
Saúl Cabrera 83cf7438ab winch: Add support for WebAssembly loads/stores (#7894)
* winch: Add support for WebAssembly loads/stores

Closes https://github.com/bytecodealliance/wasmtime/issues/6529

This patch adds support for all the instructions involving WebAssembly
loads and stores for 32-bit memories. Given that the `memory64` proposal
is not enabled by default, this patch doesn't include an
implementation/tests for it; in theory minimal tweaks to the
currrent implementation will be needed in order to support 64-bit
memories.

Implemenation-wise, this change, follows a similar pattern as Cranelift
in order to calculate addresses for dynamic/static heaps, the main
difference being that in some cases, doing less work at compile time is
preferred; the current implemenation only checks for the general case of
out-of-bounds access for dynamic heaps for example.

Another important detail regarding the implementation, is the
introduction of `MacroAssembler::wasm_load` and
`MacroAssembler::wasm_store`, which internally use a common
implemenation for loads and stores, with the only difference that the
`wasm_*` variants set the right flags in order to signal that these
operations are not trusted and might trap.

Finally, given that this change introduces support for the last set of
instructions missing for a Wasm MVP, it removes most of Winch's copy of
the spectest suite, and switches over to using the official test suite
where possible (for tests that don't use SIMD or Reference Types).

Follow-up items:

* Before doing any deep benchmarking I'm planning on landing a couple of
  improvements regarding compile times that I've identified in parallel
  to this change.
* The `imports.wast` tests are disabled because I've identified a bug
  with `call_indirect`, which is not related to this change and exists
  in main.
* Find a way to run the `tests/all/memory.rs` (or perhaps most of
  integration tests) with Winch.

--
prtest:full

* Review comments
2024-02-09 15:28:33 +00:00
Jeffrey Charles b546a5f257 Winch: Float conversion instructions (#7773)
* Winch: Float conversion instructions

* Add conversions suite to ignore list for Windows
2024-01-12 19:49:25 +00:00
Saúl Cabrera 446a7f5e02 winch: Multi-Value Part 2: Blocks (#7707)
* winch: Multi-Value Part 2: Blocks

This commit adds support for the Multi-Value proposal for blocks.

In general, this change, introduces multiple building blocks to enable
supporting arbitrary params and results in blocks:

* `BlockType`: Introduce a block type, to categorize the type of each
  block, this makes it easier to categorize blocks per type and also
  makes it possible to defer the calculation of the `ABIResults` until
  they are actually needed rather than calculating everyghing upfront
  even though they might not be needed (when in an unreachable state).
* Push/pop operations are now frame aware. Given that each
  `ControlStackFrame` contains all the information needed regarding
  params and results, this change moves the the implementation of the
  push and pop operations to the `ControlStackFrame` struct.
* `StackState`: this struct holds the entry and exit invariants of each
  block; these invariants are pre-computed when entering the block and
  used throughout the code generation, to handle params, results and
  assert the respective invariants.

In terms of the mechanics of the implementation: when entering each
block, if there are results on the stack, the expected stack pointer
offsets will be calculated via the `StackState`, and the `target_offset`
will be used to create the block's `RetArea`. Note that when entering
the block and calculating the `StackState` no space is actually reserved
for the results, any space increase in the stack is deffered until the
results are popped from the value stack via
`ControlStackFrame::pop_abi_results`.

The trickiest bit of the implementation is handling constant values that
need to be placed on the right location on the machine stack. Given that
constants are generally not spilled, this means that in order to keep
the machine and value stack in sync (spilled-values-wise), values must
be shuffled to ensure that constants are placed in the expected location results wise.
See the comment in `ControlStackFrame::adjust_stack_results` for more
details.

* Review fixes
2024-01-08 19:57:40 +00:00
Saúl Cabrera 5708d69375 winch: Add memory instructions (#7721)
* winch: Add memory instructions

This commit adds support for the following memory instructions to winch:

* `data.drop`
* `memory.init`
* `memory.fill`
* `memory.copy`
* `memory.size`
* `memory.grow`

In general the implementation is similar to what other instructions via
builtins are hanlded (e.g. table instructions), which involve stack
manipulation prior to emitting a builtin function call, with the
exception of `memory.size`, which involves loading the current length
from the `VMContext`

* Emit right shift instead of division to obtain the memory size in pages
2024-01-03 14:07:30 +00:00
Jeffrey Charles 3b055d4776 Winch: integer conversion instructions (#7683) 2023-12-13 21:54:03 +00:00
Saúl Cabrera 338653878d winch: Tighten fuzzing criteria (#7621)
This commit tightens the fuzzing criteria for Winch. The previous
implementation only accounted for unsupported instructions. However,
unsupported types can also cause the fuzzer to crash.

Winch currently doesn't support `v128` and most of the `Ref` types.
2023-11-30 20:53:39 +00:00
Alex Crichton 5856590fae Configure workspace lints, enable running some Clippy lints on CI (#7561)
* Configure Rust lints at the workspace level

This commit adds necessary configuration knobs to have lints configured
at the workspace level in Wasmtime rather than the crate level. This
uses a feature of Cargo first released with 1.74.0 (last week) of the
`[workspace.lints]` table. This should help create a more consistent set
of lints applied across all crates in our workspace in addition to
possibly running select clippy lints on CI as well.

* Move `unused_extern_crates` to the workspace level

This commit configures a `deny` lint level for the
`unused_extern_crates` lint to the workspace level rather than the
previous configuration at the individual crate level.

* Move `trivial_numeric_casts` to workspace level

* Change workspace lint levels to `warn`

CI will ensure that these don't get checked into the codebase and
otherwise provide fewer speed bumps for in-process development.

* Move `unstable_features` lint to workspace level

* Move `unused_import_braces` lint to workspace level

* Start running Clippy on CI

This commit configures our CI to run `cargo clippy --workspace` for all
merged PRs. Historically this hasn't been all the feasible due to the
amount of configuration required to control the number of warnings on
CI, but with Cargo's new `[lint]` table it's possible to have a
one-liner to silence all lints from Clippy by default. This commit by
default sets the `all` lint in Clippy to `allow` to by-default disable
warnings from Clippy. The goal of this PR is to enable selective access
to Clippy lints for Wasmtime on CI.

* Selectively enable `clippy::cast_sign_loss`

This would have fixed #7558 so try to head off future issues with that
by warning against this situation in a few crates. This lint is still
quite noisy though for Cranelift for example so it's not worthwhile at
this time to enable it for the whole workspace.

* Fix CI error

prtest:full
2023-11-20 23:23:41 +00:00
Afonso Bordado aef871b3da fuzzgen: Allow restricting generated opcodes with env var (#7433)
* fuzzgen: Allow restricting generated opcodes with env var

* fuzzgen: Add `FUZZGEN_ALLOWED_OPS` docs
2023-11-01 08:55:31 +00:00
Jeffrey Charles 0d797f7f77 Add float comparison operators to Winch (#7379)
* Add float comparison operators to Winch

* Simplify gt and gte ops and add comments
2023-10-26 19:10:11 +00:00
Jeffrey Charles dd42290e9a Add support for binary float operators to Winch (#7290) 2023-10-19 14:25:15 +00:00
Nick Fitzgerald c16540ed2a Update arbitrary to 1.3.1 (#7236)
* Update to arbitrary 1.3.1

And use workspace dependencies for arbitrary.

* Prune cargo vet's supply-chain files

This is the mechanical changes made by running `cargo vet prune` which was
suggested to me when I ran `cargo vet`.
2023-10-13 18:16:21 +00:00
Jeffrey Charles 654d9f5ea4 Add support for float sqrt operators to Winch (#7230) 2023-10-12 18:19:13 +00:00
Saúl Cabrera a109d2abe5 winch(x64): Add support for table instructions (#7155)
* winch(x64): Add support for table instructions

This change adds support for the following table insructions:
`elem.drop`, `table.copy`, `table.set`, `table.get`, `table.fill`,
`table.grow`, `table.size`, `table.init`.

This change also introduces partial support for the `Ref` WebAssembly
type, more conretely the `Func` heap type, which means that all the
table instructions above, only work this WebAssembly type as of this
change.

Finally, this change is also a small follow up to the primitives
introduced in https://github.com/bytecodealliance/wasmtime/pull/7100,
more concretely:

* `FnCall::with_lib`: tracks the presence of a libcall and ensures that
  any result registers are freed right when the call is emitted.
* `MacroAssembler::table_elem_addr` returns an address rather than the
  value of the address, making it convenient for other use cases like
  `table.set`.

--

prtest:full

* chore: Make stack functions take impl IntoIterator<..>

* Update winch/codegen/src/codegen/call.rs

Co-authored-by: Trevor Elliott <awesomelyawesome@gmail.com>

* Remove a dangling `dbg!`

* Add comment on branching

---------

Co-authored-by: Trevor Elliott <awesomelyawesome@gmail.com>
2023-10-06 22:10:55 +00:00
Saúl Cabrera 4b288ba88d winch(x64): Call indirect (#7100)
* winch(x64): Call indirect

This change adds support for the `call_indirect` instruction to Winch.

Libcalls are a pre-requisite for supporting `call_indirect` in order to
lazily initialy funcrefs. This change adds support for libcalls to
Winch by introducing a `BuiltinFunctions` struct similar to Cranelift's
`BuiltinFunctionSignatures` struct.

In general, libcalls are handled like any other function call, with the
only difference that given that not all the information to fulfill the
function call might be known up-front, control is given to the caller
for finalizing the call.

The introduction of function references also involves dealing with
pointer-sized loads and stores, so this change also adds the required
functionality to `FuncEnv` and `MacroAssembler` to be pointer aware,
making it straight forward to derive an `OperandSize` or `WasmType` from
the target's pointer size.

Finally, given the complexity of the call_indirect instrunction, this
change bundles an improvement to the register allocator, allowing it to
track the allocatable vs non-allocatable registers, this is done to
avoid any mistakes when allocating/de-allocating registers that are not
alloctable.

--
prtest:full

* Address review comments

* Fix typos
* Better documentation for `new_unchecked`
* Introduce `max` for `BitSet`
* Make allocatable property `u64`

* winch(calls): Overhaul `FnCall`

This commit simplifies `FnCall`'s interface making its usage more
uniform throughout the compiler. In summary, this change:

* Avoids side effects in the `FnCall::new` constructor, and also makes
  it the only constructor.
* Exposes `FnCall::save_live_registers` and
  `FnCall::calculate_call_stack_space` to calculate the stack space
  consumed by the call and so that the caller can decide which one to
  use at callsites depending on their use-case.

* tests: Fix regset tests
2023-09-29 16:59:40 +00:00
Trevor Elliott 9f00198611 winch: Support abs and neg for f32 and f64 on x64 (#6982)
* winch: Support f32.abs and f64.abs on x64

Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>

* Add an implementation of f32.neg and f64.neg

* Enable spec tests for winch with f{32,64}.{neg,abs}

* Enable differential fuzzing for f{32,64}.{neg,abs} for winch

* Comments from code review

---------

Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>
2023-09-10 22:14:09 +00:00
Afonso Bordado f10d665bb9 fuzzgen: Enable SIMD fuzzing for RISC-V (#6949) 2023-09-02 03:00:50 +00:00
Saúl Cabrera 350410ac9c winch: Add support for br_table (#6951)
* winch: Add support for `br_table`

This change adds support for the `br_table` instruction, including
several modifications to the existing control flow implementation:

* Improved handling of jumps to loops: Previously, the compiler erroneously
treated the result of loop blocks as the definitive result of the jump. This
change fixes this bug.

* Streamlined result handling and stack pointer balancing: In the past, these
operations were executed in two distinct steps, complicating the process of
ensuring the correct invariants when emitting unconditional jumps. To simplify
this, `CodeGenContext::unconditional_jump` is introduced . This function
guarantees all necessary invariants are met, encapsulating the entire operation
within a single function for easier understanding and maintenance.

* Handling of unreachable state at the end of a function: when reaching the end
of a function in an unreachable state, clear the stack and ensure that the
machine stack pointer is correctly placed according to the expectations of the
outermost block.

In addition to the above refactoring, the main implementation of the
`br_table` instruction involves emitting labels for each target. Within each
label, an unconditional jump is emitted to the frame's label, ensuring correct
stack pointer balancing  when the jump is emitted.

While it is possible to optimize this process by avoiding intermediate labels
when balancing isn't required, I've opted to maintain the current
implementation until such optimization becomes necessary.

* chore: Rust fmt

* fuzzing: Add `BrTable` to list of support instructions

* docs: Improve documentation for `unconditional_jump`
2023-09-01 23:14:41 +00:00
Alex Crichton 1a11e25cff Fix some more fuzz-test cases from pooling changes (#6943)
* Fix some warnings on nightly Rust

* Fix some more fuzz-test cases from pooling changes

This commit addresses some more fallout from #6835 by updating some
error messages and adding clauses for new conditions. Namely:

* Module compilation is now allowed to fail when the module may have
  more memories/tables than the pooling allocator allows per-module.
* The error message for the core instance limit being reached has been
  updated.
2023-08-31 15:49:27 +00:00
Saúl Cabrera 14b39bc234 winch: Initial support for floats (#6860)
* winch: Initial support for floats

This change introuduces the necessary building blocks to support floats in
Winch as well as support for both `f32.const` and `f64.const` instructions.

To achieve support for floats, this change adds several key enhancements to the
compiler:

* Constant pool: A constant pool is implemented, at the Assembler level, using the machinery
  exposed by Cranelift's `VCode` and `MachBuffer`. Float immediates are stored
  using their bit representation in the value stack, and whenever they are
  used at the MacroAssembler level they are added to the constant
  pool, from that point on, they are referenced through a `Constant` addressing
  mode, which gets translated to a RIP-relative addressing mode during emission.

* More precise value tagging: aside from immediates, from which the type can
  be easily inferred, all the other value stack entries (`Memory`, `Reg`, and `Local`) are
  modified to explicitly contain a WebAssembly type. This allows for better
  instruction selection.

--

prtest:full

* fix: Account for relative sp position when pushing float regs

This was an oversight of the initial implementation. When pushing float
registers, always return an address that is relative to the current position of
the stack pointer, essentially storing to (%rsp). The previous implementation
accounted for static addresses, which is not correct.

* fix: Introduce `stack_arg_slot_size_for_type`

To correctly calculate the stack argument slot sizes, instead of overallocating
for `word_bytes`, since for `f32` floating points we only need to worry about
loading/storing 4 bytes.

* fix: Correctly type the result register.

The previous version wrongly typed the register as a general purpose register.

* refactor: Re-write `add_constants` through `add_constant`

* docs: Replace old comment

* chore: Rust fmt

* refactor: Index regset per register class

This commit implements `std::ops::{Index, IndexMut}` for `RegSet` to index each
of the bitsets by class. This reduces boilerplate and repetition throuhg the
code generation context, register allocator and register set.

* refactor: Correctly size callee saved registers

To comply with the expectation of the underlying architecture: for example in
Aarch64, only the low 64 bits of VRegs are callee saved (the D-view) and in the
`fastcall` calling convention it's expected that the callee saves the entire 128
bits of the register xmm6-xmm15.

This change also fixes the the stores/loads of callee saved float registers in the
fastcall calling convention, as in the previous implementation only the low 64
bits were saved/restored.

* docs: Add comment regarding typed-based spills
2023-08-23 10:44:35 +00:00