Commit Graph

9391 Commits

Author SHA1 Message Date
Scott McMurray
ca7c54b5f8 Add Type::int_with_byte_size constructor 2021-11-29 16:53:54 -08:00
Alex Crichton
33dba07e6b aarch64: Migrate imul to ISLE
This commit migrates the `imul` clif instruction lowering for AArch64 to
ISLE. This is a relatively complicated instruction with lots of special
cases due to the simd proposal for wasm. Like x64, however, the special
casing lends itself to ISLE quite well and the lowerings here in theory
are pretty straightforward.

The main gotcha of this commit is that this encounters a unique
situation which hasn't been encountered yet with other lowerings, namely
the `Umlal32` instruction used in the implementation of `i64x2.mul` is
unique in the `VecRRRLongOp` class of instructions in that it both reads
and writes the destination register (`use_mod` instead of simply
`use_def`). This meant that I needed to add another helper in ISLe for
creating a `vec_rrrr_long` instruction (despite this enum variant not
actually existing) which implicitly moves the first operand into the
destination before issuing the actual `VecRRRLong` instruction.
2021-11-29 16:05:57 -08:00
Dan Gohman
42b23dac4a Make the trap name for unreachable traps more descriptive. (#3568)
Following up on WebAssembly/wasi-sdk#210, this makes the trap message
for `unreachable` traps more descriptive of what actually caused the
trap, so that it doesn't sound like maybe Wasmtime itself executed a
`unreachable!()` macro in Rust.

Before:
```
wasm trap: unreachable
wasm backtrace:
     [...]
```

After:
```
wasm trap: wasm `unreachable` instruction executed
wasm backtrace:
     [...]
```
2021-11-29 15:55:10 -08:00
Nick Fitzgerald
b1a40646e3 Merge pull request #3553 from alexcrichton/ineg
aarch64: Migrate `ineg` to ISLE
2021-11-29 14:20:20 -08:00
Alex Crichton
868c40cde2 Add today's cranelift meeting notes (#3566) 2021-11-29 11:38:30 -06:00
Alex Crichton
fa63e7de5a aarch64: Migrate ineg to ISLE
Needed a new `vec_misc` instruction construction helper but otherwise a
pretty straightforward translation.
2021-11-29 08:03:17 -08:00
Scott McMurray
d55a19365e Add FunctionBuilder::emit_small_memory_compare
This takes an IntCC for the comparison to do, though panics for Signed*
since memcmp is an unsigned comparison.  Currently it's most useful for
(Not)Equal, but once big-endian loads are implemented it'll be able to
support the other Unsigned* comparisons nicely on more than just bytes.
2021-11-29 02:08:04 -08:00
Scott McMurray
c266f7f4c3 Cranelift: Add LibCall::Memcmp
The comment says the enum is "likely to grow" and the function's been in libc since C89, so hopefully this is ok.

I'd like to use it for emitting things like array equality.
2021-11-29 01:42:59 -08:00
Chris Fallin
d1e9a7840e Merge pull request #3561 from cfallin/aarch64-isle-rule-explicit-ordering
Update aarch64 backend's ISLE code to be rule-ordering-independent.
2021-11-24 11:57:52 -08:00
Chris Fallin
bc0de464bc Update aarch64 backend's ISLE code to be rule-ordering-independent.
In [this
comment](https://github.com/bytecodealliance/wasmtime/pull/3545#discussion_r756284757)
I noted a potential subtle issue with the way that a few rules were
written that is fine now but could cause some unexpected pain when we
get around to verification.

Specifically, a set of rules of the form

```
    (rule (A (B _)) (C))
    (rule (A _) (D))
```

should, under any reasonable "default" rule ordering scheme, fire the
more specific rule `(A (B _))` when applicable, in preference to the
second "fallback" rule.

However, for future verification-specific applications of ISLE, we want
to ensure the property that a rule's meaning/validity is not dependent
on being overridden by more specific rules. In other words, if a rule
specifies a rewrite, that rewrite should always be correct; and choosing
a more specific rule can give a *better* compilation (better generated
code) but should not be necessary for correctness.

This is an admittedly under-documented part of the language, though in the
pending #3560 I added a note about rule ordering being a heuristic that
should hopefully make this slightly clearer. Ultimately I want to have
tests that choose non-default rule orderings and differentially fuzz in
order to be sure that we're following this principle; and of course once
we're actually doing verification, we'll catch issues like this upfront.

Apologies for the subtle footgun here and hopefully the reasoning is
clear enough :-)
2021-11-24 11:08:47 -08:00
Benjamin Bouvier
9f6efe0e22 Bump regalloc in Cranelift (#3558)
This regalloc version contains a performance fix around creation of
very large logs that might be unused.
2021-11-23 09:09:31 -06:00
Alex Crichton
ec43254292 Enable nan canonicalization in differential fuzzing (#3557)
This fixes a fuzz issue discovered over the weekend where stores with
different values for nan canonicalization may produce different results.
This is expected, however, so the fix for differential execution is to
always enable nan canonicalization.
2021-11-22 12:21:26 -06:00
Johnnie Birch
9ecff69f47 Add agenda item for cranelift meeting on 11-29 2021-11-19 18:04:39 -08:00
Alex Crichton
e08bcd6aad Revert "Temporarily disable SIMD fuzzing on CI" (#3555)
This reverts commit 95e8723d0767556f0ddbc9151bce269464852bb1.
2021-11-19 14:33:11 -06:00
Nick Fitzgerald
21bce8071e Merge pull request #3554 from fitzgen/isle-iabs
ISLE: port `iabs` to ISLE for x64
2021-11-19 12:09:22 -08:00
Andrew Brown
994fe41daf x64: allow vector types in select move
As reported in #3173, the `select` instruction fails an assertion when it is given `v128` types as operands. This change relaxes the assertion to allow the same type of XMM move that occurs for the f32 and f64 types. This fixes #3173 in the old `lower.rs` code temporarily until the relatively complex `select` lowering can be ported to ISLE.
2021-11-19 11:24:30 -08:00
Nick Fitzgerald
94e0de45ed ISLE: port iabs to ISLE for x64 2021-11-19 11:03:44 -08:00
Alex Crichton
ef8ea644f4 aarch64: Migrate {s,u}{sub,add}_sat to ISLE (#3551)
These were pretty straightforward! Only needed a single `rule` per
instruction with a new 128-bit vector type matcher.
2021-11-19 12:59:06 -06:00
Nick Fitzgerald
f84b30bb59 Merge pull request #3545 from alexcrichton/arm64-iadd-isub-isle
aarch64: Migrate `iadd` and `isub` to ISLE
2021-11-19 10:08:19 -08:00
Chris Fallin
a947c89055 Merge pull request #3550 from alexcrichton/close-simd-fuzz
x64: Add test for a fixed issue
2021-11-19 09:19:12 -08:00
Alex Crichton
88e400b98c Make memory smaller 2021-11-19 08:44:22 -08:00
Alex Crichton
efa3468ff9 x64: Add test for a fixed issue
This commit adds a test from #3337 which is an issue that was fixed
in #3506 due to moving `imul` lowering rules to ISLE which fixed the
underlying issue of accidentally not falling through to the necessary
case for general `i64x2.mul` multiplication.

Closes #3337
2021-11-19 08:16:21 -08:00
Alex Crichton
cbf539abb8 Use with_flags for 128-bith arith in aarch64
Also move the `with_flags` bits and pieces to `prelude.isle` so it can
be shared between backends if necessary.
2021-11-19 07:08:08 -08:00
Alex Crichton
98ce029bbd Add commutative addition cases 2021-11-19 07:00:04 -08:00
Alex Crichton
7412461b7b Spelling 2021-11-19 06:53:31 -08:00
Alex Crichton
15d2542939 Rebuild ISLE 2021-11-19 06:52:01 -08:00
Alex Crichton
7d0f6ab90f aarch64: Migrate iadd and isub to ISLE
This commit is the first "meaty" instruction added to ISLE for the
AArch64 backend. I chose to pick the first two in the current lowering's
`match` statement, `isub` and `iadd`. These two turned out to be
particularly interesting for a few reasons:

* Both had clearly migratable-to-ISLE behavior along the lines of
  special-casing per type. For example 128-bit and vector arithmetic
  were both easily translateable.

* The `iadd` instruction has special cases for fusing with a
  multiplication to generate `madd` which is expressed pretty easily in
  ISLE.

* Otherwise both instructions had a number of forms where they attempted
  to interpret the RHS as various forms of constants, extends, or
  shifts. There's a bit of a design space of how best to represent this
  in ISLE and what I settled on was to have a special case for each form
  of instruction, and the special cases are somewhat duplicated between
  `iadd` and `isub`. There's custom "extractors" for the special cases
  and instructions that support these special cases will have an
  `rule`-per-case.

Overall I think the ISLE transitioned pretty well. I don't think that
the aarch64 backend is going to follow the x64 backend super closely,
though. For example the x64 backend is having a helper-per-instruction
at the moment but with AArch64 it seems to make more sense to only have
a helper-per-enum-variant-of-`MInst`. This is because the same
instruction (e.g. `ALUOp::Sub32`) can be expressed with multiple
different forms depending on the payload.

It's worth noting that the ISLE looks like it's a good deal larger than
the code actually being removed from lowering as part of this commit. I
think this is deceptive though because a lot of the logic in
`put_input_in_rse_imm12_maybe_negated` and `alu_inst_imm12` is being
inlined into the ISLE definitions for each instruction instead of having
it all packed into the helper functions. Some of the "boilerplate" here
is the addition of various ISLE utilities as well.
2021-11-19 06:51:38 -08:00
Alex Crichton
352ee2b186 Move insertlane to ISLE (#3544)
This also fixes a bug where `movsd` was incorrectly used with a memory
operand for `insertlane`, causing it to actually zero the upper bits
instead of preserving them.

Note that the insertlane logic still exists in `lower.rs` because it's
used as a helper for a few other instruction lowerings which aren't
migrated to ISLE yet. This commit also adds a helper in ISLE itself for
those other lowerings to use when they get implemented.

Closes #3216
2021-11-18 13:48:11 -06:00
bjorn3
4c75616a7c Remove unused constants from cranelift-codegen-shared (#3479) 2021-11-18 18:51:35 +01:00
Alex Crichton
1141169ff8 aarch64: Initial work to transition backend to ISLE (#3541)
* aarch64: Initial work to transition backend to ISLE

This commit is what is hoped to be the initial commit towards migrating
the aarch64 backend to ISLE. There's seemingly a lot of changes here but
it's intended to largely be code motion. The current thinking is to
closely follow the x64 backend for how all this is handled and
organized.

Major changes in this PR are:

* The `Inst` enum is now defined in ISLE. This avoids having to define
  it in two places (once in Rust and once in ISLE). I've preserved all
  the comments in the ISLE and otherwise this isn't actually a
  functional change from the Rust perspective, it's still the same enum
  according to Rust.

* Lots of little enums and things were moved to ISLE as well. As with
  `Inst` their definitions didn't change, only where they're defined.
  This will give future ISLE PRs access to all these operations.

* Initial code for lowering `iconst`, `null`, and `bconst` are
  implemented. Ironically none of this is actually used right now
  because constant lowering is handled in `put_input_in_regs` which
  specially handles constants. Nonetheless I wanted to get at least
  something simple working which shows off how to special case various
  things that are specific to AArch64. In a future PR I plan to hook up
  const-lowering in ISLE to this path so even though
  `iconst`-the-clif-instruction is never lowered this should use the
  const lowering defined in ISLE rather than elsewhere in the backend
  (eventually leading to the deletion of the non-ISLE lowering).

* The `IsleContext` skeleton is created and set up for future additions.

* Some code for ISLE that's shared across all backends now lives in
  `isle_prelude_methods!()` and is deduplicated between the AArch64
  backend and the x64 backend.

* Register mapping is tweaked to do the same thing for AArch64 that it
  does for x64. Namely mapping virtual registers is supported instead of
  just virtual to machine registers.

My main goal with this PR was to get AArch64 into a place where new
instructions can be added with relative ease. Additionally I'm hoping to
figure out as part of this change how much to share for ISLE between
AArch64 and x64 (and other backends).

* Don't use priorities with rules

* Update .gitattributes with concise syntax

* Deduplicate some type definitions

* Rebuild ISLE

* Move isa::isle to machinst::isle
2021-11-18 10:38:16 -06:00
Nick Fitzgerald
5bb1ea52c9 Merge pull request #3543 from fitzgen/remove-peepmatic
Remove Peepmatic!!!
2021-11-17 13:55:41 -08:00
Nick Fitzgerald
d2d0a0f36b Remove Peepmatic!!!
Peepmatic was an early attempt at a DSL for peephole optimizations, with the
idea that maybe sometime in the future we could user it for instruction
selection as well. It didn't really pan out, however:

* Peepmatic wasn't quite flexible enough, and adding new operators or snippets
  of code implemented externally in Rust was a bit of a pain.

* The performance was never competitive with the hand-written peephole
  optimizers. It was *very* size efficient, but that came at the cost of
  run-time efficiency. Everything was table-based and interpreted, rather than
  generating any Rust code.

Ultimately, because of these reasons, we never turned Peepmatic on by default.

These days, we just landed the ISLE domain-specific language, and it is better
suited than Peepmatic for all the things that Peepmatic was originally designed
to do. It is more flexible and easy to integrate with external Rust code. It is
has better time efficiency, meeting or even beating hand-written code. I think a
small part of the reason why ISLE excels in these things is because its design
was informed by Peepmatic's failures. I still plan on continuing Peepmatic's
mission to make Cranelift's peephole optimizer passes generated from DSL rewrite
rules, but using ISLE instead of Peepmatic.

Thank you Peepmatic, rest in peace!
2021-11-17 13:04:17 -08:00
Chris Fallin
dba74024aa Merge pull request #3534 from cfallin/isle-generated-code-manifest
ISLE: guard against stale generated source in default build config.
2021-11-16 15:59:52 -08:00
Chris Fallin
1697e32afa Let's try canonicalizing file paths in the manifest too... 2021-11-16 15:22:43 -08:00
Chris Fallin
bc56ab743c ISLE build-script check logic: Canonicalize All The Things!
writeln!() to a string on Windows to generate the expected manifest
needs newline-character canonicalization, too.
2021-11-16 15:11:56 -08:00
Chris Fallin
6a4716f0f4 Two CI fixes: Windows line-endings in manifest file, and "meta deterministic check".
- The Windows line-ending canonicalization was incomplete: we need to
  canonicalize the manifest text itself too!

- The "meta deterministic check" runs the cranelift-codegen build script
  N times outside of the source tree, examining what it produces to
  ensure the output is always the same (is detministic). This works fine
  when everything comes from the internal DSL, but when reading ISLE,
  this breaks because we no longer have the ISLE source paths.

  The initial ISLE integration did not hit this because without the
  `rebuild-isle` feature, it simply did nothing in the build script;
  now, with the manifest check, we hit the issue.

  The fix for now is just to turn off all ISLE-specific behavior in the
  build script by setting a special-purpose Cargo feature in the
  specific CI job. Eventually IMHO we should remove or find a better way
  to do this check.
2021-11-16 15:02:41 -08:00
Alex Crichton
f787ce433d aarch64: Remove manual sign extension in lowering (#3538)
Currently the lowering for `iconst` will sign-extend the payload value
of the `iconst` instruction itself, but the payload is already
sign-extended to this isn't necessary. This commit removes the redundant
sign extension.
2021-11-16 16:47:12 -06:00
Chris Fallin
a2b9664bed ISLE: guard against stale generated source in default build config.
Currently, the `build.rs` script that generates Rust source from the
ISLE DSL will only do this generation if the `rebuild-isle` Cargo
feature is specified. By default, it is not. This is based on the
principle that we (the build script) do not modify the source tree as
managed by git; git-managed files are strictly a human-managed and
human-edited resource. By adding the opt-in Cargo feature, a developer
is requesting the build script to perform an explicit action. (In my
understanding at least, this principle comes from the general philosophy
of hermetic builds: the output should be a pure function of the input,
and part of this is that the input is read-only. If we modify the source
tree, then all bets are off.)

Unfortunately, requiring the opt-in feature also creates a footgun that
is easy to hit: if a developer modifies the ISLE DSL source, but forgets
to specify the Cargo feature, then the compiler will silently be built
successfully with stale source, and will silently exclude any changes
that were made.

The generated source is checked into git for a good reason: we want DSL
compiler to not affect build times for the overwhelmingly common case
that Cranelift is used as a dependency but the backends are not being
actively developed. (This overhead comes mainly from building `islec`
itself.)

So, what to do? This PR implements a middle ground first described in
[this conversation](https://github.com/bytecodealliance/wasmtime/pull/3506#discussion_r743113351), in which we:

- Generate a hash (SHA-512) of the ISLE DSL source and produce a
  "manifest" of ISLE inputs alongside the generated source; and
- Always read the ISLE DSL source, and see if the manifest is still
  valid, on builds that do not have the opt-in "rebuild" feature.

This allows us to know whether the ISLE compiler output would have been
the same (modulo changes to the DSL compiler itself, which are
out-of-scope here), without actually building the ISLE compiler and
running it.

If the compiler-backend developer modifies an ISLE source file and then
tries to build `cranelift-codegen` without adding the `rebuild-isle`
Cargo feature, they get the following output:

```text
  Error: the ISLE source files that resulted in the generated Rust source

        * src/isa/x64/lower/isle/generated_code.rs

  have changed but the generated source was not rebuilt! These ISLE source
  files are:

         * src/clif.isle
         * src/prelude.isle
         * src/isa/x64/inst.isle
         * src/isa/x64/lower.isle

  Please add `--features rebuild-isle` to your `cargo build` command
  if you wish to rebuild the generated source, then include these changes
  in any git commits you make that include the changes to the ISLE.

  For example:

    $ cargo build -p cranelift-codegen --features rebuild-isle

  (This build script cannot do this for you by default because we cannot
  modify checked-into-git source without your explicit opt-in.)
```

which will tell them exactly what they need to do to fix the problem!

Note that I am leaving the "Rebuild ISLE" CI job alone for now, because
otherwise, we are trusting whomever submits a PR to generate the correct
generated source. In other words, the manifest is a communication from
the checked-in tree to the developer, but we still need to verify that
the checked-in generated Rust source and the manifest are correct with
respect to the checked-in ISLE source.
2021-11-16 13:50:41 -08:00
Alex Crichton
f30c8eb464 isle: Migrate f32const/f64const to ISLE (#3537)
This moves the `f32const` and `f64const` instructions from `lower.rs` to
ISLE. I was originally going to add something else but due to the
`isle.rs`'s manual use of `constructor_imm(..)` it necessitated filling
out the `imm` cases for f32/f64 constants, so I figured I'd go ahead and
move these instructions as well.

The special case for 0 constants which use `xorp{s,d}` is preserved from
`lower.rs` today, but a special case isn't added for the all-ones
constant. The comment says to use `cmpeqp{s,d}` but as discovered on
other recent PRs that's not quite sufficient because comparing a
register against itself which happens to be NaN wouldn't work, so
something else will be required (perhaps `pcmpeq` or similar? I figured
I'd defer to later)
2021-11-16 14:19:53 -06:00
Nick Fitzgerald
306c96b461 Merge pull request #3536 from alexcrichton/swap-isle-order
isle: Move immediates to the end of extractors
2021-11-16 10:13:17 -08:00
Nick Fitzgerald
e0943b8030 Merge pull request #3535 from alexcrichton/small-isle-patches
x64: Migrate `fabs` and `bnot` vector operations to ISLE
2021-11-16 10:01:49 -08:00
Alex Crichton
1c13f62189 isle: Move immediates to the end of extractors
Otherwise I was getting type errors trying to match `insertlane`
instructions, so I think that this was the intended order.
2021-11-16 09:07:24 -08:00
Alex Crichton
92394566fc x64: Migrate fabs and bnot vector operations to ISLE
This was my first attempt at transitioning code to ISLE to originally
fix #3327 but that fix has since landed on `main`, so this is instead
now just porting a few operations to ISLE.

Closes #3336
2021-11-16 07:36:49 -08:00
Johnnie Birch
5d5629de60 Fix for issue 3327. Updates Bnot to handle case for NaN float 2021-11-15 18:47:23 -08:00
Nick Fitzgerald
b530d283e4 Merge pull request #3533 from fitzgen/isle-labeling
ISLE auto labeling
2021-11-15 17:13:27 -08:00
Nick Fitzgerald
e6fd306219 Subscribe @cfallin to issues labeled "isle" 2021-11-15 16:20:16 -08:00
Nick Fitzgerald
ff659f0098 Subscribe myself to issues labeled "isle" 2021-11-15 16:19:49 -08:00
Nick Fitzgerald
373ea93564 Remove lightbeam auto labeling
Lightbeam doesn't exist anymore.
2021-11-15 16:18:11 -08:00
Nick Fitzgerald
8e9ddca5cb Add auto labeling for ISLE-related changes 2021-11-15 16:18:02 -08:00
Nick Fitzgerald
b38a96955c Merge pull request #3506 from fitzgen/isle
Initial ISLE integration for x64
2021-11-15 15:38:09 -08:00