Repository: bytecodealliance/wasmtime
Pull request #8409 (2024-04-19 02:16:49)

x64: Add AVX-encoded versions of `ucomis{s,d}` and `ptest`
This PR finishes the support of AVX instructions in Cranelift (to my knowledge at least). These last few instrucitons were omitted historically because I never got around to sorting the story with comparisons. That's now sorted out, leading to this PR.

Note that this PR is broken into separate commits which lead up to and enable the final change to "drop in" AVX support.


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index ea48ab4d5..37c6ede4d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -849,7 +849,7 @@ dependencies = [
  "serde_derive",
  "smallvec",
  "target-lexicon",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
  "wasmtime-types",
  "wat",
 ]
@@ -2756,7 +2756,7 @@ dependencies = [
  "cargo_metadata",
  "heck",
  "wasmtime",
- "wit-component 0.204.0",
+ "wit-component 0.205.0",
 ]
 
 [[package]]
@@ -3092,7 +3092,7 @@ name = "verify-component-adapter"
 version = "21.0.0"
 dependencies = [
  "anyhow",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
  "wat",
 ]
 
@@ -3184,7 +3184,7 @@ dependencies = [
  "byte-array-literals",
  "object 0.33.0",
  "wasi",
- "wasm-encoder 0.204.0",
+ "wasm-encoder 0.205.0",
  "wit-bindgen",
 ]
 
@@ -3253,9 +3253,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-encoder"
-version = "0.204.0"
+version = "0.205.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "500cbde9b4d8dfc0335ec729d226dbf083e51e47501ac71e6addaed10ccb0a51"
+checksum = "90e95b3563d164f33c1cfb0a7efbd5940c37710019be10cd09f800fdec8b0e5c"
 dependencies = [
  "leb128",
 ]
@@ -3278,9 +3278,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-metadata"
-version = "0.204.0"
+version = "0.205.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f33b61754be27af5abf0fda890badb7c3265f7b634077157b4214704303ebbcc"
+checksum = "e9855ad6dd4d099fa8505f01fb0b84c7e3efd5f555207329e3ad938d5f394fe7"
 dependencies = [
  "anyhow",
  "indexmap 2.0.0",
@@ -3288,36 +3288,36 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "spdx",
- "wasm-encoder 0.204.0",
- "wasmparser 0.204.0",
+ "wasm-encoder 0.205.0",
+ "wasmparser 0.205.0",
 ]
 
 [[package]]
 name = "wasm-mutate"
-version = "0.204.0"
+version = "0.205.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34d24ec979ae72a27f3770a7db426e7f2d459e67ecf26983ca727675e4956037"
+checksum = "d92842509e0cc163a0f8f4a54e38ec180e18594b9ed3999d0a05108e70d25cb3"
 dependencies = [
  "egg",
  "log",
  "rand",
  "thiserror",
- "wasm-encoder 0.204.0",
- "wasmparser 0.204.0",
+ "wasm-encoder 0.205.0",
+ "wasmparser 0.205.0",
 ]
 
 [[package]]
 name = "wasm-smith"
-version = "0.204.0"
+version = "0.205.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1fe1d435b8a14ebf05c2669cf76d1ca1cef6b632320c8e0b0e703ff0259a328"
+checksum = "1218f393276f7a13f6c54467434633144b46c33ecbc3cbafdc938033f0315d1a"
 dependencies = [
  "anyhow",
  "arbitrary",
  "flagset",
  "indexmap 2.0.0",
  "leb128",
- "wasm-encoder 0.204.0",
+ "wasm-encoder 0.205.0",
 ]
 
 [[package]]
@@ -3373,9 +3373,9 @@ dependencies = [
 
 [[package]]
 name = "wasmparser"
-version = "0.204.0"
+version = "0.205.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1239d539d9b92489cf729d40df694a62b09f5159f2ab058f4de15d4f820d6585"
+checksum = "1d457bb52804242e09d55a306e53ddbc65d1d29ed83db6a4eea3ed412ee0cfdf"
 dependencies = [
  "bitflags 2.4.1",
  "indexmap 2.0.0",
@@ -3393,12 +3393,12 @@ dependencies = [
 
 [[package]]
 name = "wasmprinter"
-version = "0.204.0"
+version = "0.205.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce3e6a3111855bf59cb6a16a95e217c59eff1d30d9f09483039b81b0739c3128"
+checksum = "edcd1e00bc348d4b1c0abe913d86f4a89377cbd5c1c704d4eca5cf3492a27da8"
 dependencies = [
  "anyhow",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
 ]
 
 [[package]]
@@ -3430,8 +3430,8 @@ dependencies = [
  "target-lexicon",
  "tempfile",
  "wasi-common",
- "wasm-encoder 0.204.0",
- "wasmparser 0.204.0",
+ "wasm-encoder 0.205.0",
+ "wasmparser 0.205.0",
  "wasmtime-cache",
  "wasmtime-component-macro",
  "wasmtime-component-util",
@@ -3571,7 +3571,7 @@ dependencies = [
  "tracing",
  "walkdir",
  "wasi-common",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
  "wasmtime",
  "wasmtime-cache",
  "wasmtime-cli-flags",
@@ -3585,10 +3585,10 @@ dependencies = [
  "wasmtime-wasi-nn",
  "wasmtime-wasi-threads",
  "wasmtime-wast",
- "wast 204.0.0",
+ "wast 205.0.0",
  "wat",
  "windows-sys 0.52.0",
- "wit-component 0.204.0",
+ "wit-component 0.205.0",
 ]
 
 [[package]]
@@ -3617,7 +3617,7 @@ dependencies = [
  "wasmtime",
  "wasmtime-component-util",
  "wasmtime-wit-bindgen",
- "wit-parser 0.204.0",
+ "wit-parser 0.205.0",
 ]
 
 [[package]]
@@ -3641,7 +3641,7 @@ dependencies = [
  "object 0.33.0",
  "target-lexicon",
  "thiserror",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
  "wasmtime-environ",
  "wasmtime-versioned-export-macros",
 ]
@@ -3665,8 +3665,8 @@ dependencies = [
  "serde_derive",
  "target-lexicon",
  "thiserror",
- "wasm-encoder 0.204.0",
- "wasmparser 0.204.0",
+ "wasm-encoder 0.205.0",
+ "wasmparser 0.205.0",
  "wasmprinter",
  "wasmtime-component-util",
  "wasmtime-types",
@@ -3681,7 +3681,7 @@ dependencies = [
  "component-fuzz-util",
  "env_logger",
  "libfuzzer-sys",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
  "wasmprinter",
  "wasmtime-environ",
  "wat",
@@ -3738,7 +3738,7 @@ dependencies = [
  "rand",
  "smallvec",
  "target-lexicon",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
  "wasmtime",
  "wasmtime-fuzzing",
 ]
@@ -3758,12 +3758,12 @@ dependencies = [
  "target-lexicon",
  "tempfile",
  "v8",
- "wasm-encoder 0.204.0",
+ "wasm-encoder 0.205.0",
  "wasm-mutate",
  "wasm-smith",
  "wasm-spec-interpreter",
  "wasmi",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
  "wasmprinter",
  "wasmtime",
  "wasmtime-wast",
@@ -3810,7 +3810,7 @@ dependencies = [
  "rand",
  "rustix",
  "sptr",
- "wasm-encoder 0.204.0",
+ "wasm-encoder 0.205.0",
  "wasmtime-asm-macros",
  "wasmtime-environ",
  "wasmtime-fiber",
@@ -3833,7 +3833,7 @@ dependencies = [
  "serde",
  "serde_derive",
  "thiserror",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
 ]
 
 [[package]]
@@ -3940,7 +3940,7 @@ dependencies = [
  "anyhow",
  "log",
  "wasmtime",
- "wast 204.0.0",
+ "wast 205.0.0",
 ]
 
 [[package]]
@@ -3952,7 +3952,7 @@ dependencies = [
  "gimli",
  "object 0.33.0",
  "target-lexicon",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
  "wasmtime-cranelift",
  "wasmtime-environ",
  "winch-codegen",
@@ -3965,7 +3965,7 @@ dependencies = [
  "anyhow",
  "heck",
  "indexmap 2.0.0",
- "wit-parser 0.204.0",
+ "wit-parser 0.205.0",
 ]
 
 [[package]]
@@ -3983,24 +3983,24 @@ dependencies = [
 
 [[package]]
 name = "wast"
-version = "204.0.0"
+version = "205.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0e3de19692b3d4c2fa13775271a751935decf530ae59c408c9f0b510b4ead62"
+checksum = "441a6a195b3b5245e26d450bbcc91366c6b652382a22f63cbe3c73240e13b2bb"
 dependencies = [
  "bumpalo",
  "leb128",
  "memchr",
  "unicode-width",
- "wasm-encoder 0.204.0",
+ "wasm-encoder 0.205.0",
 ]
 
 [[package]]
 name = "wat"
-version = "1.204.0"
+version = "1.205.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4280322d523214024d03bc05e25bdda6088d5229d9515aecd78c5914b1f3e734"
+checksum = "19832624d606e7c6bf3cd4caa73578ecec5eac30c768269256d19c79900beb18"
 dependencies = [
- "wast 204.0.0",
+ "wast 205.0.0",
 ]
 
 [[package]]
@@ -4130,7 +4130,7 @@ dependencies = [
  "regalloc2",
  "smallvec",
  "target-lexicon",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
  "wasmtime-cranelift",
  "wasmtime-environ",
 ]
@@ -4381,9 +4381,9 @@ dependencies = [
 
 [[package]]
 name = "wit-component"
-version = "0.204.0"
+version = "0.205.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "657fab6fd5f9ad3e1b7fd65a76f06ff25cac7f4fd8f885715bed4147095a6c38"
+checksum = "74841e17b2c2bfbd8ca8c45190ef85dff1c5e8659f0e2d164802ffc87dfb18c3"
 dependencies = [
  "anyhow",
  "bitflags 2.4.1",
@@ -4392,10 +4392,10 @@ dependencies = [
  "serde",
  "serde_derive",
  "serde_json",
- "wasm-encoder 0.204.0",
- "wasm-metadata 0.204.0",
- "wasmparser 0.204.0",
- "wit-parser 0.204.0",
+ "wasm-encoder 0.205.0",
+ "wasm-metadata 0.205.0",
+ "wasmparser 0.205.0",
+ "wit-parser 0.205.0",
 ]
 
 [[package]]
@@ -4418,9 +4418,9 @@ dependencies = [
 
 [[package]]
 name = "wit-parser"
-version = "0.204.0"
+version = "0.205.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdc20f9284017574e942347e953e82fb3a0dccdfafa3beea7840b0bcbfa4fe00"
+checksum = "a3db34c7688c161ed7bd1b2f8055dca9fb2c15201db58754e9c48a0805f32e5f"
 dependencies = [
  "anyhow",
  "id-arena",
@@ -4431,7 +4431,7 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "unicode-xid",
- "wasmparser 0.204.0",
+ "wasmparser 0.205.0",
 ]
 
 [[package]]
diff --git a/Cargo.toml b/Cargo.toml
index ab812cbc6..f137a2e26 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -234,15 +234,15 @@ rustix = "0.38.31"
 wit-bindgen = { version = "0.22.0", default-features = false }
 
 # wasm-tools family:
-wasmparser = "0.204.0"
-wat = "1.204.0"
-wast = "204.0.0"
-wasmprinter = "0.204.0"
-wasm-encoder = "0.204.0"
-wasm-smith = "0.204.0"
-wasm-mutate = "0.204.0"
-wit-parser = "0.204.0"
-wit-component = "0.204.0"
+wasmparser = "0.205.0"
+wat = "1.205.0"
+wast = "205.0.0"
+wasmprinter = "0.205.0"
+wasm-encoder = "0.205.0"
+wasm-smith = "0.205.0"
+wasm-mutate = "0.205.0"
+wit-parser = "0.205.0"
+wit-component = "0.205.0"
 
 # Non-Bytecode Alliance maintained dependencies:
 # --------------------------
diff --git a/RELEASES.md b/RELEASES.md
index 84af9edc6..5b232971f 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -139,6 +139,22 @@ Unreleased.
 
 --------------------------------------------------------------------------------
 
+## 19.0.2
+
+Released 2024-04-11.
+
+* Fix a panic when compiling invalid components.
+  [#8323](https://github.com/bytecodealliance/wasmtime/issues/8323)
+
+* Fix `bindgen!` with `trappable_error_type` using unversioned/versioned
+  packages.
+  [#8305](https://github.com/bytecodealliance/wasmtime/pull/8305)
+
+* cranelift: Include clobbers and outgoing args in stack limit.
+  [#8301](https://github.com/bytecodealliance/wasmtime/pull/8301)
+
+--------------------------------------------------------------------------------
+
 ## 19.0.1
 
 Released 2024-04-02.
@@ -248,6 +264,24 @@ Released 2024-03-20
 
 --------------------------------------------------------------------------------
 
+## 18.0.4
+
+Released 2024-04-11
+
+### Fixed
+
+* Fix `bindgen!` with `trappable_error_type` using unversioned/versioned
+  packages.
+  [#8305](https://github.com/bytecodealliance/wasmtime/pull/8305)
+
+* cranelift: Include clobbers and outgoing args in stack limit.
+  [#8301](https://github.com/bytecodealliance/wasmtime/pull/8301)
+
+* Fix a panic when compiling invalid components.
+  [#8323](https://github.com/bytecodealliance/wasmtime/issues/8323)
+
+--------------------------------------------------------------------------------
+
 ## 18.0.3
 
 Released 2024-03-12
@@ -333,6 +367,20 @@ Released 2024-02-20
 
 --------------------------------------------------------------------------------
 
+## 17.0.3
+
+Released 2024-04-11
+
+### Fixed
+
+* cranelift: Include clobbers and outgoing args in stack limit.
+  [#8301](https://github.com/bytecodealliance/wasmtime/pull/8301)
+
+* Fix a panic when compiling invalid components.
+  [#8323](https://github.com/bytecodealliance/wasmtime/issues/8323)
+
+--------------------------------------------------------------------------------
+
 ## 17.0.2
 
 Released 2024-02-28
diff --git a/cranelift/codegen/src/isa/x64/inst.isle b/cranelift/codegen/src/isa/x64/inst.isle
index 84c498808..788a3b282 100644
--- a/cranelift/codegen/src/isa/x64/inst.isle
+++ b/cranelift/codegen/src/isa/x64/inst.isle
@@ -367,6 +367,10 @@
                     (dst WritableGpr)
                     (dst_size OperandSize))
 
+       ;; Float comparisons/tests: cmp (b w l q) (reg addr imm) reg.
+       (XmmCmpRmRVex (op AvxOpcode)
+                     (src1 Xmm)
+                     (src2 XmmMem))
 
        ;; XMM (scalar or vector) binary op that relies on the EVEX
        ;; prefix. Takes two inputs.
@@ -1413,6 +1417,9 @@
             Vsqrtsd
             Vroundss
             Vroundsd
+            Vucomiss
+            Vucomisd
+            Vptest
           ))
 
 (type Avx512Opcode
@@ -2817,14 +2824,24 @@
       (ProducesFlags.ProducesFlagsSideEffect
        (MInst.XmmCmpRmR opcode src1 src2)))
 
+;; Helper for creating `MInst.XmmCmpRmRVex` instructions.
+(decl xmm_cmp_rm_r_vex (AvxOpcode Xmm XmmMem) ProducesFlags)
+(rule (xmm_cmp_rm_r_vex opcode src1 src2)
+      (ProducesFlags.ProducesFlagsSideEffect
+       (MInst.XmmCmpRmRVex opcode src1 src2)))
+
 ;; Helper for creating floating-point comparison instructions (`UCOMIS[S|D]`).
-(decl x64_ucomis (Value Value) ProducesFlags)
-(rule (x64_ucomis src1 @ (value_type $F32) src2)
-      ;; N.B.: cmp can be generated more than once, so cannot do a
-      ;; load-op merge. So `put_in_xmm` for src1, not `put_in_xmm_mem`.
-      (xmm_cmp_rm_r (SseOpcode.Ucomiss) (put_in_xmm src1) (put_in_xmm src2)))
-(rule (x64_ucomis src1 @ (value_type $F64) src2)
-      (xmm_cmp_rm_r (SseOpcode.Ucomisd) (put_in_xmm src1) (put_in_xmm src2)))
+(decl x64_ucomis (Type Xmm XmmMem) ProducesFlags)
+(rule (x64_ucomis $F32 src1 src2)
+      (xmm_cmp_rm_r (SseOpcode.Ucomiss) src1 src2))
+(rule (x64_ucomis $F64 src1 src2)
+      (xmm_cmp_rm_r (SseOpcode.Ucomisd) src1 src2))
+(rule 1 (x64_ucomis $F32 src1 src2)
+        (if-let $true (use_avx))
+        (xmm_cmp_rm_r_vex (AvxOpcode.Vucomiss) src1 src2))
+(rule 1 (x64_ucomis $F64 src1 src2)
+        (if-let $true (use_avx))
+        (xmm_cmp_rm_r_vex (AvxOpcode.Vucomisd) src1 src2))
 
 ;; Helper for creating `test` instructions.
 (decl x64_test (OperandSize GprMemImm Gpr) ProducesFlags)
@@ -2835,6 +2852,9 @@
 (decl x64_ptest (Xmm XmmMem) ProducesFlags)
 (rule (x64_ptest src1 src2)
       (xmm_cmp_rm_r (SseOpcode.Ptest) src1 src2))
+(rule 1 (x64_ptest src1 src2)
+        (if-let $true (use_avx))
+        (xmm_cmp_rm_r_vex (AvxOpcode.Vptest) src1 src2))
 
 ;; Helper for creating `cmove` instructions. Note that these instructions do not
 ;; always result in a single emitted x86 instruction; e.g., XmmCmove uses jumps
@@ -4881,46 +4901,46 @@
 ;;  - equal assigns        Z = 1, P = 0, C = 0
 (decl emit_fcmp (FloatCC Value Value) FcmpCondResult)
 
-(rule (emit_fcmp (FloatCC.Equal) a @ (value_type (ty_scalar_float _)) b)
-      (FcmpCondResult.AndCondition (x64_ucomis a b) (CC.NP) (CC.Z)))
+(rule (emit_fcmp (FloatCC.Equal) a @ (value_type (ty_scalar_float ty)) b)
+      (FcmpCondResult.AndCondition (x64_ucomis ty a b) (CC.NP) (CC.Z)))
 
-(rule (emit_fcmp (FloatCC.NotEqual) a @ (value_type (ty_scalar_float _)) b)
-      (FcmpCondResult.OrCondition (x64_ucomis a b) (CC.P) (CC.NZ)))
+(rule (emit_fcmp (FloatCC.NotEqual) a @ (value_type (ty_scalar_float ty)) b)
+      (FcmpCondResult.OrCondition (x64_ucomis ty a b) (CC.P) (CC.NZ)))
 
 ;; Some scalar lowerings correspond to one condition code.
 
 (rule (emit_fcmp (FloatCC.Ordered) a @ (value_type (ty_scalar_float ty)) b)
-      (FcmpCondResult.Condition (x64_ucomis a b) (CC.NP)))
+      (FcmpCondResult.Condition (x64_ucomis ty a b) (CC.NP)))
 (rule (emit_fcmp (FloatCC.Unordered) a @ (value_type (ty_scalar_float ty)) b)
-      (FcmpCondResult.Condition (x64_ucomis a b) (CC.P)))
+      (FcmpCondResult.Condition (x64_ucomis ty a b) (CC.P)))
 (rule (emit_fcmp (FloatCC.OrderedNotEqual) a @ (value_type (ty_scalar_float ty)) b)
-      (FcmpCondResult.Condition (x64_ucomis a b) (CC.NZ)))
+      (FcmpCondResult.Condition (x64_ucomis ty a b) (CC.NZ)))
 (rule (emit_fcmp (FloatCC.UnorderedOrEqual) a @ (value_type (ty_scalar_float ty)) b)
-      (FcmpCondResult.Condition (x64_ucomis a b) (CC.Z)))
+      (FcmpCondResult.Condition (x64_ucomis ty a b) (CC.Z)))
 (rule (emit_fcmp (FloatCC.GreaterThan) a @ (value_type (ty_scalar_float ty)) b)
-      (FcmpCondResult.Condition (x64_ucomis a b) (CC.NBE)))
+      (FcmpCondResult.Condition (x64_ucomis ty a b) (CC.NBE)))
 (rule (emit_fcmp (FloatCC.GreaterThanOrEqual) a @ (value_type (ty_scalar_float ty)) b)
-      (FcmpCondResult.Condition (x64_ucomis a b) (CC.NB)))
+      (FcmpCondResult.Condition (x64_ucomis ty a b) (CC.NB)))
 (rule (emit_fcmp (FloatCC.UnorderedOrLessThan) a @ (value_type (ty_scalar_float ty)) b)
-      (FcmpCondResult.Condition (x64_ucomis a b) (CC.B)))
+      (FcmpCondResult.Condition (x64_ucomis ty a b) (CC.B)))
 (rule (emit_fcmp (FloatCC.UnorderedOrLessThanOrEqual) a @ (value_type (ty_scalar_float ty)) b)
-      (FcmpCondResult.Condition (x64_ucomis a b) (CC.BE)))
+      (FcmpCondResult.Condition (x64_ucomis ty a b) (CC.BE)))
 
 ;; Other scalar lowerings are made possible by flipping the operands and
 ;; reversing the condition code.
 
 (rule (emit_fcmp (FloatCC.LessThan) a @ (value_type (ty_scalar_float ty)) b)
       ;; Same flags as `GreaterThan`.
-      (FcmpCondResult.Condition (x64_ucomis b a) (CC.NBE)))
+      (FcmpCondResult.Condition (x64_ucomis ty b a) (CC.NBE)))
 (rule (emit_fcmp (FloatCC.LessThanOrEqual) a @ (value_type (ty_scalar_float ty)) b)
       ;; Same flags as `GreaterThanOrEqual`.
-      (FcmpCondResult.Condition (x64_ucomis b a) (CC.NB)))
+      (FcmpCondResult.Condition (x64_ucomis ty b a) (CC.NB)))
 (rule (emit_fcmp (FloatCC.UnorderedOrGreaterThan) a @ (value_type (ty_scalar_float ty)) b)
       ;; Same flags as `UnorderedOrLessThan`.
-      (FcmpCondResult.Condition (x64_ucomis b a) (CC.B)))
+      (FcmpCondResult.Condition (x64_ucomis ty b a) (CC.B)))
 (rule (emit_fcmp (FloatCC.UnorderedOrGreaterThanOrEqual) a @ (value_type (ty_scalar_float ty)) b)
       ;; Same flags as `UnorderedOrLessThanOrEqual`.
-      (FcmpCondResult.Condition (x64_ucomis b a) (CC.BE)))
+      (FcmpCondResult.Condition (x64_ucomis ty b a) (CC.BE)))
 
 ;;;; Type Guards ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
diff --git a/cranelift/codegen/src/isa/x64/inst/args.rs b/cranelift/codegen/src/isa/x64/inst/args.rs
index 992e322b4..caf21dbbb 100644
--- a/cranelift/codegen/src/isa/x64/inst/args.rs
+++ b/cranelift/codegen/src/isa/x64/inst/args.rs
@@ -1814,7 +1814,10 @@ impl AvxOpcode {
             | AvxOpcode::Vsqrtsd
             | AvxOpcode::Vroundss
             | AvxOpcode::Vroundsd
-            | AvxOpcode::Vunpcklpd => {
+            | AvxOpcode::Vunpcklpd
+            | AvxOpcode::Vptest
+            | AvxOpcode::Vucomiss
+            | AvxOpcode::Vucomisd => {
                 smallvec![InstructionSet::AVX]
             }
 
diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs
index 481362b9e..c84269c02 100644
--- a/cranelift/codegen/src/isa/x64/inst/emit.rs
+++ b/cranelift/codegen/src/isa/x64/inst/emit.rs
@@ -2855,6 +2855,32 @@ pub(crate) fn emit(
                 .encode(sink);
         }
 
+        Inst::XmmCmpRmRVex { op, src1, src2 } => {
+            let src1 = allocs.next(src1.to_reg());
+            let src2 = match src2.clone().to_reg_mem().with_allocs(allocs) {
+                RegMem::Reg { reg } => {
+                    RegisterOrAmode::Register(reg.to_real_reg().unwrap().hw_enc().into())
+                }
+                RegMem::Mem { addr } => RegisterOrAmode::Amode(addr.finalize(state, sink)),
+            };
+
+            let (prefix, map, opcode) = match op {
+                AvxOpcode::Vucomiss => (LegacyPrefixes::None, OpcodeMap::_0F, 0x2E),
+                AvxOpcode::Vucomisd => (LegacyPrefixes::_66, OpcodeMap::_0F, 0x2E),
+                AvxOpcode::Vptest => (LegacyPrefixes::_66, OpcodeMap::_0F38, 0x17),
+                _ => unimplemented!("Opcode {:?} not implemented", op),
+            };
+
+            VexInstruction::new()
+                .length(VexVectorLength::V128)
+                .prefix(prefix)
+                .map(map)
+                .opcode(opcode)
+                .rm(src2)
+                .reg(src1.to_real_reg().unwrap().hw_enc())
+                .encode(sink);
+        }
+
         Inst::XmmRmREvex {
             op,
             src1,
diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs
index 55407ee86..8b557d514 100644
--- a/cranelift/codegen/src/isa/x64/inst/mod.rs
+++ b/cranelift/codegen/src/isa/x64/inst/mod.rs
@@ -191,7 +191,8 @@ impl Inst {
             | Inst::XmmToGprImmVex { op, .. }
             | Inst::XmmToGprVex { op, .. }
             | Inst::GprToXmmVex { op, .. }
-            | Inst::CvtIntToFloatVex { op, .. } => op.available_from(),
+            | Inst::CvtIntToFloatVex { op, .. }
+            | Inst::XmmCmpRmRVex { op, .. } => op.available_from(),
         }
     }
 }
@@ -1351,6 +1352,12 @@ impl PrettyPrint for Inst {
                 format!("{op} {src1}, {src2}, {dst}")
             }
 
+            Inst::XmmCmpRmRVex { op, src1, src2 } => {
+                let src1 = pretty_print_reg(src1.to_reg(), 8, allocs);
+                let src2 = src2.pretty_print(8, allocs);
+                format!("{} {src2}, {src1}", ljustify(op.to_string()))
+            }
+
             Inst::CvtUint64ToFloatSeq {
                 src,
                 dst,
@@ -2159,6 +2166,10 @@ fn x64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandCol
             collector.reg_use(src1.to_reg());
             src2.get_operands(collector);
         }
+        Inst::XmmCmpRmRVex { src1, src2, .. } => {
+            collector.reg_use(src1.to_reg());
+            src2.get_operands(collector);
+        }
         Inst::Imm { dst, .. } => {
             collector.reg_def(dst.to_writable_reg());
         }
diff --git a/cranelift/codegen/src/isa/x64/pcc.rs b/cranelift/codegen/src/isa/x64/pcc.rs
index e28cf05d1..d6be501c2 100644
--- a/cranelift/codegen/src/isa/x64/pcc.rs
+++ b/cranelift/codegen/src/isa/x64/pcc.rs
@@ -813,6 +813,18 @@ pub(crate) fn check(
             ensure_no_fact(vcode, dst.to_reg())
         }
 
+        Inst::XmmCmpRmRVex {
+            ref src1, ref src2, ..
+        } => {
+            match <&RegMem>::from(src2) {
+                RegMem::Mem { ref addr } => {
+                    check_load(ctx, None, addr, vcode, F32, 32)?;
+                }
+                RegMem::Reg { .. } => {}
+            }
+            ensure_no_fact(vcode, src1.to_reg())
+        }
+
         Inst::CallKnown { .. }
         | Inst::ReturnCallKnown { .. }
         | Inst::JmpKnown { .. }
diff --git a/cranelift/wasm/src/code_translator.rs b/cranelift/wasm/src/code_translator.rs
index 2e32e0e70..502279f24 100644
--- a/cranelift/wasm/src/code_translator.rs
+++ b/cranelift/wasm/src/code_translator.rs
@@ -2543,6 +2543,10 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
         | Operator::StructGet { .. } => {
             unimplemented!("GC operators not yet implemented")
         }
+
+        Operator::GlobalAtomicGet { .. } | Operator::GlobalAtomicSet { .. } => {
+            unimplemented!("shared-everything-threads not yet implemented")
+        }
     };
     Ok(())
 }
diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock
index 263bfd6e6..61311c79f 100644
--- a/supply-chain/imports.lock
+++ b/supply-chain/imports.lock
@@ -1190,6 +1190,12 @@ when = "2024-04-16"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasm-encoder]]
+version = "0.205.0"
+when = "2024-04-18"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasm-metadata]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -1214,6 +1220,12 @@ when = "2024-04-16"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasm-metadata]]
+version = "0.205.0"
+when = "2024-04-18"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasm-mutate]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -1238,6 +1250,12 @@ when = "2024-04-16"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasm-mutate]]
+version = "0.205.0"
+when = "2024-04-18"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasm-smith]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -1262,6 +1280,12 @@ when = "2024-04-16"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasm-smith]]
+version = "0.205.0"
+when = "2024-04-18"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasmparser]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -1286,6 +1310,12 @@ when = "2024-04-16"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasmparser]]
+version = "0.205.0"
+when = "2024-04-18"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasmprinter]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -1310,6 +1340,12 @@ when = "2024-04-16"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasmprinter]]
+version = "0.205.0"
+when = "2024-04-18"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasmtime]]
 version = "18.0.2"
 when = "2024-02-28"
@@ -1622,6 +1658,12 @@ when = "2024-04-16"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wast]]
+version = "205.0.0"
+when = "2024-04-18"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wat]]
 version = "1.201.0"
 when = "2024-02-27"
@@ -1646,6 +1688,12 @@ when = "2024-04-16"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wat]]
+version = "1.205.0"
+when = "2024-04-18"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wiggle]]
 version = "18.0.2"
 when = "2024-02-28"
@@ -1940,6 +1988,12 @@ when = "2024-04-16"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wit-component]]
+version = "0.205.0"
+when = "2024-04-18"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wit-parser]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -1964,6 +2018,12 @@ when = "2024-04-16"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wit-parser]]
+version = "0.205.0"
+when = "2024-04-18"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.witx]]
 version = "0.9.1"
 when = "2021-06-22"


Test patch:
diff --git a/cranelift/filetests/filetests/isa/x64/branches.clif b/cranelift/filetests/filetests/isa/x64/branches.clif
index 57ab4de3f..fbbd876b8 100644
--- a/cranelift/filetests/filetests/isa/x64/branches.clif
+++ b/cranelift/filetests/filetests/isa/x64/branches.clif
@@ -630,15 +630,13 @@ block202:
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movl    $1112539136, %eax
-;   movd    %eax, %xmm4
-;   ucomiss %xmm4, %xmm0
+;   ucomiss const(1), %xmm0
 ;   jp      label2
 ;   jnz     label2; j label1
 ; block1:
 ;   jmp     label5
 ; block2:
-;   ucomiss %xmm4, %xmm0
+;   ucomiss const(0), %xmm0
 ;   jnp     label4; j label3
 ; block3:
 ;   jmp     label5
@@ -654,20 +652,36 @@ block202:
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movl $0x42500000, %eax
-;   movd %eax, %xmm4
-;   ucomiss %xmm4, %xmm0
-;   jp 0x1c
-;   je 0x27
-; block2: ; offset 0x1c
-;   ucomiss %xmm4, %xmm0
-;   jp 0x27
-; block3: ; offset 0x25
+;   ucomiss 0x25(%rip), %xmm0
+;   jp 0x17
+;   je 0x26
+; block2: ; offset 0x17
+;   ucomiss 0x22(%rip), %xmm0
+;   jp 0x26
+; block3: ; offset 0x24
 ;   ud2 ; trap: heap_oob
-; block4: ; offset 0x27
+; block4: ; offset 0x26
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %dl, 0x42(%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   pushq %rax
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
 
 function %br_i8_icmp(i32, i32) -> i32 {
 block0(v0: i32, v1: i32):
diff --git a/cranelift/filetests/filetests/isa/x64/f64-branches-avx.clif b/cranelift/filetests/filetests/isa/x64/f64-branches-avx.clif
new file mode 100644
index 000000000..f40100bbf
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/x64/f64-branches-avx.clif
@@ -0,0 +1,105 @@
+test compile precise-output
+target x86_64 has_avx
+
+function %f3(f32, f32) -> i32 {
+block0(v0: f32, v1: f32):
+  v2 = fcmp eq v0, v1
+  brif v2, block1, block2
+
+block1:
+  v3 = iconst.i32 1
+  return v3
+
+block2:
+  v4 = iconst.i32 2
+  return v4
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vucomiss %xmm1, %xmm0
+;   jp      label1
+;   jnz     label1; j label2
+; block1:
+;   movl    $2, %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; block2:
+;   movl    $1, %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vucomiss %xmm1, %xmm0
+;   jp 0x14
+;   je 0x1e
+; block2: ; offset 0x14
+;   movl $2, %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+; block3: ; offset 0x1e
+;   movl $1, %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %f3(f64, f64) -> i32 {
+block0(v0: f64, v1: f64):
+  v2 = fcmp eq v0, v1
+  brif v2, block1, block2
+
+block1:
+  v3 = iconst.i32 1
+  return v3
+
+block2:
+  v4 = iconst.i32 2
+  return v4
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vucomisd %xmm1, %xmm0
+;   jp      label1
+;   jnz     label1; j label2
+; block1:
+;   movl    $2, %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; block2:
+;   movl    $1, %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vucomisd %xmm1, %xmm0
+;   jp 0x14
+;   je 0x1e
+; block2: ; offset 0x14
+;   movl $2, %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+; block3: ; offset 0x1e
+;   movl $1, %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
diff --git a/cranelift/filetests/filetests/isa/x64/simd-logical-compile-avx.clif b/cranelift/filetests/filetests/isa/x64/simd-logical-compile-avx.clif
new file mode 100644
index 000000000..f30b20acc
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/x64/simd-logical-compile-avx.clif
@@ -0,0 +1,62 @@
+test compile precise-output
+target x86_64 sse42 has_avx
+
+function %vany_true_i32x4(i32x4) -> i8 {
+block0(v0: i32x4):
+    v1 = vany_true v0
+    return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vptest  %xmm0, %xmm0
+;   setnz   %al
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vptest %xmm0, %xmm0
+;   setne %al
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %vall_true_i64x2(i64x2) -> i8 {
+block0(v0: i64x2):
+    v1 = vall_true v0
+    return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   uninit  %xmm2
+;   vpxor   %xmm2, %xmm2, %xmm4
+;   vpcmpeqq %xmm0, %xmm4, %xmm6
+;   vptest  %xmm6, %xmm6
+;   setz    %al
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vpxor %xmm2, %xmm2, %xmm4
+;   vpcmpeqq %xmm4, %xmm0, %xmm6
+;   vptest %xmm6, %xmm6
+;   sete %al
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
diff --git a/cranelift/filetests/filetests/isa/x64/very-carefully-sink-loads-in-float-compares.clif b/cranelift/filetests/filetests/isa/x64/very-carefully-sink-loads-in-float-compares.clif
new file mode 100644
index 000000000..01c9d4db2
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/x64/very-carefully-sink-loads-in-float-compares.clif
@@ -0,0 +1,499 @@
+test compile precise-output
+target x86_64
+
+;; This test ensures that Cranelift does not attempt to too eagerly sink loads
+;; into float comparison operations. When a single `fcmp` is used multiple times
+;; it'll regenerate `ucomiss` instructions, for example, but if this duplication
+;; happens then it shouldn't have a load sunk into it because that would load
+;; at two different points in the program, possibly seeing two different
+;; results.
+;;
+;; Exactly how this guarantee is provided has changed a bit over time with
+;; Cranelift. Originally in #3934 this was done explicitly in ISLE by avoiding
+;; the use of `put_in_xmm_mem`. Later in #4061 that ended up removing the need
+;; for the safeguards in #3934. Today there are no guards in ISLE for this any
+;; more and this test is intended to serve as a reference-test for notifying
+;; reviewers if anything changes.
+
+function %select_cond_rhs(f32, i64, i32, i32) -> i32 {
+block0(v0: f32, v1: i64, v2: i32, v3: i32):
+  v4 = load.f32 notrap aligned v1
+  v5 = fcmp eq v0, v4
+  v6 = select v5, v2, v3
+  return v6
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   ucomiss 0(%rdi), %xmm0
+;   cmovpl  %edx, %esi, %esi
+;   movq    %rsi, %rax
+;   cmovnzl %edx, %eax, %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   ucomiss (%rdi), %xmm0
+;   cmovpl %edx, %esi
+;   movq %rsi, %rax
+;   cmovnel %edx, %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+
+function %select_cond_lhs(f32, i64, i32, i32) -> i32 {
+block0(v0: f32, v1: i64, v2: i32, v3: i32):
+  v4 = load.f32 notrap aligned v1
+  v5 = fcmp eq v4, v0
+  v6 = select v5, v2, v3
+  return v6
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movss   0(%rdi), %xmm7
+;   ucomiss %xmm0, %xmm7
+;   cmovpl  %edx, %esi, %esi
+;   movq    %rsi, %rax
+;   cmovnzl %edx, %eax, %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movss (%rdi), %xmm7
+;   ucomiss %xmm0, %xmm7
+;   cmovpl %edx, %esi
+;   movq %rsi, %rax
+;   cmovnel %edx, %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %select_cond_used_twice_rhs(f32, i64, i32, i32) -> i32, i32 {
+block0(v0: f32, v1: i64, v2: i32, v3: i32):
+  ;; this load should NOT sink into either `select` below
+  v4 = load.f32 notrap aligned v1
+  v5 = fcmp eq v0, v4
+  v6 = select v5, v2, v3
+  v7 = select v5, v3, v2
+  return v6, v7
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movss   0(%rdi), %xmm1
+;   ucomiss %xmm1, %xmm0
+;   movq    %rsi, %rax
+;   cmovpl  %edx, %eax, %eax
+;   cmovnzl %edx, %eax, %eax
+;   ucomiss %xmm1, %xmm0
+;   cmovpl  %esi, %edx, %edx
+;   cmovnzl %esi, %edx, %edx
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movss (%rdi), %xmm1
+;   ucomiss %xmm1, %xmm0
+;   movq %rsi, %rax
+;   cmovpl %edx, %eax
+;   cmovnel %edx, %eax
+;   ucomiss %xmm1, %xmm0
+;   cmovpl %esi, %edx
+;   cmovnel %esi, %edx
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+
+function %select_cond_used_twice_lhs(f32, i64, i32, i32) -> i32, i32 {
+block0(v0: f32, v1: i64, v2: i32, v3: i32):
+  ;; this load should NOT sink into either `select` below
+  v4 = load.f32 notrap aligned v1
+  v5 = fcmp eq v4, v0
+  v6 = select v5, v2, v3
+  v7 = select v5, v3, v2
+  return v6, v7
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movss   0(%rdi), %xmm1
+;   ucomiss %xmm0, %xmm1
+;   movq    %rsi, %rax
+;   cmovpl  %edx, %eax, %eax
+;   cmovnzl %edx, %eax, %eax
+;   ucomiss %xmm0, %xmm1
+;   cmovpl  %esi, %edx, %edx
+;   cmovnzl %esi, %edx, %edx
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movss (%rdi), %xmm1
+;   ucomiss %xmm0, %xmm1
+;   movq %rsi, %rax
+;   cmovpl %edx, %eax
+;   cmovnel %edx, %eax
+;   ucomiss %xmm0, %xmm1
+;   cmovpl %esi, %edx
+;   cmovnel %esi, %edx
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %brif_cond_rhs(f32, i64, i32, i32) -> i32 {
+block0(v0: f32, v1: i64, v2: i32, v3: i32):
+  v4 = load.f32 notrap aligned v1
+  v5 = fcmp eq v0, v4
+  brif v5, block1(v2), block1(v3)
+block1(v8: i32):
+  return v8
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movss   0(%rdi), %xmm1
+;   ucomiss %xmm1, %xmm0
+;   jp      label2
+;   jnz     label2; j label1
+; block1:
+;   movq    %rsi, %rax
+;   jmp     label3
+; block2:
+;   movq    %rdx, %rax
+;   jmp     label3
+; block3:
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movss (%rdi), %xmm1
+;   ucomiss %xmm1, %xmm0
+;   jp 0x1f
+;   jne 0x1f
+; block2: ; offset 0x17
+;   movq %rsi, %rax
+;   jmp 0x22
+; block3: ; offset 0x1f
+;   movq %rdx, %rax
+; block4: ; offset 0x22
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %brif_cond_lhs(f32, i64, i32, i32) -> i32 {
+block0(v0: f32, v1: i64, v2: i32, v3: i32):
+  v4 = load.f32 notrap aligned v1
+  v5 = fcmp eq v4, v0
+  brif v5, block1(v2), block1(v3)
+block1(v8: i32):
+  return v8
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movss   0(%rdi), %xmm1
+;   ucomiss %xmm0, %xmm1
+;   jp      label2
+;   jnz     label2; j label1
+; block1:
+;   movq    %rsi, %rax
+;   jmp     label3
+; block2:
+;   movq    %rdx, %rax
+;   jmp     label3
+; block3:
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movss (%rdi), %xmm1
+;   ucomiss %xmm0, %xmm1
+;   jp 0x1f
+;   jne 0x1f
+; block2: ; offset 0x17
+;   movq %rsi, %rax
+;   jmp 0x22
+; block3: ; offset 0x1f
+;   movq %rdx, %rax
+; block4: ; offset 0x22
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %brif_cond_used_twice_rhs(f32, i64, i32, i32) -> i32, i32 {
+block0(v0: f32, v1: i64, v2: i32, v3: i32):
+  v4 = load.f32 notrap aligned v1
+  v5 = fcmp eq v0, v4
+  brif v5, block1(v2), block1(v3)
+block1(v6: i32):
+  brif v5, block2(v3), block2(v2)
+block2(v7: i32):
+  return v6, v7
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movss   0(%rdi), %xmm3
+;   ucomiss %xmm3, %xmm0
+;   jp      label2
+;   jnz     label2; j label1
+; block1:
+;   movq    %rsi, %rax
+;   jmp     label3
+; block2:
+;   movq    %rdx, %rax
+;   jmp     label3
+; block3:
+;   ucomiss %xmm3, %xmm0
+;   jp      label5
+;   jnz     label5; j label4
+; block4:
+;   jmp     label6
+; block5:
+;   movq    %rsi, %rdx
+;   jmp     label6
+; block6:
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movss (%rdi), %xmm3
+;   ucomiss %xmm3, %xmm0
+;   jp 0x1f
+;   jne 0x1f
+; block2: ; offset 0x17
+;   movq %rsi, %rax
+;   jmp 0x22
+; block3: ; offset 0x1f
+;   movq %rdx, %rax
+; block4: ; offset 0x22
+;   ucomiss %xmm3, %xmm0
+;   jp 0x31
+;   je 0x34
+; block5: ; offset 0x31
+;   movq %rsi, %rdx
+; block6: ; offset 0x34
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %brif_cond_used_twice_lhs(f32, i64, i32, i32) -> i32, i32 {
+block0(v0: f32, v1: i64, v2: i32, v3: i32):
+  v4 = load.f32 notrap aligned v1
+  v5 = fcmp eq v4, v0
+  brif v5, block1(v2), block1(v3)
+block1(v6: i32):
+  brif v5, block2(v3), block2(v2)
+block2(v7: i32):
+  return v6, v7
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movss   0(%rdi), %xmm3
+;   ucomiss %xmm0, %xmm3
+;   jp      label2
+;   jnz     label2; j label1
+; block1:
+;   movq    %rsi, %rax
+;   jmp     label3
+; block2:
+;   movq    %rdx, %rax
+;   jmp     label3
+; block3:
+;   ucomiss %xmm0, %xmm3
+;   jp      label5
+;   jnz     label5; j label4
+; block4:
+;   jmp     label6
+; block5:
+;   movq    %rsi, %rdx
+;   jmp     label6
+; block6:
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movss (%rdi), %xmm3
+;   ucomiss %xmm0, %xmm3
+;   jp 0x1f
+;   jne 0x1f
+; block2: ; offset 0x17
+;   movq %rsi, %rax
+;   jmp 0x22
+; block3: ; offset 0x1f
+;   movq %rdx, %rax
+; block4: ; offset 0x22
+;   ucomiss %xmm0, %xmm3
+;   jp 0x31
+;   je 0x34
+; block5: ; offset 0x31
+;   movq %rsi, %rdx
+; block6: ; offset 0x34
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %mix_select_and_brif_rhs(f32, i64, i32, i32) -> i32, i32 {
+block0(v0: f32, v1: i64, v2: i32, v3: i32):
+  v4 = load.f32 notrap aligned v1
+  v5 = fcmp eq v0, v4
+  v6 = select v5, v2, v3
+  brif v5, block1(v3), block1(v2)
+block1(v7: i32):
+  return v6, v7
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movss   0(%rdi), %xmm2
+;   ucomiss %xmm2, %xmm0
+;   movq    %rsi, %rax
+;   cmovpl  %edx, %eax, %eax
+;   cmovnzl %edx, %eax, %eax
+;   ucomiss %xmm2, %xmm0
+;   jp      label2
+;   jnz     label2; j label1
+; block1:
+;   jmp     label3
+; block2:
+;   movq    %rsi, %rdx
+;   jmp     label3
+; block3:
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movss (%rdi), %xmm2
+;   ucomiss %xmm2, %xmm0
+;   movq %rsi, %rax
+;   cmovpl %edx, %eax
+;   cmovnel %edx, %eax
+;   ucomiss %xmm2, %xmm0
+;   jp 0x23
+;   je 0x26
+; block2: ; offset 0x23
+;   movq %rsi, %rdx
+; block3: ; offset 0x26
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %mix_select_and_brif_lhs(f32, i64, i32, i32) -> i32, i32 {
+block0(v0: f32, v1: i64, v2: i32, v3: i32):
+  v4 = load.f32 notrap aligned v1
+  v5 = fcmp eq v4, v0
+  v6 = select v5, v2, v3
+  brif v5, block1(v3), block1(v2)
+block1(v7: i32):
+  return v6, v7
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movss   0(%rdi), %xmm2
+;   ucomiss %xmm0, %xmm2
+;   movq    %rsi, %rax
+;   cmovpl  %edx, %eax, %eax
+;   cmovnzl %edx, %eax, %eax
+;   ucomiss %xmm0, %xmm2
+;   jp      label2
+;   jnz     label2; j label1
+; block1:
+;   jmp     label3
+; block2:
+;   movq    %rsi, %rdx
+;   jmp     label3
+; block3:
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movss (%rdi), %xmm2
+;   ucomiss %xmm0, %xmm2
+;   movq %rsi, %rax
+;   cmovpl %edx, %eax
+;   cmovnel %edx, %eax
+;   ucomiss %xmm0, %xmm2
+;   jp 0x23
+;   je 0x26
+; block2: ; offset 0x23
+;   movq %rsi, %rdx
+; block3: ; offset 0x26
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+