Repository: bytecodealliance/wasmtime (rust)

Issue:
Corruption (?) with simd + winch + fuel on spec tests
Found via OSS-Fuzz this fails locally:

```
$ cargo run -q wast -C compiler=winch ./tests/spec_testsuite/simd_load_extend.wast -W fuel=$((1<<62))
Error: failed to run script file './tests/spec_testsuite/simd_load_extend.wast'

Caused by:
    0: failed directive on ./tests/spec_testsuite/simd_load_extend.wast:163:1
    1: error while executing at wasm backtrace:
           0: <unknown>!<wasm function 0>
    2: wasm trap: all fuel consumed by WebAssembly
```

while this passes:

```
$ cargo run -q wast -C compiler=winch ./tests/spec_testsuite/simd_load_extend.wast
```

Bisection points at https://github.com/bytecodealliance/wasmtime/pull/9950 so I think this isn't a regression and it was just discovered via fuzzing recently. (cc @jeffcharles)

Pull request:
Winch: Fix Wasm vector loads to operate on 64-bits
<!--
Please make sure you include the following information:

- If this work has been discussed elsewhere, please include a link to that
  conversation. If it was discussed in an issue, just mention "issue #...".

- Explain why this change is needed. If the details are in an issue already,
  this can be brief.

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->
Fixes #10115. Wasm vector loads operate on 64 bits of memory so update `LoadKind::derive_operand_size` to return that result for vector loads. This will result in [the value containing the offset with access size](https://github.com/bytecodealliance/wasmtime/blob/1bd66bf65ba96a397d75e51f44c9bc79a1615ff8/winch/codegen/src/codegen/mod.rs#L673) to be set so that bounds are enforced correctly.

Patch:
diff --git a/winch/codegen/src/masm.rs b/winch/codegen/src/masm.rs
index 880080cfa..430eacc38 100644
--- a/winch/codegen/src/masm.rs
+++ b/winch/codegen/src/masm.rs
@@ -444,24 +444,12 @@ impl LoadKind {
     pub(crate) fn derive_operand_size(&self) -> OperandSize {
         match self {
             Self::ScalarExtend(scalar) => Self::operand_size_for_scalar(scalar),
-            Self::VectorExtend(vector) => Self::operand_size_for_vector(vector),
+            Self::VectorExtend(_) => OperandSize::S64,
             Self::Splat(kind) => Self::operand_size_for_splat(kind),
             Self::Operand(op) => *op,
         }
     }
 
-    fn operand_size_for_vector(vector: &VectorExtendKind) -> OperandSize {
-        match vector {
-            VectorExtendKind::V128Extend8x8S | VectorExtendKind::V128Extend8x8U => OperandSize::S8,
-            VectorExtendKind::V128Extend16x4S | VectorExtendKind::V128Extend16x4U => {
-                OperandSize::S16
-            }
-            VectorExtendKind::V128Extend32x2S | VectorExtendKind::V128Extend32x2U => {
-                OperandSize::S32
-            }
-        }
-    }
-
     fn operand_size_for_scalar(extend_kind: &ExtendKind) -> OperandSize {
         match extend_kind {
             ExtendKind::Signed(s) => s.from_size(),


Test patch:
diff --git a/tests/disas/winch/x64/load/v128_load32x2_s_oob_avx.wat b/tests/disas/winch/x64/load/v128_load32x2_s_oob_avx.wat
new file mode 100644
index 000000000..00942ca80
--- /dev/null
+++ b/tests/disas/winch/x64/load/v128_load32x2_s_oob_avx.wat
@@ -0,0 +1,40 @@
+;;! target = "x86_64"
+;;! test = "winch"
+;;! flags = [ "-Ccranelift-has-avx=true", "-Omemory-reservation=0" ]
+
+(module
+  (memory (data "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\a0\7f"))
+
+  (func (export "v128.load32x2_s") (result v128) (v128.load32x2_s (i32.const 65529)))
+)
+;; wasm[0]::function[0]:
+;;       pushq   %rbp
+;;       movq    %rsp, %rbp
+;;       movq    8(%rdi), %r11
+;;       movq    0x10(%r11), %r11
+;;       addq    $0x10, %r11
+;;       cmpq    %rsp, %r11
+;;       ja      0x6d
+;;   1c: movq    %rdi, %r14
+;;       subq    $0x10, %rsp
+;;       movq    %rdi, 8(%rsp)
+;;       movq    %rsi, (%rsp)
+;;       movl    $0xfff9, %eax
+;;       movq    $0x10000, %rcx
+;;       movl    %eax, %edx
+;;       addq    $8, %rdx
+;;       jb      0x6f
+;;   44: cmpq    %rcx, %rdx
+;;       ja      0x71
+;;   4d: movq    0x50(%r14), %rbx
+;;       addq    %rax, %rbx
+;;       movq    $0, %rsi
+;;       cmpq    %rcx, %rdx
+;;       cmovaq  %rsi, %rbx
+;;       vpmovsxdq (%rbx), %xmm0
+;;       addq    $0x10, %rsp
+;;       popq    %rbp
+;;       retq
+;;   6d: ud2
+;;   6f: ud2
+;;   71: ud2
diff --git a/tests/disas/winch/x64/load/v128_load32x2_u_oob_avx.wat b/tests/disas/winch/x64/load/v128_load32x2_u_oob_avx.wat
new file mode 100644
index 000000000..f36b9042c
--- /dev/null
+++ b/tests/disas/winch/x64/load/v128_load32x2_u_oob_avx.wat
@@ -0,0 +1,40 @@
+;;! target = "x86_64"
+;;! test = "winch"
+;;! flags = [ "-Ccranelift-has-avx=true", "-Omemory-reservation=0" ]
+
+(module
+  (memory (data "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\a0\7f"))
+
+  (func (export "v128.load32x2_u") (result v128) (v128.load32x2_u (i32.const 65529)))
+)
+;; wasm[0]::function[0]:
+;;       pushq   %rbp
+;;       movq    %rsp, %rbp
+;;       movq    8(%rdi), %r11
+;;       movq    0x10(%r11), %r11
+;;       addq    $0x10, %r11
+;;       cmpq    %rsp, %r11
+;;       ja      0x6d
+;;   1c: movq    %rdi, %r14
+;;       subq    $0x10, %rsp
+;;       movq    %rdi, 8(%rsp)
+;;       movq    %rsi, (%rsp)
+;;       movl    $0xfff9, %eax
+;;       movq    $0x10000, %rcx
+;;       movl    %eax, %edx
+;;       addq    $8, %rdx
+;;       jb      0x6f
+;;   44: cmpq    %rcx, %rdx
+;;       ja      0x71
+;;   4d: movq    0x50(%r14), %rbx
+;;       addq    %rax, %rbx
+;;       movq    $0, %rsi
+;;       cmpq    %rcx, %rdx
+;;       cmovaq  %rsi, %rbx
+;;       vpmovzxdq (%rbx), %xmm0
+;;       addq    $0x10, %rsp
+;;       popq    %rbp
+;;       retq
+;;   6d: ud2
+;;   6f: ud2
+;;   71: ud2