Repository: bytecodealliance/wasmtime
Pull request #8627 (2024-05-15 17:16:51)

Use WASM function names in compiled objects
Instead of generating symbol names in the format
"wasm[$MODULE_ID]::function[$FUNCTION_INDEX]", generate (if possible) something more readable, such as "wasm[$MODULE_ID]::$FUNCTION_NAME". This helps when debugging or profiling the generated code.


bjorn3: Is it guaranteed that the names section only contains unique names?
alexcrichton: Thanks! This makes sense to me and I've often thought this would be nice as well. A hesitation I've had in the past though is that I'm a bit wary about exposing user-provided data to native tools like `perf` and `objdump` and such. The name section has completely arbitrary strings and I while I can't say for certainty that native tooling behaves well in the face of arbitrary strings I suspect that there might be a security issue waiting to happen along the lines of "if you run `ldd` over a binary it can run arbitrary code" or something like that.

(a good example being @bjorn3's suggestion where the `name` section has no guarantees of uniqueness and I'm not sure what tooling would do with same-named-symbols)
cfallin: I wonder if we could define suitable "cleanup" for names: (i) rewrite duplicates with numeric suffixes, (ii) replace or remove any characters not in the usual set (`[A-Za-z0-9-_]` -- maybe spaces too? can tools handle those?), (iii) cap the length at something reasonable like 32 or 64 characters?
lpereira: Could also add the function_index for the cases where uniqueness isn't guaranteed.  Alright, I'll cook up a patch with the suggestions.
alexcrichton: Yeah I think that'd work well (albeit bit a bit more involved in the implementation). While I can't say for certainty that spaces are not supported my guess is that tools would likely eventually choke on non-C-looking symbols so I'd be tempted to leave them out. 
fitzgen: How about

* `wasm[N]::func[M]` if no name section entry
* `wasm[N]::func[m]: <name>` where `<name>` is sanitized and has a capped length if there is an entry

?
lpereira: Alright, pushed some changes that:

- Will filter symbols to only include alphanumeric characters and others that might be generated by name mangling and whatnot, and replace runs of them with a single '?'
- Always include the function index in the symbol name
- Truncate the symbol name to 96 characters

I think this should be sufficient, although I'm not really sold on how good the string filtering code is. I wish there was a `String::translate()` that would work similarly to `String::retain()`, but replace the character with what the callback function returns.  I'm a newbie in Rust, though, so maybe there's a way I couldn't figure out? 
cfallin: Ah, force-pushed after my review; could you do subsequent updates as additional commits? Let me know when stable and I can re-review.

Patch:
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index d5c1801a7..df6b167cd 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -299,12 +299,67 @@ jobs:
       env:
         GH_TOKEN: ${{ github.token }}
 
-  # Checks of various feature combinations and whether things
-  # compile. The goal here isn't to run tests, mostly just serve as a
-  # double-check that Rust code compiles and is likely to work everywhere else.
-  checks:
+  # Checks of various feature combinations and whether things compile. The goal
+  # here isn't to run tests, mostly just serve as a double-check that Rust code
+  # compiles and is likely to work everywhere else.
+  micro_checks:
     needs: determine
-    name: Check
+    name: Check ${{matrix.name}}
+    strategy:
+      fail-fast: true
+      matrix:
+        include:
+          - name: wasmtime
+            checks: |
+              -p wasmtime --no-default-features
+              -p wasmtime --no-default-features --features wat
+              -p wasmtime --no-default-features --features profiling
+              -p wasmtime --no-default-features --features cache
+              -p wasmtime --no-default-features --features async
+              -p wasmtime --no-default-features --features pooling-allocator
+              -p wasmtime --no-default-features --features cranelift
+              -p wasmtime --no-default-features --features component-model
+              -p wasmtime --no-default-features --features runtime,component-model
+              -p wasmtime --no-default-features --features cranelift,wat,async,cache
+              -p wasmtime --no-default-features --features winch
+              -p wasmtime --no-default-features --features wmemcheck
+              -p wasmtime --no-default-features --features wmemcheck,cranelift,runtime
+              -p wasmtime --no-default-features --features demangle
+              -p wasmtime --no-default-features --features addr2line
+              -p wasmtime --no-default-features --features gc
+              -p wasmtime --no-default-features --features runtime,gc
+              -p wasmtime --no-default-features --features cranelift,gc
+              -p wasmtime --no-default-features --features runtime
+              -p wasmtime --no-default-features --features threads
+              -p wasmtime --no-default-features --features runtime,threads
+              -p wasmtime --no-default-features --features cranelift,threads
+              -p wasmtime --features incremental-cache
+              -p wasmtime --all-features
+
+          - name: wasmtime-cli
+            checks: |
+              -p wasmtime-cli --no-default-features
+              -p wasmtime-cli --no-default-features --features run
+              -p wasmtime-cli --no-default-features --features run,component-model
+              -p wasmtime-cli --no-default-features --features compile
+              -p wasmtime-cli --no-default-features --features compile,cranelift
+              -p wasmtime-cli --no-default-features --features compile,cranelift,component-model
+              -p wasmtime-cli --all-features
+              -p wasmtime-cli --features component-model
+
+          - name: cranelift-codegen benches
+            checks: |
+              --benches -p cranelift-codegen
+
+          - name: wasmtime-bench-api
+            checks: |
+              -p wasmtime-bench-api
+
+          - name: wasmtime-c-api
+            checks: |
+              -p wasmtime-c-api --no-default-features
+              -p wasmtime-c-api --no-default-features --features wat
+              -p wasmtime-c-api --no-default-features --features wasi
     runs-on: ubuntu-latest
     steps:
     - uses: actions/checkout@v4
@@ -312,52 +367,34 @@ jobs:
         submodules: true
     - uses: ./.github/actions/install-rust
 
-    # Check some feature combinations of the `wasmtime` crate
-    - run: cargo check -p wasmtime --no-default-features
-    - run: cargo check -p wasmtime --no-default-features --features wat
-    - run: cargo check -p wasmtime --no-default-features --features profiling
-    - run: cargo check -p wasmtime --no-default-features --features cache
-    - run: cargo check -p wasmtime --no-default-features --features async
-    - run: cargo check -p wasmtime --no-default-features --features pooling-allocator
-    - run: cargo check -p wasmtime --no-default-features --features cranelift
-    - run: cargo check -p wasmtime --no-default-features --features component-model
-    - run: cargo check -p wasmtime --no-default-features --features runtime,component-model
-    - run: cargo check -p wasmtime --no-default-features --features cranelift,wat,async,cache
-    - run: cargo check -p wasmtime --no-default-features --features winch
-    - run: cargo check -p wasmtime --no-default-features --features wmemcheck
-    - run: cargo check -p wasmtime --no-default-features --features wmemcheck,cranelift,runtime
-    - run: cargo check -p wasmtime --no-default-features --features demangle
-    - run: cargo check -p wasmtime --no-default-features --features addr2line
-    - run: cargo check -p wasmtime --no-default-features --features gc
-    - run: cargo check -p wasmtime --no-default-features --features runtime,gc
-    - run: cargo check -p wasmtime --no-default-features --features cranelift,gc
-    - run: cargo check -p wasmtime --no-default-features --features runtime
-    - run: cargo check -p wasmtime --no-default-features --features threads
-    - run: cargo check -p wasmtime --no-default-features --features runtime,threads
-    - run: cargo check -p wasmtime --no-default-features --features cranelift,threads
-    - run: cargo check --features component-model
-    - run: cargo check -p wasmtime --features incremental-cache
-    - run: cargo check -p wasmtime --all-features
-
-    # Feature combinations of the `wasmtime-cli`
-    - run: cargo check -p wasmtime-cli --no-default-features
-    - run: cargo check -p wasmtime-cli --no-default-features --features run
-    - run: cargo check -p wasmtime-cli --no-default-features --features run,component-model
-    - run: cargo check -p wasmtime-cli --no-default-features --features compile
-    - run: cargo check -p wasmtime-cli --no-default-features --features compile,cranelift
-    - run: cargo check -p wasmtime-cli --no-default-features --features compile,cranelift,component-model
-    - run: cargo check -p wasmtime-cli --all-features
-
-    # Check that benchmarks of the cranelift project build
-    - run: cargo check --benches -p cranelift-codegen
-
-    # Check that the bench-api compiles
-    - run: cargo check -p wasmtime-bench-api
-
-    # Check some feature combinations of the `wasmtime-c-api` crate
-    - run: cargo check -p wasmtime-c-api --no-default-features
-    - run: cargo check -p wasmtime-c-api --no-default-features --features wat
-    - run: cargo check -p wasmtime-c-api --no-default-features --features wasi
+    # Run the check.
+    - run: |
+        checks=$(cat <<END
+        ${{ matrix.checks }}
+        END
+        )
+        echo "$checks" | xargs -I CHECK sh -c 'echo "=== cargo check CHECK ==="; cargo check CHECK'
+
+    # Common logic to cancel the entire run if this job fails.
+    - run: gh run cancel ${{ github.run_id }}
+      if: failure() && github.event_name != 'pull_request'
+      env:
+        GH_TOKEN: ${{ github.token }}
+
+  # Similar to `micro_checks` but where we need to install some more state
+  # (e.g. Android NDK) and we haven't factored support for those things out into
+  # a parallel jobs yet.
+  monolith_checks:
+    needs: determine
+    name: Monolith Checks
+    runs-on: ubuntu-latest
+    env:
+      CARGO_NDK_VERSION: 2.12.2
+    steps:
+    - uses: actions/checkout@v4
+      with:
+        submodules: true
+    - uses: ./.github/actions/install-rust
 
     # Checks for no_std support, ensure that crates can build on a no_std
     # target
@@ -523,10 +560,6 @@ jobs:
     - run: echo CARGO_BUILD_TARGET=${{ matrix.target }} >> $GITHUB_ENV
       if: matrix.target != ''
 
-    # Install OpenVINO for testing wasmtime-wasi-nn.
-    - uses: abrown/install-openvino-action@v8
-      if: runner.arch == 'X64'
-
     # Fix an ICE for now in gcc when compiling zstd with debuginfo (??)
     - run: echo CFLAGS=-g0 >> $GITHUB_ENV
       if: matrix.target == 'x86_64-pc-windows-gnu'
@@ -608,7 +641,7 @@ jobs:
         fi
 
     # Build and test all features
-    - run: ./ci/run-tests.sh ${{ matrix.extra_features }} --locked
+    - run: ./ci/run-tests.sh --locked ${{ matrix.bucket }}
       env:
         RUST_BACKTRACE: 1
 
@@ -617,6 +650,67 @@ jobs:
     # Windows fails GitHub Actions will confusingly mark the failed Windows job
     # as cancelled instead of failed.
 
+  # Test `wasmtime-wasi-nn` in its own job, as not all of its backends are
+  # compatible with all targets, and each must be tested separately anyways.
+  test_wasi_nn:
+    strategy:
+      matrix:
+        feature: ["openvino", "onnx"]
+        os: ["ubuntu-latest", "windows-latest"]
+    name: Test wasi-nn (${{ matrix.feature }}, ${{ matrix.os }})
+    runs-on: ${{ matrix.os }}
+    needs: determine
+    if: needs.determine.outputs.run-full
+    steps:
+    - uses: actions/checkout@v4
+      with:
+        submodules: true
+    - uses: ./.github/actions/install-rust
+
+    # Install OpenVINO
+    - uses: abrown/install-openvino-action@v8
+      if: runner.arch == 'X64'
+
+    # Install Rust targets.
+    - run: rustup target add wasm32-wasi
+
+    # Run the tests!
+    - run: cargo test -p wasmtime-wasi-nn --features ${{ matrix.feature }}
+      env:
+        RUST_BACKTRACE: 1
+
+    # common logic to cancel the entire run if this job fails
+    - run: gh run cancel ${{ github.run_id }}
+      if: failure() && github.event_name != 'pull_request'
+      env:
+        GH_TOKEN: ${{ github.token }}
+
+  # Test the `wasmtime-fuzzing` crate. Split out from the main tests because
+  # `--all-features` brings in OCaml, which is a pain to get setup for all
+  # targets.
+  test_fuzzing:
+    needs: determine
+    if: needs.determine.outputs.run-full
+    name: Test wasmtime-fuzzing
+    runs-on: 'ubuntu-latest'
+    steps:
+    - uses: actions/checkout@v4
+      with:
+        submodules: true
+    - uses: ./.github/actions/install-rust
+
+    # Run the tests
+    - run: |
+        cargo test -p wasmtime-fuzzing -p wasm-spec-interpreter
+      env:
+        RUST_BACKTRACE: 1
+
+    # common logic to cancel the entire run if this job fails
+    - run: gh run cancel ${{ github.run_id }}
+      if: failure() && github.event_name != 'pull_request'
+      env:
+        GH_TOKEN: ${{ github.token }}
+
   # Test debug (DWARF) related functionality.
   test_debug_dwarf:
     needs: determine
@@ -811,6 +905,9 @@ jobs:
   # Note that `cargo nextest` is used here additionally to get parallel test
   # execution by default to help cut down on the time in CI.
   miri:
+    strategy:
+      matrix:
+        crate: ["wasmtime", "wasmtime-cli", "wasmtime-environ"]
     needs: determine
     if: needs.determine.outputs.run-full && github.repository == 'bytecodealliance/wasmtime'
     name: Miri
@@ -832,10 +929,7 @@ jobs:
     - run: echo "${{ runner.tool_cache }}/cargo-nextest/bin" >> $GITHUB_PATH
     - run: cargo install --root ${{ runner.tool_cache }}/cargo-nextest --version ${{ env.CARGO_NEXTEST_VERSION }} cargo-nextest --locked
     - run: |
-        cargo miri nextest run -j4 --no-fail-fast \
-          -p wasmtime \
-          -p wasmtime-cli \
-          -p wasmtime-environ
+        cargo miri nextest run -j4 --no-fail-fast -p ${{ matrix.crate }}
       env:
         MIRIFLAGS: -Zmiri-strict-provenance
 
@@ -924,15 +1018,18 @@ jobs:
       - test
       - test_capi
       - test_debug_dwarf
+      - test_fuzzing
+      - test_wasi_nn
+      - test_nightly
       - build
       - rustfmt
       - clangformat
       - cargo_deny
       - cargo_vet
       - doc
-      - checks
+      - micro_checks
+      - monolith_checks
       - checks_winarm64
-      - test_nightly
       - bench
       - meta_deterministic_check
       - verify-publish
diff --git a/cranelift/codegen/src/ir/stackslot.rs b/cranelift/codegen/src/ir/stackslot.rs
index dfe0109e9..d906fb291 100644
--- a/cranelift/codegen/src/ir/stackslot.rs
+++ b/cranelift/codegen/src/ir/stackslot.rs
@@ -70,32 +70,38 @@ pub struct StackSlotData {
 
     /// Size of stack slot in bytes.
     pub size: StackSize,
+
+    /// Alignment of stack slot as a power-of-two exponent (log2
+    /// value). The stack slot will be at least this aligned; it may
+    /// be aligned according to other considerations, such as minimum
+    /// stack slot size or machine word size, as well.
+    pub align_shift: u8,
 }
 
 impl StackSlotData {
-    /// Create a stack slot with the specified byte size.
-    pub fn new(kind: StackSlotKind, size: StackSize) -> Self {
-        Self { kind, size }
-    }
-
-    /// Get the alignment in bytes of this stack slot given the stack pointer alignment.
-    pub fn alignment(&self, max_align: StackSize) -> StackSize {
-        debug_assert!(max_align.is_power_of_two());
-        if self.kind == StackSlotKind::ExplicitDynamicSlot {
-            max_align
-        } else {
-            // We want to find the largest power of two that divides both `self.size` and `max_align`.
-            // That is the same as isolating the rightmost bit in `x`.
-            let x = self.size | max_align;
-            // C.f. Hacker's delight.
-            x & x.wrapping_neg()
+    /// Create a stack slot with the specified byte size and alignment.
+    pub fn new(kind: StackSlotKind, size: StackSize, align_shift: u8) -> Self {
+        Self {
+            kind,
+            size,
+            align_shift,
         }
     }
 }
 
 impl fmt::Display for StackSlotData {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{} {}", self.kind, self.size)
+        if self.align_shift != 0 {
+            write!(
+                f,
+                "{} {}, align = {}",
+                self.kind,
+                self.size,
+                1u32 << self.align_shift
+            )
+        } else {
+            write!(f, "{} {}", self.kind, self.size)
+        }
     }
 }
 
@@ -146,8 +152,10 @@ mod tests {
     fn stack_slot() {
         let mut func = Function::new();
 
-        let ss0 = func.create_sized_stack_slot(StackSlotData::new(StackSlotKind::ExplicitSlot, 4));
-        let ss1 = func.create_sized_stack_slot(StackSlotData::new(StackSlotKind::ExplicitSlot, 8));
+        let ss0 =
+            func.create_sized_stack_slot(StackSlotData::new(StackSlotKind::ExplicitSlot, 4, 0));
+        let ss1 =
+            func.create_sized_stack_slot(StackSlotData::new(StackSlotKind::ExplicitSlot, 8, 0));
         assert_eq!(ss0.to_string(), "ss0");
         assert_eq!(ss1.to_string(), "ss1");
 
@@ -197,20 +205,4 @@ mod tests {
             "explicit_dynamic_slot dt1"
         );
     }
-
-    #[test]
-    fn alignment() {
-        let slot = StackSlotData::new(StackSlotKind::ExplicitSlot, 8);
-
-        assert_eq!(slot.alignment(4), 4);
-        assert_eq!(slot.alignment(8), 8);
-        assert_eq!(slot.alignment(16), 8);
-
-        let slot2 = StackSlotData::new(StackSlotKind::ExplicitSlot, 24);
-
-        assert_eq!(slot2.alignment(4), 4);
-        assert_eq!(slot2.alignment(8), 8);
-        assert_eq!(slot2.alignment(16), 8);
-        assert_eq!(slot2.alignment(32), 8);
-    }
 }
diff --git a/cranelift/codegen/src/isa/aarch64/inst/unwind/systemv.rs b/cranelift/codegen/src/isa/aarch64/inst/unwind/systemv.rs
index a22b9e787..da31d7d80 100644
--- a/cranelift/codegen/src/isa/aarch64/inst/unwind/systemv.rs
+++ b/cranelift/codegen/src/isa/aarch64/inst/unwind/systemv.rs
@@ -85,7 +85,7 @@ mod tests {
 
         let mut context = Context::for_function(create_function(
             CallConv::SystemV,
-            Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64)),
+            Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64, 0)),
         ));
 
         let code = context
diff --git a/cranelift/codegen/src/isa/riscv64/inst/unwind/systemv.rs b/cranelift/codegen/src/isa/riscv64/inst/unwind/systemv.rs
index 971201b85..b0260ceef 100644
--- a/cranelift/codegen/src/isa/riscv64/inst/unwind/systemv.rs
+++ b/cranelift/codegen/src/isa/riscv64/inst/unwind/systemv.rs
@@ -80,7 +80,7 @@ mod tests {
 
         let mut context = Context::for_function(create_function(
             CallConv::SystemV,
-            Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64)),
+            Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64, 0)),
         ));
 
         let code = context
diff --git a/cranelift/codegen/src/isa/riscv64/lower/isle.rs b/cranelift/codegen/src/isa/riscv64/lower/isle.rs
index f55ecd958..77299882a 100644
--- a/cranelift/codegen/src/isa/riscv64/lower/isle.rs
+++ b/cranelift/codegen/src/isa/riscv64/lower/isle.rs
@@ -18,7 +18,7 @@ use crate::machinst::{VCodeConstant, VCodeConstantData};
 use crate::{
     ir::{
         immediates::*, types::*, AtomicRmwOp, BlockCall, ExternalName, Inst, InstructionData,
-        MemFlags, Opcode, StackSlot, TrapCode, Value, ValueList,
+        MemFlags, Opcode, TrapCode, Value, ValueList,
     },
     isa::riscv64::inst::*,
     machinst::{ArgPair, InstOutput},
diff --git a/cranelift/codegen/src/isa/s390x/inst/unwind/systemv.rs b/cranelift/codegen/src/isa/s390x/inst/unwind/systemv.rs
index de287d87d..9be66c14f 100644
--- a/cranelift/codegen/src/isa/s390x/inst/unwind/systemv.rs
+++ b/cranelift/codegen/src/isa/s390x/inst/unwind/systemv.rs
@@ -116,7 +116,7 @@ mod tests {
 
         let mut context = Context::for_function(create_function(
             CallConv::SystemV,
-            Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64)),
+            Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64, 0)),
         ));
 
         let code = context
@@ -160,7 +160,7 @@ mod tests {
 
         let mut context = Context::for_function(create_multi_return_function(
             CallConv::SystemV,
-            Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64)),
+            Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64, 0)),
         ));
 
         let code = context
diff --git a/cranelift/codegen/src/isa/x64/inst/unwind/systemv.rs b/cranelift/codegen/src/isa/x64/inst/unwind/systemv.rs
index 25d723751..576cc060c 100644
--- a/cranelift/codegen/src/isa/x64/inst/unwind/systemv.rs
+++ b/cranelift/codegen/src/isa/x64/inst/unwind/systemv.rs
@@ -112,7 +112,7 @@ mod tests {
 
         let mut context = Context::for_function(create_function(
             CallConv::SystemV,
-            Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64)),
+            Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64, 0)),
         ));
 
         let code = context
diff --git a/cranelift/codegen/src/isle_prelude.rs b/cranelift/codegen/src/isle_prelude.rs
index 39bc55027..424531d64 100644
--- a/cranelift/codegen/src/isle_prelude.rs
+++ b/cranelift/codegen/src/isle_prelude.rs
@@ -953,5 +953,29 @@ macro_rules! isle_common_prelude_methods {
                 None
             }
         }
+
+        fn f32_neg(&mut self, n: Ieee32) -> Ieee32 {
+            n.neg()
+        }
+
+        fn f32_abs(&mut self, n: Ieee32) -> Ieee32 {
+            n.abs()
+        }
+
+        fn f32_copysign(&mut self, a: Ieee32, b: Ieee32) -> Ieee32 {
+            a.copysign(b)
+        }
+
+        fn f64_neg(&mut self, n: Ieee64) -> Ieee64 {
+            n.neg()
+        }
+
+        fn f64_abs(&mut self, n: Ieee64) -> Ieee64 {
+            n.abs()
+        }
+
+        fn f64_copysign(&mut self, a: Ieee64, b: Ieee64) -> Ieee64 {
+            a.copysign(b)
+        }
     };
 }
diff --git a/cranelift/codegen/src/machinst/abi.rs b/cranelift/codegen/src/machinst/abi.rs
index 1edec7269..ccdbc2910 100644
--- a/cranelift/codegen/src/machinst/abi.rs
+++ b/cranelift/codegen/src/machinst/abi.rs
@@ -1178,7 +1178,11 @@ impl<M: ABIMachineSpec> Callee<M> {
             sized_stack_offset = sized_stack_offset
                 .checked_add(data.size)
                 .ok_or(CodegenError::ImplLimitExceeded)?;
-            let mask = M::word_bytes() - 1;
+            // Always at least machine-word-align slots, but also
+            // satisfy the user's requested alignment.
+            debug_assert!(data.align_shift < 32);
+            let align = std::cmp::max(M::word_bytes(), 1u32 << data.align_shift);
+            let mask = align - 1;
             sized_stack_offset = checked_round_up(sized_stack_offset, mask)
                 .ok_or(CodegenError::ImplLimitExceeded)?;
             debug_assert_eq!(stackslot.as_u32() as usize, sized_stackslots.len());
@@ -1938,12 +1942,13 @@ impl<M: ABIMachineSpec> Callee<M> {
         frame_layout.clobber_size + frame_layout.fixed_frame_storage_size
     }
 
-    /// Returns offset from the nominal SP to caller's SP.
-    pub fn nominal_sp_to_caller_sp_offset(&self) -> u32 {
+    /// Returns offset from the SP to caller's SP.
+    pub fn sp_to_caller_sp_offset(&self) -> u32 {
         let frame_layout = self.frame_layout();
         frame_layout.clobber_size
             + frame_layout.fixed_frame_storage_size
             + frame_layout.setup_area_size
+            + frame_layout.outgoing_args_size
     }
 
     /// Returns the size of arguments expected on the stack.
diff --git a/cranelift/codegen/src/machinst/vcode.rs b/cranelift/codegen/src/machinst/vcode.rs
index 6e9318912..112f643c7 100644
--- a/cranelift/codegen/src/machinst/vcode.rs
+++ b/cranelift/codegen/src/machinst/vcode.rs
@@ -1138,7 +1138,7 @@ impl<I: VCodeInst> VCode<I> {
             } else {
                 let slot = alloc.as_stack().unwrap();
                 let sp_offset = self.abi.get_spillslot_offset(slot);
-                let sp_to_caller_sp_offset = self.abi.nominal_sp_to_caller_sp_offset();
+                let sp_to_caller_sp_offset = self.abi.sp_to_caller_sp_offset();
                 let caller_sp_to_cfa_offset =
                     crate::isa::unwind::systemv::caller_sp_to_cfa_offset();
                 let cfa_to_sp_offset = -((sp_to_caller_sp_offset + caller_sp_to_cfa_offset) as i64);
diff --git a/cranelift/codegen/src/opts/cprop.isle b/cranelift/codegen/src/opts/cprop.isle
index 8c86ff2c5..d6b56543b 100644
--- a/cranelift/codegen/src/opts/cprop.isle
+++ b/cranelift/codegen/src/opts/cprop.isle
@@ -279,3 +279,19 @@
 (extern constructor u64_bswap32 u64_bswap32)
 (decl pure u64_bswap64 (u64) u64)
 (extern constructor u64_bswap64 u64_bswap64)
+
+;; Constant fold bitwise float operations (fneg/fabs/fcopysign)
+(rule (simplify (fneg $F32 (f32const $F32 n)))
+      (subsume (f32const $F32 (f32_neg n))))
+(rule (simplify (fneg $F64 (f64const $F64 n)))
+      (subsume (f64const $F64 (f64_neg n))))
+
+(rule (simplify (fabs $F32 (f32const $F32 n)))
+      (subsume (f32const $F32 (f32_abs n))))
+(rule (simplify (fabs $F64 (f64const $F64 n)))
+      (subsume (f64const $F64 (f64_abs n))))
+
+(rule (simplify (fcopysign $F32 (f32const $F32 n) (f32const $F32 m)))
+      (subsume (f32const $F32 (f32_copysign n m))))
+(rule (simplify (fcopysign $F64 (f64const $F64 n) (f64const $F64 m)))
+      (subsume (f64const $F64 (f64_copysign n m))))
diff --git a/cranelift/codegen/src/prelude.isle b/cranelift/codegen/src/prelude.isle
index e7517fc41..1df50f950 100644
--- a/cranelift/codegen/src/prelude.isle
+++ b/cranelift/codegen/src/prelude.isle
@@ -234,6 +234,21 @@
 (decl u16_replicated_u8 (u8) u64)
 (extern extractor u16_replicated_u8 u16_replicated_u8)
 
+;; Floating point operations
+
+(decl pure f32_neg (Ieee32) Ieee32)
+(extern constructor f32_neg f32_neg)
+(decl pure f32_abs (Ieee32) Ieee32)
+(extern constructor f32_abs f32_abs)
+(decl pure f32_copysign (Ieee32 Ieee32) Ieee32)
+(extern constructor f32_copysign f32_copysign)
+(decl pure f64_neg (Ieee64) Ieee64)
+(extern constructor f64_neg f64_neg)
+(decl pure f64_abs (Ieee64) Ieee64)
+(extern constructor f64_abs f64_abs)
+(decl pure f64_copysign (Ieee64 Ieee64) Ieee64)
+(extern constructor f64_copysign f64_copysign)
+
 ;;;; `cranelift_codegen::ir::Type` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (extern const $I8 Type)
diff --git a/cranelift/codegen/src/write.rs b/cranelift/codegen/src/write.rs
index 190e1c20e..e80081625 100644
--- a/cranelift/codegen/src/write.rs
+++ b/cranelift/codegen/src/write.rs
@@ -535,7 +535,7 @@ mod tests {
         f.name = UserFuncName::testcase("foo");
         assert_eq!(f.to_string(), "function %foo() fast {\n}\n");
 
-        f.create_sized_stack_slot(StackSlotData::new(StackSlotKind::ExplicitSlot, 4));
+        f.create_sized_stack_slot(StackSlotData::new(StackSlotKind::ExplicitSlot, 4, 0));
         assert_eq!(
             f.to_string(),
             "function %foo() fast {\n    ss0 = explicit_slot 4\n}\n"
@@ -569,6 +569,13 @@ mod tests {
             f.to_string(),
             "function %foo() fast {\n    ss0 = explicit_slot 4\n\nblock0(v0: i8, v1: f32x4):\n    return\n}\n"
         );
+
+        let mut f = Function::new();
+        f.create_sized_stack_slot(StackSlotData::new(StackSlotKind::ExplicitSlot, 4, 2));
+        assert_eq!(
+            f.to_string(),
+            "function u0:0() fast {\n    ss0 = explicit_slot 4, align = 4\n}\n"
+        );
     }
 
     #[test]
diff --git a/cranelift/fuzzgen/src/function_generator.rs b/cranelift/fuzzgen/src/function_generator.rs
index 4e2506bdb..182336dfd 100644
--- a/cranelift/fuzzgen/src/function_generator.rs
+++ b/cranelift/fuzzgen/src/function_generator.rs
@@ -1605,7 +1605,7 @@ where
     fn generate_stack_slots(&mut self, builder: &mut FunctionBuilder) -> Result<()> {
         for _ in 0..self.param(&self.config.static_stack_slots_per_function)? {
             let bytes = self.param(&self.config.static_stack_slot_size)? as u32;
-            let ss_data = StackSlotData::new(StackSlotKind::ExplicitSlot, bytes);
+            let ss_data = StackSlotData::new(StackSlotKind::ExplicitSlot, bytes, 0);
             let slot = builder.create_sized_stack_slot(ss_data);
 
             // Generate one Alias Analysis Category for each slot
diff --git a/cranelift/reader/src/parser.rs b/cranelift/reader/src/parser.rs
index 0dc9289ef..9e176ccf9 100644
--- a/cranelift/reader/src/parser.rs
+++ b/cranelift/reader/src/parser.rs
@@ -245,8 +245,11 @@ impl Context {
     fn add_ss(&mut self, ss: StackSlot, data: StackSlotData, loc: Location) -> ParseResult<()> {
         self.map.def_ss(ss, loc)?;
         while self.function.sized_stack_slots.next_key().index() <= ss.index() {
-            self.function
-                .create_sized_stack_slot(StackSlotData::new(StackSlotKind::ExplicitSlot, 0));
+            self.function.create_sized_stack_slot(StackSlotData::new(
+                StackSlotKind::ExplicitSlot,
+                0,
+                0,
+            ));
         }
         self.function.sized_stack_slots[ss] = data;
         Ok(())
@@ -1483,6 +1486,7 @@ impl<'a> Parser<'a> {
     //                   | "spill_slot"
     //                   | "incoming_arg"
     //                   | "outgoing_arg"
+    // stack-slot-flag ::= "align" "=" Bytes
     fn parse_stack_slot_decl(&mut self) -> ParseResult<(StackSlot, StackSlotData)> {
         let ss = self.match_ss("expected stack slot number: ss«n»")?;
         self.match_token(Token::Equal, "expected '=' in stack slot declaration")?;
@@ -1498,7 +1502,30 @@ impl<'a> Parser<'a> {
         if bytes > i64::from(u32::MAX) {
             return err!(self.loc, "stack slot too large");
         }
-        let data = StackSlotData::new(kind, bytes as u32);
+
+        // Parse flags.
+        let align = if self.token() == Some(Token::Comma) {
+            self.consume();
+            self.match_token(
+                Token::Identifier("align"),
+                "expected a valid stack-slot flag (currently only `align`)",
+            )?;
+            self.match_token(Token::Equal, "expected `=` after flag")?;
+            let align: i64 = self
+                .match_imm64("expected alignment-size after `align` flag")?
+                .into();
+            u32::try_from(align)
+                .map_err(|_| self.error("alignment must be a 32-bit unsigned integer"))?
+        } else {
+            1
+        };
+
+        if !align.is_power_of_two() {
+            return err!(self.loc, "stack slot alignment is not a power of two");
+        }
+        let align_shift = u8::try_from(align.ilog2()).unwrap(); // Always succeeds: range 0..=31.
+
+        let data = StackSlotData::new(kind, bytes as u32, align_shift);
 
         // Collect any trailing comments.
         self.token();
diff --git a/crates/cranelift/src/compiler.rs b/crates/cranelift/src/compiler.rs
index fed9ac988..c121802c1 100644
--- a/crates/cranelift/src/compiler.rs
+++ b/crates/cranelift/src/compiler.rs
@@ -407,7 +407,7 @@ impl wasmtime_environ::Compiler for Compiler {
         let slot = match &ret {
             NativeRet::Bare => None,
             NativeRet::Retptr { size, .. } => Some(builder.func.create_sized_stack_slot(
-                ir::StackSlotData::new(ir::StackSlotKind::ExplicitSlot, *size),
+                ir::StackSlotData::new(ir::StackSlotKind::ExplicitSlot, *size, 0),
             )),
         };
         if let Some(slot) = slot {
@@ -942,6 +942,7 @@ impl Compiler {
         let slot = builder.func.create_sized_stack_slot(ir::StackSlotData::new(
             ir::StackSlotKind::ExplicitSlot,
             values_vec_byte_size,
+            4,
         ));
         let values_vec_ptr = builder.ins().stack_addr(pointer_type, slot, 0);
 
diff --git a/crates/cranelift/src/compiler/component.rs b/crates/cranelift/src/compiler/component.rs
index 250f7c304..8068cade5 100644
--- a/crates/cranelift/src/compiler/component.rs
+++ b/crates/cranelift/src/compiler/component.rs
@@ -775,6 +775,7 @@ impl TrampolineCompiler<'_> {
                 .create_sized_stack_slot(ir::StackSlotData::new(
                     ir::StackSlotKind::ExplicitSlot,
                     pointer_type.bytes(),
+                    0,
                 ));
             args.push(self.builder.ins().stack_addr(pointer_type, slot, 0));
         }
diff --git a/crates/fuzzing/Cargo.toml b/crates/fuzzing/Cargo.toml
index 877012436..ddaa4ad57 100644
--- a/crates/fuzzing/Cargo.toml
+++ b/crates/fuzzing/Cargo.toml
@@ -49,7 +49,7 @@ rand = { version = "0.8.0", features = ["small_rng"] }
 wasm-spec-interpreter = { path = "./wasm-spec-interpreter", optional = true, features = ['build-libinterpret'] }
 
 [features]
-fuzz-spec-interpreter = ['wasm-spec-interpreter']
+fuzz-spec-interpreter = ['dep:wasm-spec-interpreter']
 
 # Fuzz proof-carrying code. Off by default.
 fuzz-pcc = []
diff --git a/crates/jit-icache-coherence/src/libc.rs b/crates/jit-icache-coherence/src/libc.rs
index 0d7462042..9e90f1b58 100644
--- a/crates/jit-icache-coherence/src/libc.rs
+++ b/crates/jit-icache-coherence/src/libc.rs
@@ -108,6 +108,7 @@ fn riscv_flush_icache(start: u64, end: u64) -> Result<()> {
     cfg_if::cfg_if! {
         if #[cfg(feature = "one-core")] {
             use core::arch::asm;
+            let _ = (start, end);
             unsafe {
                 asm!("fence.i");
             };
diff --git a/crates/wasmtime/src/compile.rs b/crates/wasmtime/src/compile.rs
index 62f910d86..315c228c9 100644
--- a/crates/wasmtime/src/compile.rs
+++ b/crates/wasmtime/src/compile.rs
@@ -27,6 +27,7 @@ use crate::Engine;
 use anyhow::{Context, Result};
 use std::{
     any::Any,
+    borrow::Cow,
     collections::{btree_map, BTreeMap, BTreeSet, HashMap, HashSet},
     mem,
 };
@@ -419,6 +420,35 @@ impl<'a> CompileInputs<'a> {
         ret
     }
 
+    fn clean_symbol(name: &str) -> Cow<str> {
+        /// Maximum length of symbols generated in objects.
+        const MAX_SYMBOL_LEN: usize = 96;
+
+        // Just to be on the safe side, avoid passing user-provided data to tools
+        // like "perf" or "objdump", and filter the name.  Let only characters usually
+        // used for function names, plus some characters that might be used in name
+        // mangling.
+        let bad_char = |c: char| !c.is_ascii_alphanumeric() && !r"<>[]_-:@$".contains(c);
+        if name.chars().any(bad_char) {
+            let mut last_char_seen = '\u{0000}';
+            Cow::Owned(
+                name.chars()
+                    .map(|c| if bad_char(c) { '?' } else { c })
+                    .filter(|c| {
+                        let skip = last_char_seen == '?' && *c == '?';
+                        last_char_seen = *c;
+                        !skip
+                    })
+                    .take(MAX_SYMBOL_LEN)
+                    .collect::<String>(),
+            )
+        } else if name.len() <= MAX_SYMBOL_LEN {
+            Cow::Borrowed(&name[..])
+        } else {
+            Cow::Borrowed(&name[..MAX_SYMBOL_LEN])
+        }
+    }
+
     fn collect_inputs_in_translations(
         &mut self,
         types: &'a ModuleTypesBuilder,
@@ -436,13 +466,28 @@ impl<'a> CompileInputs<'a> {
                     let func_index = translation.module.func_index(def_func_index);
                     let (info, function) =
                         compiler.compile_function(translation, def_func_index, func_body, types)?;
-                    Ok(CompileOutput {
-                        key: CompileKey::wasm_function(module, def_func_index),
-                        symbol: format!(
+                    let symbol = match translation
+                        .debuginfo
+                        .name_section
+                        .func_names
+                        .get(&func_index)
+                    {
+                        Some(name) => format!(
+                            "wasm[{}]::function[{}]::{}",
+                            module.as_u32(),
+                            func_index.as_u32(),
+                            Self::clean_symbol(&name)
+                        ),
+                        None => format!(
                             "wasm[{}]::function[{}]",
                             module.as_u32(),
                             func_index.as_u32()
                         ),
+                    };
+
+                    Ok(CompileOutput {
+                        key: CompileKey::wasm_function(module, def_func_index),
+                        symbol,
                         function: CompiledFunction::Function(function),
                         info: Some(info),
                     })
diff --git a/crates/wasmtime/src/config.rs b/crates/wasmtime/src/config.rs
index 7afc00bbf..5522e561e 100644
--- a/crates/wasmtime/src/config.rs
+++ b/crates/wasmtime/src/config.rs
@@ -1368,7 +1368,7 @@ impl Config {
     /// for pooling allocation by using memory protection; see
     /// `PoolingAllocatorConfig::memory_protection_keys` for details.
     pub fn static_memory_maximum_size(&mut self, max_size: u64) -> &mut Self {
-        self.tunables.static_memory_reservation = Some(max_size);
+        self.tunables.static_memory_reservation = Some(round_up_to_pages(max_size));
         self
     }
 


Test patch:
diff --git a/ci/build-test-matrix.js b/ci/build-test-matrix.js
index 38ad67c73..4ae97b66a 100644
--- a/ci/build-test-matrix.js
+++ b/ci/build-test-matrix.js
@@ -5,43 +5,55 @@
 // couldn't figure out how to write it in bash.
 
 const fs = require('fs');
+const { spawn } = require('node:child_process');
 
-// Our first argument is a file that is a giant json blob which contains at
-// least all the messages for all of the commits that were a part of this PR.
-// This is used to test if any commit message includes a string.
-const commits = fs.readFileSync(process.argv[2]).toString();
+// Number of generic buckets to shard crates into. Note that we additionally add
+// single-crate buckets for our biggest crates.
+const GENERIC_BUCKETS = 3;
 
-// The second argument is a file that contains the names of all files modified
-// for a PR, used for file-based filters.
-const names = fs.readFileSync(process.argv[3]).toString();
+// Crates which are their own buckets. These are the very slowest to
+// compile-and-test crates.
+const SINGLE_CRATE_BUCKETS = ["wasmtime", "wasmtime-cli", "wasmtime-wasi"];
 
-// This is the full matrix of what we test on CI. This includes a number of
-// platforms and a number of cross-compiled targets that are emulated with QEMU.
-// This must be kept tightly in sync with the `test` step in `main.yml`.
+// This is the small, fast-to-execute matrix we use for PRs before they enter
+// the merge queue. Same schema as `FULL_MATRIX`.
+const FAST_MATRIX = [
+  {
+    "os": "ubuntu-latest",
+    "name": "Test Linux x86_64",
+    "filter": "linux-x64",
+    "isa": "x64",
+  },
+];
+
+// This is the full, unsharded, and unfiltered matrix of what we test on
+// CI. This includes a number of platforms and a number of cross-compiled
+// targets that are emulated with QEMU. This must be kept tightly in sync with
+// the `test` step in `main.yml`.
 //
 // The supported keys here are:
 //
 // * `os` - the github-actions name of the runner os
+//
 // * `name` - the human-readable name of the job
+//
 // * `filter` - a string which if `prtest:$filter` is in the commit messages
 //   it'll force running this test suite on PR CI.
+//
+// * `isa` - changes to `cranelift/codegen/src/$isa` will automatically run this
+//   test suite.
+//
 // * `target` - used for cross-compiles if present. Effectively Cargo's
 //   `--target` option for all its operations.
+//
 // * `gcc_package`, `gcc`, `qemu`, `qemu_target` - configuration for building
 //   QEMU and installing cross compilers to execute a cross-compiled test suite
 //   on CI.
-// * `isa` - changes to `cranelift/codegen/src/$isa` will automatically run this
-//   test suite.
+//
 // * `rust` - the Rust version to install, and if unset this'll be set to
 //   `default`
-const array = [
-  {
-    "os": "ubuntu-latest",
-    "name": "Test Linux x86_64",
-    "filter": "linux-x64",
-    "isa": "x64",
-    "extra_features": "--features wasmtime-wasi-nn/onnx"
-  },
+const FULL_MATRIX = [
+  ...FAST_MATRIX,
   {
     "os": "ubuntu-latest",
     "name": "Test MSRV on Linux x86_64",
@@ -59,20 +71,17 @@ const array = [
     "os": "macos-13",
     "name": "Test macOS x86_64",
     "filter": "macos-x64",
-    "extra_features": "--features wasmtime-wasi-nn/onnx"
   },
   {
     "os": "macos-14",
     "name": "Test macOS arm64",
     "filter": "macos-arm64",
     "target": "aarch64-apple-darwin",
-    "extra_features": "--features wasmtime-wasi-nn/onnx"
   },
   {
     "os": "windows-latest",
     "name": "Test Windows MSVC x86_64",
     "filter": "windows-x64",
-    "extra_features": "--features wasmtime-wasi-nn/onnx"
   },
   {
     "os": "windows-latest",
@@ -115,44 +124,153 @@ const array = [
   }
 ];
 
-for (let config of array) {
-  if (config.rust === undefined) {
-    config.rust = 'default';
+/// Get the workspace's full list of member crates.
+async function getWorkspaceMembers() {
+  // Spawn a `cargo metadata` subprocess, accumulate its JSON output from
+  // `stdout`, and wait for it to exit.
+  const child = spawn("cargo", ["metadata"], { encoding: "utf8" });
+  let data = "";
+  child.stdout.on("data", chunk => data += chunk);
+  await new Promise((resolve, reject) => {
+    child.on("close", resolve);
+    child.on("error", reject);
+  });
+
+  // Get the names of the crates in the workspace from the JSON metadata by
+  // building a package-id to name map and then translating the package-ids
+  // listed as workspace members.
+  const metadata = JSON.parse(data);
+  const id_to_name = {};
+  for (const pkg of metadata.packages) {
+    id_to_name[pkg.id] = pkg.name;
   }
+  return metadata.workspace_members.map(m => id_to_name[m]);
 }
 
-function myFilter(item) {
-  if (item.isa && names.includes(`cranelift/codegen/src/isa/${item.isa}`)) {
-    return true;
+/// For each given target configuration, shard the workspace's crates into
+/// buckets across that config.
+///
+/// This is essentially a `flat_map` where each config that logically tests all
+/// crates int he workspace is mapped to N sharded configs that each test only a
+/// subset of crates in the workspace. Each sharded config's subset of crates to
+/// test are disjoint from all its siblings, and the union of all thes siblings'
+/// crates to test is the full workspace members set.
+///
+/// With some poetic license around a `crates_to_test` key that doesn't actually
+/// exist, logically each element of the input `configs` list gets transformed
+/// like this:
+///
+///     { os: "ubuntu-latest", isa: "x64", ..., crates: "all" }
+///
+///     ==>
+///
+///     [
+///       { os: "ubuntu-latest", isa: "x64", ..., crates: ["wasmtime"] },
+///       { os: "ubuntu-latest", isa: "x64", ..., crates: ["wasmtime-cli"] },
+///       { os: "ubuntu-latest", isa: "x64", ..., crates: ["wasmtime-wasi"] },
+///       { os: "ubuntu-latest", isa: "x64", ..., crates: ["cranelift", "cranelift-codegen", ...] },
+///       { os: "ubuntu-latest", isa: "x64", ..., crates: ["wasmtime-slab", "cranelift-entity", ...] },
+///       { os: "ubuntu-latest", isa: "x64", ..., crates: ["cranelift-environ", "wasmtime-cli-flags", ...] },
+///       ...
+///     ]
+///
+/// Note that `crates: "all"` is implicit in the input and omitted. Similarly,
+/// `crates: [...]` in each output config is actually implemented via adding a
+/// `bucket` key, which contains the CLI flags we must pass to `cargo` to run
+/// tests for just this config's subset of crates.
+async function shard(configs) {
+  const members = await getWorkspaceMembers();
+
+  // Divide the workspace crates into N disjoint subsets. Crates that are
+  // particularly expensive to compile and test form their own singleton subset.
+  const buckets = Array.from({ length: GENERIC_BUCKETS }, _ => new Set());
+  let i = 0;
+  for (const crate of members) {
+    if (SINGLE_CRATE_BUCKETS.indexOf(crate) != -1) continue;
+    buckets[i].add(crate);
+    i = (i + 1) % GENERIC_BUCKETS;
   }
-  if (item.filter && commits.includes(`prtest:${item.filter}`)) {
-    return true;
+  for (crate of SINGLE_CRATE_BUCKETS) {
+    buckets.push(new Set([crate]));
   }
 
-  // If any runtest was modified, re-run the whole test suite as those can
-  // target any backend.
-  if (names.includes(`cranelift/filetests/filetests/runtests`)) {
-    return true;
+  // For each config, expand it into N configs, one for each disjoint set we
+  // created above.
+  const sharded = [];
+  for (const config of configs) {
+    for (const bucket of buckets) {
+      sharded.push(Object.assign(
+        {},
+        config,
+        {
+          name: `${config.name} (${Array.from(bucket).join(', ')})`,
+          // We run tests via `cargo test --workspace`, so exclude crates that
+          // aren't in this bucket, rather than naming only the crates that are
+          // in this bucket.
+          bucket: members
+            .map(c => bucket.has(c) ? `--package ${c}` : `--exclude ${c}`)
+            .join(" "),
+        }
+      ));
+    }
   }
-
-  return false;
+  return sharded;
 }
 
-const filtered = array.filter(myFilter);
+async function main() {
+  // Our first argument is a file that is a giant json blob which contains at
+  // least all the messages for all of the commits that were a part of this PR.
+  // This is used to test if any commit message includes a string.
+  const commits = fs.readFileSync(process.argv[2]).toString();
 
-// If the optional third argument to this script is `true` then that means all
-// tests are being run and no filtering should happen.
-if (process.argv[4] == 'true') {
-  console.log(JSON.stringify(array));
-  return;
-}
+  // The second argument is a file that contains the names of all files modified
+  // for a PR, used for file-based filters.
+  const names = fs.readFileSync(process.argv[3]).toString();
+
+  for (let config of FULL_MATRIX) {
+    if (config.rust === undefined) {
+      config.rust = 'default';
+    }
+  }
+
+  // If the optional third argument to this script is `true` then that means all
+  // tests are being run and no filtering should happen.
+  if (process.argv[4] == 'true') {
+    console.log(JSON.stringify(await shard(FULL_MATRIX), undefined, 2));
+    return;
+  }
+
+  // When we aren't running the full CI matrix, filter configs down to just the
+  // relevant bits based on files changed in this commit or if the commit asks
+  // for a certain config to run.
+  const filtered = FULL_MATRIX.filter(config => {
+    // If an ISA-specific test was modified, then include that ISA config.
+    if (config.isa && names.includes(`cranelift/codegen/src/isa/${config.isa}`)) {
+      return true;
+    }
+
+    // If any runtest was modified, include all ISA configs as runtests can
+    // target any backend.
+    if (names.includes(`cranelift/filetests/filetests/runtests`)) {
+      return config.isa !== undefined;
+    }
+
+    // If the commit explicitly asks for this test config, then include it.
+    if (config.filter && commits.includes(`prtest:${config.filter}`)) {
+      return true;
+    }
+
+    return false;
+  });
+
+  // If at least one test is being run via our filters then run those tests.
+  if (filtered.length > 0) {
+    console.log(JSON.stringify(await shard(filtered), undefined, 2));
+    return;
+  }
 
-// If at least one test is being run via our filters then run those tests.
-if (filtered.length > 0) {
-  console.log(JSON.stringify(filtered));
-  return;
+  // Otherwise if nothing else is being run, run the fast subset of the matrix.
+  console.log(JSON.stringify(await shard(FAST_MATRIX), undefined, 2));
 }
 
-// Otherwise if nothing else is being run, run the first one which is Ubuntu
-// Linux which should be the fastest for now.
-console.log(JSON.stringify([array[0]]));
+main()
diff --git a/ci/run-tests.sh b/ci/run-tests.sh
index db338dc24..274d35232 100755
--- a/ci/run-tests.sh
+++ b/ci/run-tests.sh
@@ -1,10 +1,23 @@
-#!/bin/bash
+#!/usr/bin/env bash
+
+# Excludes:
+#
+# - test-programs: just programs used in tests.
+#
+# - wasmtime-wasi-nn: mutually-exclusive features that aren't available for all
+#   targets, needs its own CI job.
+#
+# - wasmtime-fuzzing: enabling all features brings in OCaml which is a pain to
+#   configure for all targets, so it has its own CI job.
+#
+# - wasm-spec-interpreter: brings in OCaml which is a pain to configure for all
+#   targets, tested as part of the wastime-fuzzing CI job.
 
 cargo test \
-    --features wasi-threads \
-    --features wasi-http \
-    --features component-model \
-    --features serve \
-    --workspace \
-    --exclude test-programs \
-    $@
+      --workspace \
+      --all-features \
+      --exclude test-programs \
+      --exclude wasmtime-wasi-nn \
+      --exclude wasmtime-fuzzing \
+      --exclude wasm-spec-interpreter \
+      $@
diff --git a/cranelift/filetests/filetests/egraph/cprop.clif b/cranelift/filetests/filetests/egraph/cprop.clif
index 95f902d7b..df1ac116f 100644
--- a/cranelift/filetests/filetests/egraph/cprop.clif
+++ b/cranelift/filetests/filetests/egraph/cprop.clif
@@ -312,3 +312,65 @@ block0:
 
 ; check: v2 = iconst.i64 0xf0de_bc9a_7856_3412
 ; nextln: return v2
+
+function %f32_fneg() -> f32 {
+block0:
+    v1 = f32const 0.0
+    v2 = fneg v1
+    return v2
+}
+
+; check: v3 = f32const -0.0
+; check: return v3  ; v3 = -0.0
+
+function %f32_fabs() -> f32 {
+block0:
+    v1 = f32const -0.0
+    v2 = fabs v1
+    return v2
+}
+
+; check: v3 = f32const 0.0
+; check: return v3  ; v3 = 0.0
+
+function %f32_fabs() -> f32 {
+block0:
+    v1 = f32const -0.0
+    v2 = f32const NaN
+    v3 = fcopysign v2, v1
+    return v3
+}
+
+; check: v4 = f32const -NaN
+; check: return v4  ; v4 = -NaN
+
+function %f64_fneg() -> f64 {
+block0:
+    v1 = f64const 0.0
+    v2 = fneg v1
+    return v2
+}
+
+; check: v3 = f64const -0.0
+; check: return v3  ; v3 = -0.0
+
+function %f64_fabs() -> f64 {
+block0:
+    v1 = f64const -0.0
+    v2 = fabs v1
+    return v2
+}
+
+; check: v3 = f64const 0.0
+; check: return v3  ; v3 = 0.0
+
+function %f64_fabs() -> f64 {
+block0:
+    v1 = f64const -0.0
+    v2 = f64const NaN
+    v3 = fcopysign v2, v1
+    return v3
+}
+
+; check: v4 = f64const -NaN
+; check: return v4  ; v4 = -NaN
diff --git a/cranelift/filetests/filetests/isa/x64/stackslot.clif b/cranelift/filetests/filetests/isa/x64/stackslot.clif
new file mode 100644
index 000000000..b4c013839
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/x64/stackslot.clif
@@ -0,0 +1,61 @@
+test compile precise-output
+target x86_64
+
+function %f0(i64 vmctx) -> i64, i64, i64, i64 {
+  gv0 = vmctx
+  stack_limit = gv0
+  ss0 = explicit_slot 8, align=16
+  ss1 = explicit_slot 8, align=16
+  ss2 = explicit_slot 4
+  ss3 = explicit_slot 4
+
+block0(v0: i64):
+  v1 = stack_addr.i64 ss0
+  v2 = stack_addr.i64 ss1
+  v3 = stack_addr.i64 ss2
+  v4 = stack_addr.i64 ss3
+  return v1, v2, v3, v4
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+;   movq    %rdi, %r10
+;   addq    %r10, $48, %r10
+;   cmpq    %rsp, %r10
+;   jnbe #trap=stk_ovf
+;   subq    %rsp, $48, %rsp
+; block0:
+;   lea     rsp(0 + virtual offset), %rax
+;   lea     rsp(16 + virtual offset), %rdx
+;   lea     rsp(32 + virtual offset), %r8
+;   lea     rsp(40 + virtual offset), %r9
+;   movq    %r8, 0(%rsi)
+;   movq    %r9, 8(%rsi)
+;   addq    %rsp, $48, %rsp
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+;   movq %rdi, %r10
+;   addq $0x30, %r10
+;   cmpq %rsp, %r10
+;   ja 0x3b
+;   subq $0x30, %rsp
+; block1: ; offset 0x18
+;   leaq (%rsp), %rax
+;   leaq 0x10(%rsp), %rdx
+;   leaq 0x20(%rsp), %r8
+;   leaq 0x28(%rsp), %r9
+;   movq %r8, (%rsi)
+;   movq %r9, 8(%rsi)
+;   addq $0x30, %rsp
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+;   ud2 ; trap: stk_ovf
+
diff --git a/tests/all/memory.rs b/tests/all/memory.rs
index 6625cf919..6bbd3c2ce 100644
--- a/tests/all/memory.rs
+++ b/tests/all/memory.rs
@@ -658,3 +658,14 @@ fn init_with_negative_segment() -> Result<()> {
     Instance::new(&mut store, &module, &[])?;
     Ok(())
 }
+
+#[test]
+fn non_page_aligned_static_memory() -> Result<()> {
+    let mut config = Config::new();
+    config.static_memory_maximum_size(100_000);
+    config.static_memory_forced(true);
+    let engine = Engine::new(&config)?;
+    let ty = MemoryType::new(1, None);
+    Memory::new(&mut Store::new(&engine, ()), ty)?;
+    Ok(())
+}
diff --git a/tests/all/pooling_allocator.rs b/tests/all/pooling_allocator.rs
index eceb330fc..7c563a0e1 100644
--- a/tests/all/pooling_allocator.rs
+++ b/tests/all/pooling_allocator.rs
@@ -644,10 +644,10 @@ fn instance_too_large() -> Result<()> {
     let engine = Engine::new(&config)?;
     let expected = if cfg!(feature = "wmemcheck") {
         "\
-        instance allocation for this module requires 336 bytes which exceeds the \
+        instance allocation for this module requires 352 bytes which exceeds the \
 configured maximum of 16 bytes; breakdown of allocation requirement:
 
- * 76.19% - 256 bytes - instance state management
+ * 72.73% - 256 bytes - instance state management
 "
     } else {
         "\
@@ -671,11 +671,11 @@ configured maximum of 16 bytes; breakdown of allocation requirement:
 
     let expected = if cfg!(feature = "wmemcheck") {
         "\
-instance allocation for this module requires 1936 bytes which exceeds the \
+instance allocation for this module requires 1952 bytes which exceeds the \
 configured maximum of 16 bytes; breakdown of allocation requirement:
 
- * 13.22% - 256 bytes - instance state management
- * 82.64% - 1600 bytes - defined globals
+ * 13.11% - 256 bytes - instance state management
+ * 81.97% - 1600 bytes - defined globals
 "
     } else {
         "\
diff --git a/tests/disas/winch/x64/block/as_if_cond.wat b/tests/disas/winch/x64/block/as_if_cond.wat
index e4404cd50..7c1d774ee 100644
--- a/tests/disas/winch/x64/block/as_if_cond.wat
+++ b/tests/disas/winch/x64/block/as_if_cond.wat
@@ -8,7 +8,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/block/deep.wat b/tests/disas/winch/x64/block/deep.wat
index 2cb1638f8..e578060aa 100644
--- a/tests/disas/winch/x64/block/deep.wat
+++ b/tests/disas/winch/x64/block/deep.wat
@@ -45,7 +45,7 @@
     ))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/block/empty.wat b/tests/disas/winch/x64/block/empty.wat
index bfef77e6d..7730095b1 100644
--- a/tests/disas/winch/x64/block/empty.wat
+++ b/tests/disas/winch/x64/block/empty.wat
@@ -9,7 +9,7 @@
     (block $l)
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/block/nested.wat b/tests/disas/winch/x64/block/nested.wat
index 14d77ab75..4d97a9da5 100644
--- a/tests/disas/winch/x64/block/nested.wat
+++ b/tests/disas/winch/x64/block/nested.wat
@@ -10,7 +10,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br/as_block_first.wat b/tests/disas/winch/x64/br/as_block_first.wat
index ebfbd6310..ac9667ee1 100644
--- a/tests/disas/winch/x64/br/as_block_first.wat
+++ b/tests/disas/winch/x64/br/as_block_first.wat
@@ -7,7 +7,7 @@
     (block (br 0) (call $dummy))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br/as_block_last.wat b/tests/disas/winch/x64/br/as_block_last.wat
index 21a071561..85c7aa243 100644
--- a/tests/disas/winch/x64/br/as_block_last.wat
+++ b/tests/disas/winch/x64/br/as_block_last.wat
@@ -7,7 +7,7 @@
     (block (nop) (call $dummy) (br 0))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br/as_block_mid.wat b/tests/disas/winch/x64/br/as_block_mid.wat
index 56f1cc850..8341c4852 100644
--- a/tests/disas/winch/x64/br/as_block_mid.wat
+++ b/tests/disas/winch/x64/br/as_block_mid.wat
@@ -7,7 +7,7 @@
     (block (call $dummy) (br 0) (call $dummy))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br/as_block_value.wat b/tests/disas/winch/x64/br/as_block_value.wat
index 2261e64d9..6ae481851 100644
--- a/tests/disas/winch/x64/br/as_block_value.wat
+++ b/tests/disas/winch/x64/br/as_block_value.wat
@@ -7,7 +7,7 @@
     (block (result i32) (nop) (call $dummy) (br 0 (i32.const 2)))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br/as_call_all.wat b/tests/disas/winch/x64/br/as_call_all.wat
index 5b59fe008..b2305f66c 100644
--- a/tests/disas/winch/x64/br/as_call_all.wat
+++ b/tests/disas/winch/x64/br/as_call_all.wat
@@ -6,7 +6,7 @@
     (block (result i32) (call $f (br 0 (i32.const 15))))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br/as_call_first.wat b/tests/disas/winch/x64/br/as_call_first.wat
index 0d1b2e8ff..ea2035e8f 100644
--- a/tests/disas/winch/x64/br/as_call_first.wat
+++ b/tests/disas/winch/x64/br/as_call_first.wat
@@ -9,7 +9,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br/as_call_last.wat b/tests/disas/winch/x64/br/as_call_last.wat
index 9c826a8ef..445f65c6d 100644
--- a/tests/disas/winch/x64/br/as_call_last.wat
+++ b/tests/disas/winch/x64/br/as_call_last.wat
@@ -8,7 +8,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br/as_call_mid.wat b/tests/disas/winch/x64/br/as_call_mid.wat
index ea7102463..fdc019aa0 100644
--- a/tests/disas/winch/x64/br/as_call_mid.wat
+++ b/tests/disas/winch/x64/br/as_call_mid.wat
@@ -9,7 +9,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br/as_loop_last.wat b/tests/disas/winch/x64/br/as_loop_last.wat
index bed25087a..d8c08c3ee 100644
--- a/tests/disas/winch/x64/br/as_loop_last.wat
+++ b/tests/disas/winch/x64/br/as_loop_last.wat
@@ -8,7 +8,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br/as_loop_mid.wat b/tests/disas/winch/x64/br/as_loop_mid.wat
index 09a438948..12b0297c1 100644
--- a/tests/disas/winch/x64/br/as_loop_mid.wat
+++ b/tests/disas/winch/x64/br/as_loop_mid.wat
@@ -9,7 +9,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br_if/as_block_last.wat b/tests/disas/winch/x64/br_if/as_block_last.wat
index d1c9dddbc..91b1ea643 100644
--- a/tests/disas/winch/x64/br_if/as_block_last.wat
+++ b/tests/disas/winch/x64/br_if/as_block_last.wat
@@ -6,7 +6,7 @@
     (block (call $dummy) (call $dummy) (br_if 0 (local.get 0)))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br_if/as_block_last_value.wat b/tests/disas/winch/x64/br_if/as_block_last_value.wat
index 791d49846..881b92114 100644
--- a/tests/disas/winch/x64/br_if/as_block_last_value.wat
+++ b/tests/disas/winch/x64/br_if/as_block_last_value.wat
@@ -8,7 +8,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br_if/as_call_first.wat b/tests/disas/winch/x64/br_if/as_call_first.wat
index ae425c7b1..1278b2ff0 100644
--- a/tests/disas/winch/x64/br_if/as_call_first.wat
+++ b/tests/disas/winch/x64/br_if/as_call_first.wat
@@ -10,7 +10,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br_if/as_call_last.wat b/tests/disas/winch/x64/br_if/as_call_last.wat
index 816c0b419..a28b592c2 100644
--- a/tests/disas/winch/x64/br_if/as_call_last.wat
+++ b/tests/disas/winch/x64/br_if/as_call_last.wat
@@ -10,7 +10,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br_if/as_call_mid.wat b/tests/disas/winch/x64/br_if/as_call_mid.wat
index e49fe0e35..ffc1cf196 100644
--- a/tests/disas/winch/x64/br_if/as_call_mid.wat
+++ b/tests/disas/winch/x64/br_if/as_call_mid.wat
@@ -10,7 +10,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br_if/as_if_else.wat b/tests/disas/winch/x64/br_if/as_if_else.wat
index 09bd9bf2a..dbbb85c0f 100644
--- a/tests/disas/winch/x64/br_if/as_if_else.wat
+++ b/tests/disas/winch/x64/br_if/as_if_else.wat
@@ -9,7 +9,7 @@
   )
 )
 
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br_if/as_if_then.wat b/tests/disas/winch/x64/br_if/as_if_then.wat
index 253ceff3d..08bdb24a0 100644
--- a/tests/disas/winch/x64/br_if/as_if_then.wat
+++ b/tests/disas/winch/x64/br_if/as_if_then.wat
@@ -8,7 +8,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/br_if/as_loop_last.wat b/tests/disas/winch/x64/br_if/as_loop_last.wat
index c0b6739fe..a9e069491 100644
--- a/tests/disas/winch/x64/br_if/as_loop_last.wat
+++ b/tests/disas/winch/x64/br_if/as_loop_last.wat
@@ -6,7 +6,7 @@
     (loop (call $dummy) (br_if 1 (local.get 0)))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/call/params.wat b/tests/disas/winch/x64/call/params.wat
index f253ff46c..8a848b586 100644
--- a/tests/disas/winch/x64/call/params.wat
+++ b/tests/disas/winch/x64/call/params.wat
@@ -119,7 +119,7 @@
 ;;       retq
 ;;  152: ud2
 ;;
-;; wasm[0]::function[1]:
+;; wasm[0]::function[1]::add:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/call/recursive.wat b/tests/disas/winch/x64/call/recursive.wat
index fe7ed34d6..3f7f2a139 100644
--- a/tests/disas/winch/x64/call/recursive.wat
+++ b/tests/disas/winch/x64/call/recursive.wat
@@ -23,7 +23,7 @@
   )
   (export "fib" (func $fibonacci8))
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::fibonacci8:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/call/simple.wat b/tests/disas/winch/x64/call/simple.wat
index 8a4c12cd0..1209138d6 100644
--- a/tests/disas/winch/x64/call/simple.wat
+++ b/tests/disas/winch/x64/call/simple.wat
@@ -14,7 +14,7 @@
     (local.get 1)
     (i32.mul))
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::main:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
@@ -53,7 +53,7 @@
 ;;       retq
 ;;   8b: ud2
 ;;
-;; wasm[0]::function[1]:
+;; wasm[0]::function[1]::product:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/f32_const/call_id.wat b/tests/disas/winch/x64/f32_const/call_id.wat
index d0495223d..615cf587d 100644
--- a/tests/disas/winch/x64/f32_const/call_id.wat
+++ b/tests/disas/winch/x64/f32_const/call_id.wat
@@ -5,7 +5,7 @@
   (func $id-f32 (param f32) (result f32) (local.get 0))
   (func (export "type-first-f32") (result f32) (call $id-f32 (f32.const 1.32)))
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::id-f32:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/f64_const/call_id.wat b/tests/disas/winch/x64/f64_const/call_id.wat
index ce95cf96e..f40f4a069 100644
--- a/tests/disas/winch/x64/f64_const/call_id.wat
+++ b/tests/disas/winch/x64/f64_const/call_id.wat
@@ -5,7 +5,7 @@
   (func $id-f64 (param f64) (result f64) (local.get 0))
   (func (export "type-first-f64") (result f64) (call $id-f64 (f64.const 1.32)))
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::id-f64:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/if/as_binop.wat b/tests/disas/winch/x64/if/as_binop.wat
index 79838837b..dfe38960d 100644
--- a/tests/disas/winch/x64/if/as_binop.wat
+++ b/tests/disas/winch/x64/if/as_binop.wat
@@ -16,7 +16,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/if/as_br_if_last.wat b/tests/disas/winch/x64/if/as_br_if_last.wat
index 18687ed39..504631666 100644
--- a/tests/disas/winch/x64/if/as_br_if_last.wat
+++ b/tests/disas/winch/x64/if/as_br_if_last.wat
@@ -15,7 +15,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/if/as_if_cond.wat b/tests/disas/winch/x64/if/as_if_cond.wat
index c1acd2518..3632b0f72 100644
--- a/tests/disas/winch/x64/if/as_if_cond.wat
+++ b/tests/disas/winch/x64/if/as_if_cond.wat
@@ -13,7 +13,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/if/as_testop.wat b/tests/disas/winch/x64/if/as_testop.wat
index 326371c67..598f018d9 100644
--- a/tests/disas/winch/x64/if/as_testop.wat
+++ b/tests/disas/winch/x64/if/as_testop.wat
@@ -11,7 +11,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/if/nested.wat b/tests/disas/winch/x64/if/nested.wat
index 149fe1395..c53a4b478 100644
--- a/tests/disas/winch/x64/if/nested.wat
+++ b/tests/disas/winch/x64/if/nested.wat
@@ -23,7 +23,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/if/singular.wat b/tests/disas/winch/x64/if/singular.wat
index efe7d8509..93f55f143 100644
--- a/tests/disas/winch/x64/if/singular.wat
+++ b/tests/disas/winch/x64/if/singular.wat
@@ -9,7 +9,7 @@
     (if (result i32) (local.get 0) (then (i32.const 7)) (else (i32.const 8)))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/loop/as_binary_operand.wat b/tests/disas/winch/x64/loop/as_binary_operand.wat
index 1f1b831be..7df234a8c 100644
--- a/tests/disas/winch/x64/loop/as_binary_operand.wat
+++ b/tests/disas/winch/x64/loop/as_binary_operand.wat
@@ -9,7 +9,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/loop/as_call_value.wat b/tests/disas/winch/x64/loop/as_call_value.wat
index bda642ce5..46925e8b6 100644
--- a/tests/disas/winch/x64/loop/as_call_value.wat
+++ b/tests/disas/winch/x64/loop/as_call_value.wat
@@ -6,7 +6,7 @@
     (call $f (loop (result i32) (i32.const 1)))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/loop/as_if_condition.wat b/tests/disas/winch/x64/loop/as_if_condition.wat
index b5946a601..ce0eacb62 100644
--- a/tests/disas/winch/x64/loop/as_if_condition.wat
+++ b/tests/disas/winch/x64/loop/as_if_condition.wat
@@ -6,7 +6,7 @@
     (loop (result i32) (i32.const 1)) (if (then (call $dummy)))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/loop/as_test_operand.wat b/tests/disas/winch/x64/loop/as_test_operand.wat
index 21aceaf30..5ddc5238a 100644
--- a/tests/disas/winch/x64/loop/as_test_operand.wat
+++ b/tests/disas/winch/x64/loop/as_test_operand.wat
@@ -6,7 +6,7 @@
     (i32.eqz (loop (result i32) (call $dummy) (i32.const 13)))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/loop/as_unary_operand.wat b/tests/disas/winch/x64/loop/as_unary_operand.wat
index 660fe9344..13a544918 100644
--- a/tests/disas/winch/x64/loop/as_unary_operand.wat
+++ b/tests/disas/winch/x64/loop/as_unary_operand.wat
@@ -6,7 +6,7 @@
     (i32.ctz (loop (result i32) (call $dummy) (i32.const 13)))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/loop/deep.wat b/tests/disas/winch/x64/loop/deep.wat
index 19c57c350..b60c55acf 100644
--- a/tests/disas/winch/x64/loop/deep.wat
+++ b/tests/disas/winch/x64/loop/deep.wat
@@ -47,7 +47,7 @@
     ))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/loop/effects.wat b/tests/disas/winch/x64/loop/effects.wat
index 3af51046f..66b70462e 100644
--- a/tests/disas/winch/x64/loop/effects.wat
+++ b/tests/disas/winch/x64/loop/effects.wat
@@ -16,7 +16,7 @@
     (i32.eq (local.get 0) (i32.const -14))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::fx:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/loop/multi.wat b/tests/disas/winch/x64/loop/multi.wat
index ab4e22f2c..d43531681 100644
--- a/tests/disas/winch/x64/loop/multi.wat
+++ b/tests/disas/winch/x64/loop/multi.wat
@@ -8,7 +8,7 @@
     (loop (result i32) (call $dummy) (call $dummy) (i32.const 8) (call $dummy))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/loop/nested.wat b/tests/disas/winch/x64/loop/nested.wat
index af64528b5..8c1fbd9bf 100644
--- a/tests/disas/winch/x64/loop/nested.wat
+++ b/tests/disas/winch/x64/loop/nested.wat
@@ -9,7 +9,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_block_first.wat b/tests/disas/winch/x64/return/as_block_first.wat
index 9fa014f24..0114f5477 100644
--- a/tests/disas/winch/x64/return/as_block_first.wat
+++ b/tests/disas/winch/x64/return/as_block_first.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_block_last.wat b/tests/disas/winch/x64/return/as_block_last.wat
index 2eab7167f..2caf07ccf 100644
--- a/tests/disas/winch/x64/return/as_block_last.wat
+++ b/tests/disas/winch/x64/return/as_block_last.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_block_mid.wat b/tests/disas/winch/x64/return/as_block_mid.wat
index 5ee7d306e..100de03d1 100644
--- a/tests/disas/winch/x64/return/as_block_mid.wat
+++ b/tests/disas/winch/x64/return/as_block_mid.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_block_value.wat b/tests/disas/winch/x64/return/as_block_value.wat
index 143ceb22f..7fa73dbea 100644
--- a/tests/disas/winch/x64/return/as_block_value.wat
+++ b/tests/disas/winch/x64/return/as_block_value.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_br_if_cond.wat b/tests/disas/winch/x64/return/as_br_if_cond.wat
index 7976d90e4..bdee5f728 100644
--- a/tests/disas/winch/x64/return/as_br_if_cond.wat
+++ b/tests/disas/winch/x64/return/as_br_if_cond.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_br_value.wat b/tests/disas/winch/x64/return/as_br_value.wat
index 8302d1bea..752869e73 100644
--- a/tests/disas/winch/x64/return/as_br_value.wat
+++ b/tests/disas/winch/x64/return/as_br_value.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_call_fist.wat b/tests/disas/winch/x64/return/as_call_fist.wat
index 0978041e7..58a6fe06f 100644
--- a/tests/disas/winch/x64/return/as_call_fist.wat
+++ b/tests/disas/winch/x64/return/as_call_fist.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_call_last.wat b/tests/disas/winch/x64/return/as_call_last.wat
index 3df2e675d..d58617f19 100644
--- a/tests/disas/winch/x64/return/as_call_last.wat
+++ b/tests/disas/winch/x64/return/as_call_last.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_call_mid.wat b/tests/disas/winch/x64/return/as_call_mid.wat
index 52971f7b4..056ffee67 100644
--- a/tests/disas/winch/x64/return/as_call_mid.wat
+++ b/tests/disas/winch/x64/return/as_call_mid.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_func_first.wat b/tests/disas/winch/x64/return/as_func_first.wat
index 16bad3739..7e0e5dd48 100644
--- a/tests/disas/winch/x64/return/as_func_first.wat
+++ b/tests/disas/winch/x64/return/as_func_first.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_func_last.wat b/tests/disas/winch/x64/return/as_func_last.wat
index cb3d1e343..0f6a545cb 100644
--- a/tests/disas/winch/x64/return/as_func_last.wat
+++ b/tests/disas/winch/x64/return/as_func_last.wat
@@ -4,7 +4,7 @@
   (func $dummy)
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_func_mid.wat b/tests/disas/winch/x64/return/as_func_mid.wat
index 86cca502f..730073fcf 100644
--- a/tests/disas/winch/x64/return/as_func_mid.wat
+++ b/tests/disas/winch/x64/return/as_func_mid.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_func_value.wat b/tests/disas/winch/x64/return/as_func_value.wat
index eb769edb2..3311f70de 100644
--- a/tests/disas/winch/x64/return/as_func_value.wat
+++ b/tests/disas/winch/x64/return/as_func_value.wat
@@ -7,7 +7,7 @@
     )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_if_cond.wat b/tests/disas/winch/x64/return/as_if_cond.wat
index e370e684f..c1b869dd2 100644
--- a/tests/disas/winch/x64/return/as_if_cond.wat
+++ b/tests/disas/winch/x64/return/as_if_cond.wat
@@ -9,7 +9,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_if_else.wat b/tests/disas/winch/x64/return/as_if_else.wat
index 99c44d8c7..64d14f0fd 100644
--- a/tests/disas/winch/x64/return/as_if_else.wat
+++ b/tests/disas/winch/x64/return/as_if_else.wat
@@ -10,7 +10,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_if_then.wat b/tests/disas/winch/x64/return/as_if_then.wat
index e00b1f0e1..897cf6047 100644
--- a/tests/disas/winch/x64/return/as_if_then.wat
+++ b/tests/disas/winch/x64/return/as_if_then.wat
@@ -10,7 +10,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_loop_first.wat b/tests/disas/winch/x64/return/as_loop_first.wat
index 4b47758c0..ffc33d39a 100644
--- a/tests/disas/winch/x64/return/as_loop_first.wat
+++ b/tests/disas/winch/x64/return/as_loop_first.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_loop_last.wat b/tests/disas/winch/x64/return/as_loop_last.wat
index 664026bfe..503a65305 100644
--- a/tests/disas/winch/x64/return/as_loop_last.wat
+++ b/tests/disas/winch/x64/return/as_loop_last.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_loop_mid.wat b/tests/disas/winch/x64/return/as_loop_mid.wat
index d735a976b..7d238eca4 100644
--- a/tests/disas/winch/x64/return/as_loop_mid.wat
+++ b/tests/disas/winch/x64/return/as_loop_mid.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/as_return_value.wat b/tests/disas/winch/x64/return/as_return_value.wat
index 4893b4902..d6273e7d7 100644
--- a/tests/disas/winch/x64/return/as_return_value.wat
+++ b/tests/disas/winch/x64/return/as_return_value.wat
@@ -7,7 +7,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/nullary.wat b/tests/disas/winch/x64/return/nullary.wat
index f1eb2cd19..91b8d1fcd 100644
--- a/tests/disas/winch/x64/return/nullary.wat
+++ b/tests/disas/winch/x64/return/nullary.wat
@@ -5,7 +5,7 @@
   (func (export "nullary") (return))
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/type_i32.wat b/tests/disas/winch/x64/return/type_i32.wat
index 698794e08..66703bbc8 100644
--- a/tests/disas/winch/x64/return/type_i32.wat
+++ b/tests/disas/winch/x64/return/type_i32.wat
@@ -8,7 +8,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/return/type_i64_value.wat b/tests/disas/winch/x64/return/type_i64_value.wat
index e6a3ff0f5..802f3578e 100644
--- a/tests/disas/winch/x64/return/type_i64_value.wat
+++ b/tests/disas/winch/x64/return/type_i64_value.wat
@@ -8,7 +8,7 @@
   )
 )
   
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/table/fill.wat b/tests/disas/winch/x64/table/fill.wat
index b9efc719e..20a340eca 100644
--- a/tests/disas/winch/x64/table/fill.wat
+++ b/tests/disas/winch/x64/table/fill.wat
@@ -20,7 +20,7 @@
     (table.fill $t2 (local.get $i) (local.get $ref) (local.get $n))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::f1:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
@@ -37,7 +37,7 @@
 ;;       retq
 ;;   31: ud2
 ;;
-;; wasm[0]::function[1]:
+;; wasm[0]::function[1]::f2:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
@@ -54,7 +54,7 @@
 ;;       retq
 ;;   71: ud2
 ;;
-;; wasm[0]::function[2]:
+;; wasm[0]::function[2]::f3:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/table/get.wat b/tests/disas/winch/x64/table/get.wat
index 06fa26052..a4f69b462 100644
--- a/tests/disas/winch/x64/table/get.wat
+++ b/tests/disas/winch/x64/table/get.wat
@@ -10,7 +10,7 @@
 )
 
 
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
@@ -27,7 +27,7 @@
 ;;       retq
 ;;   31: ud2
 ;;
-;; wasm[0]::function[1]:
+;; wasm[0]::function[1]::f3:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/table/set.wat b/tests/disas/winch/x64/table/set.wat
index 54ee08e48..7ffe246a5 100644
--- a/tests/disas/winch/x64/table/set.wat
+++ b/tests/disas/winch/x64/table/set.wat
@@ -15,7 +15,7 @@
   )
 )
 
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_block_broke.wat b/tests/disas/winch/x64/unreachable/as_block_broke.wat
index dd4f5ad7c..39b703504 100644
--- a/tests/disas/winch/x64/unreachable/as_block_broke.wat
+++ b/tests/disas/winch/x64/unreachable/as_block_broke.wat
@@ -7,7 +7,7 @@
     (block (result i32) (call $dummy) (br 0 (i32.const 1)) (unreachable))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_block_last.wat b/tests/disas/winch/x64/unreachable/as_block_last.wat
index 5c5d35d07..ab32d0e0f 100644
--- a/tests/disas/winch/x64/unreachable/as_block_last.wat
+++ b/tests/disas/winch/x64/unreachable/as_block_last.wat
@@ -6,7 +6,7 @@
     (block (nop) (call $dummy) (unreachable))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_block_mid.wat b/tests/disas/winch/x64/unreachable/as_block_mid.wat
index 3800af484..501df3a27 100644
--- a/tests/disas/winch/x64/unreachable/as_block_mid.wat
+++ b/tests/disas/winch/x64/unreachable/as_block_mid.wat
@@ -7,7 +7,7 @@
     (block (result i32) (call $dummy) (unreachable) (i32.const 2))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_block_value.wat b/tests/disas/winch/x64/unreachable/as_block_value.wat
index 79efcd8da..cf5f8e2a4 100644
--- a/tests/disas/winch/x64/unreachable/as_block_value.wat
+++ b/tests/disas/winch/x64/unreachable/as_block_value.wat
@@ -6,7 +6,7 @@
     (block (result i32) (nop) (call $dummy) (unreachable))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_call_first.wat b/tests/disas/winch/x64/unreachable/as_call_first.wat
index a87de485c..b878ceb5a 100644
--- a/tests/disas/winch/x64/unreachable/as_call_first.wat
+++ b/tests/disas/winch/x64/unreachable/as_call_first.wat
@@ -7,7 +7,7 @@
     (call $dummy3 (unreachable) (i32.const 2) (i32.const 3))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy3:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_call_last.wat b/tests/disas/winch/x64/unreachable/as_call_last.wat
index 6a1f70264..5f4328061 100644
--- a/tests/disas/winch/x64/unreachable/as_call_last.wat
+++ b/tests/disas/winch/x64/unreachable/as_call_last.wat
@@ -8,7 +8,7 @@
     (call $dummy3 (i32.const 1) (i32.const 2) (unreachable))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy3:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_call_mid.wat b/tests/disas/winch/x64/unreachable/as_call_mid.wat
index ad4b01e98..b6b2fc393 100644
--- a/tests/disas/winch/x64/unreachable/as_call_mid.wat
+++ b/tests/disas/winch/x64/unreachable/as_call_mid.wat
@@ -7,7 +7,7 @@
     (call $dummy3 (i32.const 1) (unreachable) (i32.const 3))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy3:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_func_first.wat b/tests/disas/winch/x64/unreachable/as_func_first.wat
index 090a1cb56..c36754b7d 100644
--- a/tests/disas/winch/x64/unreachable/as_func_first.wat
+++ b/tests/disas/winch/x64/unreachable/as_func_first.wat
@@ -6,7 +6,7 @@
     (unreachable) (i32.const -1)
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_func_last.wat b/tests/disas/winch/x64/unreachable/as_func_last.wat
index ca99fde0a..88ad788e0 100644
--- a/tests/disas/winch/x64/unreachable/as_func_last.wat
+++ b/tests/disas/winch/x64/unreachable/as_func_last.wat
@@ -6,7 +6,7 @@
     (call $dummy) (unreachable)
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_func_mid.wat b/tests/disas/winch/x64/unreachable/as_func_mid.wat
index 9e2d8bad0..9173c23d4 100644
--- a/tests/disas/winch/x64/unreachable/as_func_mid.wat
+++ b/tests/disas/winch/x64/unreachable/as_func_mid.wat
@@ -7,7 +7,7 @@
     (call $dummy) (unreachable) (i32.const -1)
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_func_value.wat b/tests/disas/winch/x64/unreachable/as_func_value.wat
index 1ef0748ca..23b75ad14 100644
--- a/tests/disas/winch/x64/unreachable/as_func_value.wat
+++ b/tests/disas/winch/x64/unreachable/as_func_value.wat
@@ -7,7 +7,7 @@
     (call $dummy) (unreachable)
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_loop_broke.wat b/tests/disas/winch/x64/unreachable/as_loop_broke.wat
index c73cd10be..3d5460495 100644
--- a/tests/disas/winch/x64/unreachable/as_loop_broke.wat
+++ b/tests/disas/winch/x64/unreachable/as_loop_broke.wat
@@ -9,7 +9,7 @@
     )
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_loop_last.wat b/tests/disas/winch/x64/unreachable/as_loop_last.wat
index bb4ec5788..e265bcd52 100644
--- a/tests/disas/winch/x64/unreachable/as_loop_last.wat
+++ b/tests/disas/winch/x64/unreachable/as_loop_last.wat
@@ -8,7 +8,7 @@
     (loop (nop) (call $dummy) (unreachable))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11
diff --git a/tests/disas/winch/x64/unreachable/as_loop_mid.wat b/tests/disas/winch/x64/unreachable/as_loop_mid.wat
index 7683284e3..77624e2a3 100644
--- a/tests/disas/winch/x64/unreachable/as_loop_mid.wat
+++ b/tests/disas/winch/x64/unreachable/as_loop_mid.wat
@@ -8,7 +8,7 @@
     (loop (result i32) (call $dummy) (unreachable) (i32.const 2))
   )
 )
-;; wasm[0]::function[0]:
+;; wasm[0]::function[0]::dummy:
 ;;       pushq   %rbp
 ;;       movq    %rsp, %rbp
 ;;       movq    8(%rdi), %r11