Repository: bytecodealliance/wasmtime
Pull request #8136 (2024-03-14 17:54:50)

s390x: Fix ABI vector-lane swap for overflow args
On s390x we support ABIs with little-endian or big-endian vector lane ordering.  When calling to function with a different lane order, vector arguments need to be lane-swapped.  This currently happens for arguments passed in registers, but not for those passed on the stack - that is a bug.

Fixed by swapping stack arguments as well.

Fixes https://github.com/bytecodealliance/wasmtime/issues/8132

<!--
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
-->



Patch:
diff --git a/cranelift/codegen/src/isa/riscv64/lower.isle b/cranelift/codegen/src/isa/riscv64/lower.isle
index df9ebf694..5891cbbe0 100644
--- a/cranelift/codegen/src/isa/riscv64/lower.isle
+++ b/cranelift/codegen/src/isa/riscv64/lower.isle
@@ -1838,21 +1838,29 @@
 ;;
 ;; This allows us to skip the mask expansion step and use the more efficient
 ;; vmerge.vvm instruction.
-(rule 2 (lower (has_type (ty_vec_fits_in_register ty) (bitselect (icmp cc a @ (value_type (ty_vec_fits_in_register cmp_ty)) b) x y)))
+;;
+;; We should be careful to ensure that the mask and the vmerge have the
+;; same type. So that we don't generate a mask with length 16 (i.e. for i8x16), and then
+;; only copy the first few lanes of the result to the destination register because
+;; the bitselect has a different length (i.e. i64x2).
+;;
+;; See: https://github.com/bytecodealliance/wasmtime/issues/8131
+
+(rule 2 (lower (has_type (ty_vec_fits_in_register _ty) (bitselect (icmp cc a @ (value_type (ty_vec_fits_in_register cmp_ty)) b) x y)))
   (let ((mask VReg (gen_icmp_mask cmp_ty cc a b)))
-    (rv_vmerge_vvm y x mask ty)))
+    (rv_vmerge_vvm y x mask cmp_ty)))
 
-(rule 2 (lower (has_type (ty_vec_fits_in_register ty) (bitselect (fcmp cc a @ (value_type (ty_vec_fits_in_register cmp_ty)) b) x y)))
+(rule 2 (lower (has_type (ty_vec_fits_in_register _ty) (bitselect (fcmp cc a @ (value_type (ty_vec_fits_in_register cmp_ty)) b) x y)))
   (let ((mask VReg (gen_fcmp_mask cmp_ty cc a b)))
-    (rv_vmerge_vvm y x mask ty)))
+    (rv_vmerge_vvm y x mask cmp_ty)))
 
-(rule 2 (lower (has_type (ty_vec_fits_in_register ty) (bitselect (bitcast _ (fcmp cc a @ (value_type (ty_vec_fits_in_register cmp_ty)) b)) x y)))
+(rule 2 (lower (has_type (ty_vec_fits_in_register _ty) (bitselect (bitcast _ (fcmp cc a @ (value_type (ty_vec_fits_in_register cmp_ty)) b)) x y)))
   (let ((mask VReg (gen_fcmp_mask cmp_ty cc a b)))
-    (rv_vmerge_vvm y x mask ty)))
+    (rv_vmerge_vvm y x mask cmp_ty)))
 
-(rule 2 (lower (has_type (ty_vec_fits_in_register ty) (bitselect (bitcast _ (icmp cc a @ (value_type (ty_vec_fits_in_register cmp_ty)) b)) x y)))
+(rule 2 (lower (has_type (ty_vec_fits_in_register _ty) (bitselect (bitcast _ (icmp cc a @ (value_type (ty_vec_fits_in_register cmp_ty)) b)) x y)))
   (let ((mask VReg (gen_icmp_mask cmp_ty cc a b)))
-    (rv_vmerge_vvm y x mask ty)))
+    (rv_vmerge_vvm y x mask cmp_ty)))
 
 
 ;;;;;  Rules for `isplit`;;;;;;;;;
diff --git a/cranelift/codegen/src/isa/s390x/inst.isle b/cranelift/codegen/src/isa/s390x/inst.isle
index 54b3649da..74e9b0e3c 100644
--- a/cranelift/codegen/src/isa/s390x/inst.isle
+++ b/cranelift/codegen/src/isa/s390x/inst.isle
@@ -2872,8 +2872,8 @@
       (let ((rev Reg (vec_permute_dw_imm $I64X2 reg 1 reg 0)))
         (vec_rot_imm $I16X8 (vec_rot_imm $I32X4 (vec_rot_imm $I64X2 rev 32) 16) 8)))
 
-;; When passing a vector value in register to a function whose ABI uses
-;; a different lane order than the current function, we need to swap lanes.
+;; When passing a vector value to a function whose ABI uses a different
+;; lane order than the current function, we need to swap lanes.
 ;; The first operand is the lane order used by the callee.
 (decl abi_vec_elt_rev (LaneOrder Type Reg) Reg)
 (rule 4 (abi_vec_elt_rev _ (gpr32_ty ty) reg) reg)
@@ -2948,15 +2948,17 @@
 (rule (copy_reg_to_arg_slot uses lo _ (ABIArgSlot.Reg reg ty ext) src)
       (let ((_ Unit (args_builder_push uses (abi_vec_elt_rev lo ty src) reg)))
         (output_none)))
-(rule (copy_reg_to_arg_slot _ _ base (ABIArgSlot.Stack offset ty ext) src)
-      (side_effect (arg_store (abi_ext_ty ext ty) src (memarg_stack_off base offset))))
+(rule (copy_reg_to_arg_slot _ lo base (ABIArgSlot.Stack offset ty ext) src)
+      (side_effect (arg_store (abi_ext_ty ext ty) (abi_vec_elt_rev lo ty src)
+                              (memarg_stack_off base offset))))
 
 ;; Copy one component of an argument/return value from its slot.
 (decl copy_reg_from_arg_slot (CallRetList LaneOrder i64 ABIArgSlot) Reg)
 (rule (copy_reg_from_arg_slot defs lo _ (ABIArgSlot.Reg reg ty ext))
       (abi_vec_elt_rev lo ty (defs_lookup defs reg)))
-(rule (copy_reg_from_arg_slot _ _ base (ABIArgSlot.Stack offset ty ext))
-      (arg_load (abi_ext_ty ext ty) (memarg_stack_off base offset)))
+(rule (copy_reg_from_arg_slot _ lo base (ABIArgSlot.Stack offset ty ext))
+      (abi_vec_elt_rev lo ty (arg_load (abi_ext_ty ext ty)
+                                       (memarg_stack_off base offset))))
 
 ;; Helper to compute the type of an implicitly extended argument/return value.
 (decl abi_ext_ty (ArgumentExtension Type) Type)
diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md
index f4758b7ef..d6ce4a5d9 100644
--- a/docs/SUMMARY.md
+++ b/docs/SUMMARY.md
@@ -1,16 +1,13 @@
 # Summary
 
 - [Introduction](./introduction.md)
-- [Examples](./examples.md)
-  - [Debugging WebAssembly](./examples-debugging.md)
-    - [Debugging with `gdb` and `lldb`](./examples-debugging-native-debugger.md)
-    - [Debugging with Core Dumps](./examples-debugging-core-dumps.md)
-  - [Profiling WebAssembly](./examples-profiling.md)
-    - [Profiling with Perf](./examples-profiling-perf.md)
-    - [Profiling with VTune](./examples-profiling-vtune.md)
-    - [Profiling with samply](./examples-profiling-samply.md)
-    - [Cross-platform Profiling](./examples-profiling-guest.md)
-  - [Embedding in Rust](./examples-rust-embed.md)
+- [Using the Wasmtime CLI](./cli.md)
+  - [Installation](./cli-install.md)
+  - [CLI Options](./cli-options.md)
+  - [CLI Logging](./cli-logging.md)
+  - [Cache Configuration](./cli-cache.md)
+- [Using the Wasmtime API](./lang.md)
+  - [Rust](./lang-rust.md)
     - [Hello, world!](./examples-rust-hello-world.md)
     - [Calculating the GCD](./examples-rust-gcd.md)
     - [Using Linear Memory](./examples-rust-memory.md)
@@ -19,7 +16,7 @@
     - [Debugging](./examples-rust-debugging.md)
     - [Core Dumps](./examples-rust-core-dumps.md)
     - [Using Multi-Value](./examples-rust-multi-value.md)
-  - [Embedding in C](./examples-c-embed.md)
+  - [C](./lang-c.md)
     - [Hello, World!](./examples-c-hello-world.md)
     - [Calculating the GCD](./examples-c-gcd.md)
     - [Using Linear Memory](./examples-c-memory.md)
@@ -27,21 +24,23 @@
     - [Linking Modules](./examples-c-linking.md)
     - [Debugging](./examples-c-debugging.md)
     - [Using Multi-Value](./examples-c-multi-value.md)
-  - [Checking Guests' Memory Accesses](./wmemcheck.md)
-  - [Building a minimal embedding](./examples-minimal.md)
-- [Using WebAssembly from your language](./lang.md)
-  - [Rust](./lang-rust.md)
-  - [C](./lang-c.md)
   - [Python](./lang-python.md)
   - [.NET](./lang-dotnet.md)
   - [Go](./lang-go.md)
   - [Bash](./lang-bash.md)
   - [Ruby](./lang-ruby.md)
-- [Using the `wasmtime` CLI](./cli.md)
-  - [Installation](./cli-install.md)
-  - [CLI Options](./cli-options.md)
-  - [CLI Logging](./cli-logging.md)
-  - [Cache Configuration](./cli-cache.md)
+  - [Elixir](./lang-elixir.md)
+- [Further Examples](./examples.md)
+  - [Debugging WebAssembly](./examples-debugging.md)
+    - [Debugging with `gdb` and `lldb`](./examples-debugging-native-debugger.md)
+    - [Debugging with Core Dumps](./examples-debugging-core-dumps.md)
+  - [Profiling WebAssembly](./examples-profiling.md)
+    - [Profiling with Perf](./examples-profiling-perf.md)
+    - [Profiling with VTune](./examples-profiling-vtune.md)
+    - [Profiling with samply](./examples-profiling-samply.md)
+    - [Cross-platform Profiling](./examples-profiling-guest.md)
+  - [Checking Guests' Memory Accesses](./wmemcheck.md)
+  - [Building a minimal embedding](./examples-minimal.md)
 - [Stability](stability.md)
   - [Release Process](./stability-release.md)
   - [Tiers of support](./stability-tiers.md)
diff --git a/docs/cli-install.md b/docs/cli-install.md
index b6f98b42b..ffd370f62 100644
--- a/docs/cli-install.md
+++ b/docs/cli-install.md
@@ -2,7 +2,7 @@
 
 Here we'll show you how to install the `wasmtime` command line tool. Note that
 this is distinct from embedding the Wasmtime project into another, for that
-you'll want to consult the [embedding documentation](embed.md).
+you'll want to consult the [embedding documentation](lang.md).
 
 The easiest way to install the `wasmtime` CLI tool is through our installation
 script. Linux and macOS users can execute the following:
diff --git a/docs/examples-c-embed.md b/docs/examples-c-embed.md
index c6dc5b678..57b88955a 100644
--- a/docs/examples-c-embed.md
+++ b/docs/examples-c-embed.md
@@ -1,6 +1,1 @@
-# Embedding in C
-
-This section is intended to showcase the C embedding API for Wasmtime. Full
-reference documentation for the C API [can be found online][online]
-
-[online]: https://bytecodealliance.github.io/wasmtime/c-api/
+# C
diff --git a/docs/examples-profiling.md b/docs/examples-profiling.md
index 348979c03..d1b0ab0c7 100644
--- a/docs/examples-profiling.md
+++ b/docs/examples-profiling.md
@@ -20,14 +20,16 @@ platforms:
 - For Intel's x86 CPUs on Linux or Windows, we support
   [VTune](./examples-profiling-vtune.md).
 
-- For everything else, see the cross-platform profiler below.
+- For Linux and macOS, we support [samply](./examples-profiling-samply.md).
+
+- For everything else, see the [cross-platform
+  profiler](./examples-profiling-guest.md).
 
 The native profilers can measure time spent in WebAssembly guest code as well as
 time spent in the Wasmtime host and potentially even time spent in the kernel.
 This provides a comprehensive view of performance.
 
-If the native profiling tools don't work for you, Wasmtime also provides a
-[cross-platform profiler](./examples-profiling-guest.md). This profiler can only
-measure time spent in WebAssembly guest code, and its timing measurements are
-not as precise as the native profilers. However, it works on every platform that
-Wasmtime supports.
+The cross-platform-profiler can only measure time spent in WebAssembly guest
+code, and its timing measurements are not as precise as the native profilers.
+However, it works on every platform that Wasmtime supports.
+
diff --git a/docs/examples-rust-embed.md b/docs/examples-rust-embed.md
deleted file mode 100644
index 14b4b1ebb..000000000
--- a/docs/examples-rust-embed.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Embedding in Rust
-
-This section is intended to showcase the Rust embedding API for Wasmtime. This
-is done through the [`wasmtime` crate](https://crates.io/crates/wasmtime). In
-addition to browsing the following examples you can also browse the [full API
-documentation](https://docs.rs/wasmtime).
diff --git a/docs/examples.md b/docs/examples.md
index f2cc544ef..1ab9078d1 100644
--- a/docs/examples.md
+++ b/docs/examples.md
@@ -1,4 +1,4 @@
-# Examples
+# Further Examples
 
 The examples contained in this section explain how to use Wasmtime in several
 common scenarios.
diff --git a/docs/lang-c.md b/docs/lang-c.md
index a40cd10d1..5db21c927 100644
--- a/docs/lang-c.md
+++ b/docs/lang-c.md
@@ -1,7 +1,6 @@
-# C
+# Embedding in C
 
-... more coming soon
+This section is intended to showcase the C embedding API for Wasmtime. Full
+reference documentation for the C API [can be found online][online].
 
-In the meantime, have a look at the [C API docs].
-
-[C API docs]: https://bytecodealliance.github.io/wasmtime/c-api/
+[online]: https://bytecodealliance.github.io/wasmtime/c-api/
diff --git a/docs/lang-rust.md b/docs/lang-rust.md
index cc5d57248..9199605a1 100644
--- a/docs/lang-rust.md
+++ b/docs/lang-rust.md
@@ -3,18 +3,16 @@
 This document shows an example of how to embed Wasmtime using the [Rust
 API][apidoc] to execute a simple wasm program. Be sure to also check out the
 [full API documentation][apidoc] for a full listing of what the [`wasmtime`
-crate][wasmtime] has to offer and the [book examples for
-Rust](./examples-rust-embed.md) for more information.
+crate][wasmtime] has to offer.
 
 [apidoc]: https://bytecodealliance.github.io/wasmtime/api/wasmtime/
 [wasmtime]: https://crates.io/crates/wasmtime
 
 ## Creating the WebAssembly to execute
 
-Creation of a WebAssembly file is generally covered by the [Writing
-WebAssembly chapter](./wasm.md), so we'll just assume that you've already got a
-wasm file on hand for the rest of this tutorial. To make things simple we'll
-also just assume you've got a `hello.wat` file which looks like this:
+We'll just assume that you've already got a wasm file on hand for the rest of
+this tutorial. To make things simple we'll also just assume you've got a
+`hello.wat` file which looks like this:
 
 ```wat
 (module
diff --git a/docs/lang.md b/docs/lang.md
index 94e38d1b0..be222bf6e 100644
--- a/docs/lang.md
+++ b/docs/lang.md
@@ -1,4 +1,4 @@
-# Using WebAssembly from your Language
+# Using the Wasmtime API
 
 Wasmtime can be used as a library to embed WebAssembly execution support
 within applications. Wasmtime is written in Rust, but bindings are available


Test patch:
diff --git a/cranelift/filetests/filetests/isa/riscv64/simd-bitselect.clif b/cranelift/filetests/filetests/isa/riscv64/simd-bitselect.clif
index 28c0092ac..eb9186895 100644
--- a/cranelift/filetests/filetests/isa/riscv64/simd-bitselect.clif
+++ b/cranelift/filetests/filetests/isa/riscv64/simd-bitselect.clif
@@ -410,3 +410,115 @@ block0(v0: i64x2, v1: i64x2, v2: f64x2, v3: f64x2):
 ;   addi sp, sp, 0x10
 ;   ret
 
+function %bitselect_i8x16_fcmp_f64x2(i8x16) -> i8x16 fast {
+    const0 = 0x00000000000000000000000000000000
+
+block0(v0: i8x16):
+    v1 = bitcast.f64x2 little v0
+    v2 = fcmp eq v1, v1
+    v3 = bitcast.i8x16 little v2
+    v4 = vconst.i8x16 const0
+    v5 = bitselect.i8x16 v3, v0, v4
+    return v5
+}
+
+; VCode:
+;   addi sp,sp,-16
+;   sd ra,8(sp)
+;   sd fp,0(sp)
+;   mv fp,sp
+; block0:
+;   vle8.v v9,16(fp) #avl=16, #vtype=(e8, m1, ta, ma)
+;   vle8.v v14,[const(0)] #avl=16, #vtype=(e8, m1, ta, ma)
+;   vmfeq.vv v0,v9,v9 #avl=2, #vtype=(e64, m1, ta, ma)
+;   vmerge.vvm v15,v14,v9,v0.t #avl=2, #vtype=(e64, m1, ta, ma)
+;   vse8.v v15,0(a0) #avl=16, #vtype=(e8, m1, ta, ma)
+;   ld ra,8(sp)
+;   ld fp,0(sp)
+;   addi sp,sp,16
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   addi sp, sp, -0x10
+;   sd ra, 8(sp)
+;   sd s0, 0(sp)
+;   mv s0, sp
+; block1: ; offset 0x10
+;   .byte 0x57, 0x70, 0x08, 0xcc
+;   addi t6, s0, 0x10
+;   .byte 0x87, 0x84, 0x0f, 0x02
+;   auipc t6, 0
+;   addi t6, t6, 0x34
+;   .byte 0x07, 0x87, 0x0f, 0x02
+;   .byte 0x57, 0x70, 0x81, 0xcd
+;   .byte 0x57, 0x90, 0x94, 0x62
+;   .byte 0xd7, 0x87, 0xe4, 0x5c
+;   .byte 0x57, 0x70, 0x08, 0xcc
+;   .byte 0xa7, 0x07, 0x05, 0x02
+;   ld ra, 8(sp)
+;   ld s0, 0(sp)
+;   addi sp, sp, 0x10
+;   ret
+;   .byte 0x00, 0x00, 0x00, 0x00
+;   .byte 0x00, 0x00, 0x00, 0x00
+;   .byte 0x00, 0x00, 0x00, 0x00
+;   .byte 0x00, 0x00, 0x00, 0x00
+;   .byte 0x00, 0x00, 0x00, 0x00
+
+function %bitselect_i8x16_icmp_i64x2(i8x16) -> i8x16 fast {
+    const0 = 0x00000000000000000000000000000000
+
+block0(v0: i8x16):
+    v1 = bitcast.i64x2 little v0
+    v2 = icmp eq v1, v1
+    v3 = bitcast.i8x16 little v2
+    v4 = vconst.i8x16 const0
+    v5 = bitselect.i8x16 v3, v0, v4
+    return v5
+}
+
+; VCode:
+;   addi sp,sp,-16
+;   sd ra,8(sp)
+;   sd fp,0(sp)
+;   mv fp,sp
+; block0:
+;   vle8.v v9,16(fp) #avl=16, #vtype=(e8, m1, ta, ma)
+;   vle8.v v14,[const(0)] #avl=16, #vtype=(e8, m1, ta, ma)
+;   vmseq.vv v0,v9,v9 #avl=2, #vtype=(e64, m1, ta, ma)
+;   vmerge.vvm v15,v14,v9,v0.t #avl=2, #vtype=(e64, m1, ta, ma)
+;   vse8.v v15,0(a0) #avl=16, #vtype=(e8, m1, ta, ma)
+;   ld ra,8(sp)
+;   ld fp,0(sp)
+;   addi sp,sp,16
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   addi sp, sp, -0x10
+;   sd ra, 8(sp)
+;   sd s0, 0(sp)
+;   mv s0, sp
+; block1: ; offset 0x10
+;   .byte 0x57, 0x70, 0x08, 0xcc
+;   addi t6, s0, 0x10
+;   .byte 0x87, 0x84, 0x0f, 0x02
+;   auipc t6, 0
+;   addi t6, t6, 0x34
+;   .byte 0x07, 0x87, 0x0f, 0x02
+;   .byte 0x57, 0x70, 0x81, 0xcd
+;   .byte 0x57, 0x80, 0x94, 0x62
+;   .byte 0xd7, 0x87, 0xe4, 0x5c
+;   .byte 0x57, 0x70, 0x08, 0xcc
+;   .byte 0xa7, 0x07, 0x05, 0x02
+;   ld ra, 8(sp)
+;   ld s0, 0(sp)
+;   addi sp, sp, 0x10
+;   ret
+;   .byte 0x00, 0x00, 0x00, 0x00
+;   .byte 0x00, 0x00, 0x00, 0x00
+;   .byte 0x00, 0x00, 0x00, 0x00
+;   .byte 0x00, 0x00, 0x00, 0x00
+;   .byte 0x00, 0x00, 0x00, 0x00
+
diff --git a/cranelift/filetests/filetests/isa/s390x/vec-abi.clif b/cranelift/filetests/filetests/isa/s390x/vec-abi.clif
index 76130443c..f05272f67 100644
--- a/cranelift/filetests/filetests/isa/s390x/vec-abi.clif
+++ b/cranelift/filetests/filetests/isa/s390x/vec-abi.clif
@@ -1,247 +1,391 @@
 test compile precise-output
 target s390x
 
-function %caller_be_to_be(i64x2, i32x4, i16x8, i8x16) -> i32x4 {
-    fn0 = %callee_be(i64x2, i32x4, i16x8, i8x16) -> i32x4
+function %caller_be_to_be(i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16) -> i32x4 {
+    fn0 = %callee_be(i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16) -> i32x4
 
-block0(v0: i64x2, v1: i32x4, v2: i16x8, v3: i8x16):
-    v4 = call fn0(v0, v1, v2, v3)
-    return v4
+block0(v0: i64x2, v1: i32x4, v2: i16x8, v3: i8x16, v4: i64x2, v5: i32x4, v6: i16x8, v7: i8x16, v8: i64x2, v9: i32x4, v10: i16x8, v11: i8x16):
+    v12 = call fn0(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
+    return v12
 }
 
 ; VCode:
 ;   stmg %r14, %r15, 112(%r15)
-;   aghi %r15, -160
-;   virtual_sp_offset_adjust 160
+;   aghi %r15, -224
+;   virtual_sp_offset_adjust 224
 ; block0:
+;   vl %v17, 384(%r15)
+;   vl %v19, 400(%r15)
+;   vl %v21, 416(%r15)
+;   vl %v23, 432(%r15)
+;   vst %v17, 160(%r15)
+;   vst %v19, 176(%r15)
+;   vst %v21, 192(%r15)
+;   vst %v23, 208(%r15)
 ;   bras %r1, 12 ; data %callee_be + 0 ; lg %r4, 0(%r1)
 ;   basr %r14, %r4
-;   lmg %r14, %r15, 272(%r15)
+;   lmg %r14, %r15, 336(%r15)
 ;   br %r14
 ;
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   stmg %r14, %r15, 0x70(%r15)
-;   aghi %r15, -0xa0
+;   aghi %r15, -0xe0
 ; block1: ; offset 0xa
-;   bras %r1, 0x16
+;   vl %v17, 0x180(%r15)
+;   vl %v19, 0x190(%r15)
+;   vl %v21, 0x1a0(%r15)
+;   vl %v23, 0x1b0(%r15)
+;   vst %v17, 0xa0(%r15)
+;   vst %v19, 0xb0(%r15)
+;   vst %v21, 0xc0(%r15)
+;   vst %v23, 0xd0(%r15)
+;   bras %r1, 0x46
 ;   .byte 0x00, 0x00 ; reloc_external Abs8 %callee_be 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   lg %r4, 0(%r1)
 ;   basr %r14, %r4
-;   lmg %r14, %r15, 0x110(%r15)
+;   lmg %r14, %r15, 0x150(%r15)
 ;   br %r14
 
-function %caller_be_to_le(i64x2, i32x4, i16x8, i8x16) -> i32x4 {
-    fn0 = %callee_le(i64x2, i32x4, i16x8, i8x16) -> i32x4 wasmtime_system_v
+function %caller_be_to_le(i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16) -> i32x4 {
+    fn0 = %callee_le(i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16) -> i32x4 wasmtime_system_v
 
-block0(v0: i64x2, v1: i32x4, v2: i16x8, v3: i8x16):
-    v4 = call fn0(v0, v1, v2, v3)
-    return v4
+block0(v0: i64x2, v1: i32x4, v2: i16x8, v3: i8x16, v4: i64x2, v5: i32x4, v6: i16x8, v7: i8x16, v8: i64x2, v9: i32x4, v10: i16x8, v11: i8x16):
+    v12 = call fn0(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
+    return v12
 }
 
 ; VCode:
 ;   stmg %r14, %r15, 112(%r15)
-;   aghi %r15, -224
-;   virtual_sp_offset_adjust 160
-;   std %f8, 160(%r15)
-;   std %f9, 168(%r15)
-;   std %f10, 176(%r15)
-;   std %f11, 184(%r15)
-;   std %f12, 192(%r15)
-;   std %f13, 200(%r15)
-;   std %f14, 208(%r15)
-;   std %f15, 216(%r15)
+;   aghi %r15, -288
+;   virtual_sp_offset_adjust 224
+;   std %f8, 224(%r15)
+;   std %f9, 232(%r15)
+;   std %f10, 240(%r15)
+;   std %f11, 248(%r15)
+;   std %f12, 256(%r15)
+;   std %f13, 264(%r15)
+;   std %f14, 272(%r15)
+;   std %f15, 280(%r15)
 ; block0:
+;   vl %v17, 448(%r15)
+;   vl %v19, 464(%r15)
+;   vl %v21, 480(%r15)
+;   vl %v23, 496(%r15)
 ;   vpdi %v24, %v24, %v24, 4
-;   vpdi %v7, %v25, %v25, 4
-;   verllg %v25, %v7, 32
-;   vpdi %v19, %v26, %v26, 4
-;   verllg %v21, %v19, 32
-;   verllf %v26, %v21, 16
-;   vpdi %v27, %v27, %v27, 4
-;   verllg %v27, %v27, 32
-;   verllf %v29, %v27, 16
-;   verllh %v27, %v29, 8
+;   vpdi %v0, %v25, %v25, 4
+;   verllg %v25, %v0, 32
+;   vpdi %v0, %v26, %v26, 4
+;   verllg %v1, %v0, 32
+;   verllf %v26, %v1, 16
+;   vpdi %v5, %v27, %v27, 4
+;   verllg %v7, %v5, 32
+;   verllf %v18, %v7, 16
+;   verllh %v27, %v18, 8
+;   vpdi %v28, %v28, %v28, 4
+;   vpdi %v29, %v29, %v29, 4
+;   verllg %v29, %v29, 32
+;   vpdi %v30, %v30, %v30, 4
+;   verllg %v30, %v30, 32
+;   verllf %v30, %v30, 16
+;   vpdi %v1, %v31, %v31, 4
+;   verllg %v3, %v1, 32
+;   verllf %v5, %v3, 16
+;   verllh %v31, %v5, 8
+;   vpdi %v17, %v17, %v17, 4
+;   vst %v17, 160(%r15)
+;   vpdi %v20, %v19, %v19, 4
+;   verllg %v22, %v20, 32
+;   vst %v22, 176(%r15)
+;   vpdi %v0, %v21, %v21, 4
+;   verllg %v0, %v0, 32
+;   verllf %v0, %v0, 16
+;   vst %v0, 192(%r15)
+;   vpdi %v0, %v23, %v23, 4
+;   verllg %v2, %v0, 32
+;   verllf %v4, %v2, 16
+;   verllh %v6, %v4, 8
+;   vst %v6, 208(%r15)
 ;   bras %r1, 12 ; data %callee_le + 0 ; lg %r4, 0(%r1)
 ;   basr %r14, %r4
-;   vpdi %v5, %v24, %v24, 4
-;   verllg %v24, %v5, 32
-;   ld %f8, 160(%r15)
-;   ld %f9, 168(%r15)
-;   ld %f10, 176(%r15)
-;   ld %f11, 184(%r15)
-;   ld %f12, 192(%r15)
-;   ld %f13, 200(%r15)
-;   ld %f14, 208(%r15)
-;   ld %f15, 216(%r15)
-;   lmg %r14, %r15, 336(%r15)
+;   vpdi %v21, %v24, %v24, 4
+;   verllg %v24, %v21, 32
+;   ld %f8, 224(%r15)
+;   ld %f9, 232(%r15)
+;   ld %f10, 240(%r15)
+;   ld %f11, 248(%r15)
+;   ld %f12, 256(%r15)
+;   ld %f13, 264(%r15)
+;   ld %f14, 272(%r15)
+;   ld %f15, 280(%r15)
+;   lmg %r14, %r15, 400(%r15)
 ;   br %r14
 ;
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   stmg %r14, %r15, 0x70(%r15)
-;   aghi %r15, -0xe0
-;   std %f8, 0xa0(%r15)
-;   std %f9, 0xa8(%r15)
-;   std %f10, 0xb0(%r15)
-;   std %f11, 0xb8(%r15)
-;   std %f12, 0xc0(%r15)
-;   std %f13, 0xc8(%r15)
-;   std %f14, 0xd0(%r15)
-;   std %f15, 0xd8(%r15)
+;   aghi %r15, -0x120
+;   std %f8, 0xe0(%r15)
+;   std %f9, 0xe8(%r15)
+;   std %f10, 0xf0(%r15)
+;   std %f11, 0xf8(%r15)
+;   std %f12, 0x100(%r15)
+;   std %f13, 0x108(%r15)
+;   std %f14, 0x110(%r15)
+;   std %f15, 0x118(%r15)
 ; block1: ; offset 0x2a
+;   vl %v17, 0x1c0(%r15)
+;   vl %v19, 0x1d0(%r15)
+;   vl %v21, 0x1e0(%r15)
+;   vl %v23, 0x1f0(%r15)
 ;   vpdi %v24, %v24, %v24, 4
-;   vpdi %v7, %v25, %v25, 4
-;   verllg %v25, %v7, 0x20
-;   vpdi %v19, %v26, %v26, 4
-;   verllg %v21, %v19, 0x20
-;   verllf %v26, %v21, 0x10
-;   vpdi %v27, %v27, %v27, 4
-;   verllg %v27, %v27, 0x20
-;   verllf %v29, %v27, 0x10
-;   verllh %v27, %v29, 8
-;   bras %r1, 0x72
+;   vpdi %v0, %v25, %v25, 4
+;   verllg %v25, %v0, 0x20
+;   vpdi %v0, %v26, %v26, 4
+;   verllg %v1, %v0, 0x20
+;   verllf %v26, %v1, 0x10
+;   vpdi %v5, %v27, %v27, 4
+;   verllg %v7, %v5, 0x20
+;   verllf %v18, %v7, 0x10
+;   verllh %v27, %v18, 8
+;   vpdi %v28, %v28, %v28, 4
+;   vpdi %v29, %v29, %v29, 4
+;   verllg %v29, %v29, 0x20
+;   vpdi %v30, %v30, %v30, 4
+;   verllg %v30, %v30, 0x20
+;   verllf %v30, %v30, 0x10
+;   vpdi %v1, %v31, %v31, 4
+;   verllg %v3, %v1, 0x20
+;   verllf %v5, %v3, 0x10
+;   verllh %v31, %v5, 8
+;   vpdi %v17, %v17, %v17, 4
+;   vst %v17, 0xa0(%r15)
+;   vpdi %v20, %v19, %v19, 4
+;   verllg %v22, %v20, 0x20
+;   vst %v22, 0xb0(%r15)
+;   vpdi %v0, %v21, %v21, 4
+;   verllg %v0, %v0, 0x20
+;   verllf %v0, %v0, 0x10
+;   vst %v0, 0xc0(%r15)
+;   vpdi %v0, %v23, %v23, 4
+;   verllg %v2, %v0, 0x20
+;   verllf %v4, %v2, 0x10
+;   verllh %v6, %v4, 8
+;   vst %v6, 0xd0(%r15)
+;   bras %r1, 0x11a
 ;   .byte 0x00, 0x00 ; reloc_external Abs8 %callee_le 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   lg %r4, 0(%r1)
 ;   basr %r14, %r4
-;   vpdi %v5, %v24, %v24, 4
-;   verllg %v24, %v5, 0x20
-;   ld %f8, 0xa0(%r15)
-;   ld %f9, 0xa8(%r15)
-;   ld %f10, 0xb0(%r15)
-;   ld %f11, 0xb8(%r15)
-;   ld %f12, 0xc0(%r15)
-;   ld %f13, 0xc8(%r15)
-;   ld %f14, 0xd0(%r15)
-;   ld %f15, 0xd8(%r15)
-;   lmg %r14, %r15, 0x150(%r15)
+;   vpdi %v21, %v24, %v24, 4
+;   verllg %v24, %v21, 0x20
+;   ld %f8, 0xe0(%r15)
+;   ld %f9, 0xe8(%r15)
+;   ld %f10, 0xf0(%r15)
+;   ld %f11, 0xf8(%r15)
+;   ld %f12, 0x100(%r15)
+;   ld %f13, 0x108(%r15)
+;   ld %f14, 0x110(%r15)
+;   ld %f15, 0x118(%r15)
+;   lmg %r14, %r15, 0x190(%r15)
 ;   br %r14
 
-function %caller_le_to_be(i64x2, i32x4, i16x8, i8x16) -> i32x4 wasmtime_system_v {
-    fn0 = %callee_be(i64x2, i32x4, i16x8, i8x16) -> i32x4
+function %caller_le_to_be(i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16) -> i32x4 wasmtime_system_v {
+    fn0 = %callee_be(i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16) -> i32x4
 
-block0(v0: i64x2, v1: i32x4, v2: i16x8, v3: i8x16):
-    v4 = call fn0(v0, v1, v2, v3)
-    return v4
+block0(v0: i64x2, v1: i32x4, v2: i16x8, v3: i8x16, v4: i64x2, v5: i32x4, v6: i16x8, v7: i8x16, v8: i64x2, v9: i32x4, v10: i16x8, v11: i8x16):
+    v12 = call fn0(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
+    return v12
 }
 
 ; VCode:
 ;   stmg %r14, %r15, 112(%r15)
-;   aghi %r15, -224
-;   virtual_sp_offset_adjust 160
-;   std %f8, 160(%r15)
-;   std %f9, 168(%r15)
-;   std %f10, 176(%r15)
-;   std %f11, 184(%r15)
-;   std %f12, 192(%r15)
-;   std %f13, 200(%r15)
-;   std %f14, 208(%r15)
-;   std %f15, 216(%r15)
+;   aghi %r15, -288
+;   virtual_sp_offset_adjust 224
+;   std %f8, 224(%r15)
+;   std %f9, 232(%r15)
+;   std %f10, 240(%r15)
+;   std %f11, 248(%r15)
+;   std %f12, 256(%r15)
+;   std %f13, 264(%r15)
+;   std %f14, 272(%r15)
+;   std %f15, 280(%r15)
 ; block0:
+;   vl %v17, 448(%r15)
+;   vl %v19, 464(%r15)
+;   vl %v21, 480(%r15)
+;   vl %v23, 496(%r15)
 ;   vpdi %v24, %v24, %v24, 4
-;   vpdi %v7, %v25, %v25, 4
-;   verllg %v25, %v7, 32
-;   vpdi %v19, %v26, %v26, 4
-;   verllg %v21, %v19, 32
-;   verllf %v26, %v21, 16
-;   vpdi %v27, %v27, %v27, 4
-;   verllg %v27, %v27, 32
-;   verllf %v29, %v27, 16
-;   verllh %v27, %v29, 8
+;   vpdi %v0, %v25, %v25, 4
+;   verllg %v25, %v0, 32
+;   vpdi %v0, %v26, %v26, 4
+;   verllg %v1, %v0, 32
+;   verllf %v26, %v1, 16
+;   vpdi %v5, %v27, %v27, 4
+;   verllg %v7, %v5, 32
+;   verllf %v18, %v7, 16
+;   verllh %v27, %v18, 8
+;   vpdi %v28, %v28, %v28, 4
+;   vpdi %v29, %v29, %v29, 4
+;   verllg %v29, %v29, 32
+;   vpdi %v30, %v30, %v30, 4
+;   verllg %v30, %v30, 32
+;   verllf %v30, %v30, 16
+;   vpdi %v1, %v31, %v31, 4
+;   verllg %v3, %v1, 32
+;   verllf %v5, %v3, 16
+;   verllh %v31, %v5, 8
+;   vpdi %v17, %v17, %v17, 4
+;   vst %v17, 160(%r15)
+;   vpdi %v20, %v19, %v19, 4
+;   verllg %v22, %v20, 32
+;   vst %v22, 176(%r15)
+;   vpdi %v0, %v21, %v21, 4
+;   verllg %v0, %v0, 32
+;   verllf %v0, %v0, 16
+;   vst %v0, 192(%r15)
+;   vpdi %v0, %v23, %v23, 4
+;   verllg %v2, %v0, 32
+;   verllf %v4, %v2, 16
+;   verllh %v6, %v4, 8
+;   vst %v6, 208(%r15)
 ;   bras %r1, 12 ; data %callee_be + 0 ; lg %r4, 0(%r1)
 ;   basr %r14, %r4
-;   vpdi %v5, %v24, %v24, 4
-;   verllg %v24, %v5, 32
-;   ld %f8, 160(%r15)
-;   ld %f9, 168(%r15)
-;   ld %f10, 176(%r15)
-;   ld %f11, 184(%r15)
-;   ld %f12, 192(%r15)
-;   ld %f13, 200(%r15)
-;   ld %f14, 208(%r15)
-;   ld %f15, 216(%r15)
-;   lmg %r14, %r15, 336(%r15)
+;   vpdi %v21, %v24, %v24, 4
+;   verllg %v24, %v21, 32
+;   ld %f8, 224(%r15)
+;   ld %f9, 232(%r15)
+;   ld %f10, 240(%r15)
+;   ld %f11, 248(%r15)
+;   ld %f12, 256(%r15)
+;   ld %f13, 264(%r15)
+;   ld %f14, 272(%r15)
+;   ld %f15, 280(%r15)
+;   lmg %r14, %r15, 400(%r15)
 ;   br %r14
 ;
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   stmg %r14, %r15, 0x70(%r15)
-;   aghi %r15, -0xe0
-;   std %f8, 0xa0(%r15)
-;   std %f9, 0xa8(%r15)
-;   std %f10, 0xb0(%r15)
-;   std %f11, 0xb8(%r15)
-;   std %f12, 0xc0(%r15)
-;   std %f13, 0xc8(%r15)
-;   std %f14, 0xd0(%r15)
-;   std %f15, 0xd8(%r15)
+;   aghi %r15, -0x120
+;   std %f8, 0xe0(%r15)
+;   std %f9, 0xe8(%r15)
+;   std %f10, 0xf0(%r15)
+;   std %f11, 0xf8(%r15)
+;   std %f12, 0x100(%r15)
+;   std %f13, 0x108(%r15)
+;   std %f14, 0x110(%r15)
+;   std %f15, 0x118(%r15)
 ; block1: ; offset 0x2a
+;   vl %v17, 0x1c0(%r15)
+;   vl %v19, 0x1d0(%r15)
+;   vl %v21, 0x1e0(%r15)
+;   vl %v23, 0x1f0(%r15)
 ;   vpdi %v24, %v24, %v24, 4
-;   vpdi %v7, %v25, %v25, 4
-;   verllg %v25, %v7, 0x20
-;   vpdi %v19, %v26, %v26, 4
-;   verllg %v21, %v19, 0x20
-;   verllf %v26, %v21, 0x10
-;   vpdi %v27, %v27, %v27, 4
-;   verllg %v27, %v27, 0x20
-;   verllf %v29, %v27, 0x10
-;   verllh %v27, %v29, 8
-;   bras %r1, 0x72
+;   vpdi %v0, %v25, %v25, 4
+;   verllg %v25, %v0, 0x20
+;   vpdi %v0, %v26, %v26, 4
+;   verllg %v1, %v0, 0x20
+;   verllf %v26, %v1, 0x10
+;   vpdi %v5, %v27, %v27, 4
+;   verllg %v7, %v5, 0x20
+;   verllf %v18, %v7, 0x10
+;   verllh %v27, %v18, 8
+;   vpdi %v28, %v28, %v28, 4
+;   vpdi %v29, %v29, %v29, 4
+;   verllg %v29, %v29, 0x20
+;   vpdi %v30, %v30, %v30, 4
+;   verllg %v30, %v30, 0x20
+;   verllf %v30, %v30, 0x10
+;   vpdi %v1, %v31, %v31, 4
+;   verllg %v3, %v1, 0x20
+;   verllf %v5, %v3, 0x10
+;   verllh %v31, %v5, 8
+;   vpdi %v17, %v17, %v17, 4
+;   vst %v17, 0xa0(%r15)
+;   vpdi %v20, %v19, %v19, 4
+;   verllg %v22, %v20, 0x20
+;   vst %v22, 0xb0(%r15)
+;   vpdi %v0, %v21, %v21, 4
+;   verllg %v0, %v0, 0x20
+;   verllf %v0, %v0, 0x10
+;   vst %v0, 0xc0(%r15)
+;   vpdi %v0, %v23, %v23, 4
+;   verllg %v2, %v0, 0x20
+;   verllf %v4, %v2, 0x10
+;   verllh %v6, %v4, 8
+;   vst %v6, 0xd0(%r15)
+;   bras %r1, 0x11a
 ;   .byte 0x00, 0x00 ; reloc_external Abs8 %callee_be 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   lg %r4, 0(%r1)
 ;   basr %r14, %r4
-;   vpdi %v5, %v24, %v24, 4
-;   verllg %v24, %v5, 0x20
-;   ld %f8, 0xa0(%r15)
-;   ld %f9, 0xa8(%r15)
-;   ld %f10, 0xb0(%r15)
-;   ld %f11, 0xb8(%r15)
-;   ld %f12, 0xc0(%r15)
-;   ld %f13, 0xc8(%r15)
-;   ld %f14, 0xd0(%r15)
-;   ld %f15, 0xd8(%r15)
-;   lmg %r14, %r15, 0x150(%r15)
+;   vpdi %v21, %v24, %v24, 4
+;   verllg %v24, %v21, 0x20
+;   ld %f8, 0xe0(%r15)
+;   ld %f9, 0xe8(%r15)
+;   ld %f10, 0xf0(%r15)
+;   ld %f11, 0xf8(%r15)
+;   ld %f12, 0x100(%r15)
+;   ld %f13, 0x108(%r15)
+;   ld %f14, 0x110(%r15)
+;   ld %f15, 0x118(%r15)
+;   lmg %r14, %r15, 0x190(%r15)
 ;   br %r14
 
-function %caller_le_to_le(i64x2, i32x4, i16x8, i8x16) -> i32x4 wasmtime_system_v {
-    fn0 = %callee_le(i64x2, i32x4, i16x8, i8x16) -> i32x4 wasmtime_system_v
+function %caller_le_to_le(i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16) -> i32x4 wasmtime_system_v {
+    fn0 = %callee_le(i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16, i64x2, i32x4, i16x8, i8x16) -> i32x4 wasmtime_system_v
 
-block0(v0: i64x2, v1: i32x4, v2: i16x8, v3: i8x16):
-    v4 = call fn0(v0, v1, v2, v3)
-    return v4
+block0(v0: i64x2, v1: i32x4, v2: i16x8, v3: i8x16, v4: i64x2, v5: i32x4, v6: i16x8, v7: i8x16, v8: i64x2, v9: i32x4, v10: i16x8, v11: i8x16):
+    v12 = call fn0(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
+    return v12
 }
 
 ; VCode:
 ;   stmg %r14, %r15, 112(%r15)
-;   aghi %r15, -160
-;   virtual_sp_offset_adjust 160
+;   aghi %r15, -224
+;   virtual_sp_offset_adjust 224
 ; block0:
+;   vl %v17, 384(%r15)
+;   vl %v19, 400(%r15)
+;   vl %v21, 416(%r15)
+;   vl %v23, 432(%r15)
+;   vst %v17, 160(%r15)
+;   vst %v19, 176(%r15)
+;   vst %v21, 192(%r15)
+;   vst %v23, 208(%r15)
 ;   bras %r1, 12 ; data %callee_le + 0 ; lg %r4, 0(%r1)
 ;   basr %r14, %r4
-;   lmg %r14, %r15, 272(%r15)
+;   lmg %r14, %r15, 336(%r15)
 ;   br %r14
 ;
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   stmg %r14, %r15, 0x70(%r15)
-;   aghi %r15, -0xa0
+;   aghi %r15, -0xe0
 ; block1: ; offset 0xa
-;   bras %r1, 0x16
+;   vl %v17, 0x180(%r15)
+;   vl %v19, 0x190(%r15)
+;   vl %v21, 0x1a0(%r15)
+;   vl %v23, 0x1b0(%r15)
+;   vst %v17, 0xa0(%r15)
+;   vst %v19, 0xb0(%r15)
+;   vst %v21, 0xc0(%r15)
+;   vst %v23, 0xd0(%r15)
+;   bras %r1, 0x46
 ;   .byte 0x00, 0x00 ; reloc_external Abs8 %callee_le 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   lg %r4, 0(%r1)
 ;   basr %r14, %r4
-;   lmg %r14, %r15, 0x110(%r15)
+;   lmg %r14, %r15, 0x150(%r15)
 ;   br %r14
 
diff --git a/cranelift/filetests/filetests/runtests/simd-bitselect.clif b/cranelift/filetests/filetests/runtests/simd-bitselect.clif
index 7d250c779..6c399ee03 100644
--- a/cranelift/filetests/filetests/runtests/simd-bitselect.clif
+++ b/cranelift/filetests/filetests/runtests/simd-bitselect.clif
@@ -94,3 +94,37 @@ block0(v0: i64x2, v1: i64x2, v2: i64x2):
 ; run: %bitwise_bitselect_i64x2(0x11111111111111111111111111111111, 0x11111111111111111111111111111111, 0x00000000000000000000000000000000) == 0x11111111111111111111111111111111
 ; run: %bitwise_bitselect_i64x2(0x01010011000011110000000011111111, 0x11111111111111111111111111111111, 0x00000000000000000000000000000000) == 0x01010011000011110000000011111111
 ; run: %bitwise_bitselect_i64x2(0x00000000000000001111111111111111, 0x00000000000000000000000000000000, 0x11111111111111111111111111111111) == 0x11111111111111110000000000000000
+
+
+;; See issue #8131
+;;
+;; These tests test the fusion of `bitselect+bitcast+{f,i}cmp` that
+;; some backends perform. Importantly the `fcmp` and the `bitselect`
+;; have both different type sizes as well as a different number of
+;; lanes.
+
+function %bitselect_i8x16_fcmp_f64x2(i8x16) -> i8x16 fast {
+    const0 = 0x00000000000000000000000000000000
+
+block0(v0: i8x16):
+    v1 = bitcast.f64x2 little v0
+    v2 = fcmp eq v1, v1
+    v3 = bitcast.i8x16 little v2
+    v4 = vconst.i8x16 const0
+    v5 = bitselect.i8x16 v3, v0, v4  ; v3 = const0
+    return v5
+}
+; run: %bitselect_i8x16_fcmp_f64x2(0x80808080808080808080808080808080) == 0x80808080808080808080808080808080
+
+function %bitselect_i8x16_icmp_i64x2(i8x16) -> i8x16 fast {
+    const0 = 0x00000000000000000000000000000000
+
+block0(v0: i8x16):
+    v1 = bitcast.i64x2 little v0
+    v2 = icmp eq v1, v1
+    v3 = bitcast.i8x16 little v2
+    v4 = vconst.i8x16 const0
+    v5 = bitselect.i8x16 v3, v0, v4  ; v3 = const0
+    return v5
+}
+; run: %bitselect_i8x16_icmp_i64x2(0x80808080808080808080808080808080) == 0x80808080808080808080808080808080