Repository: bytecodealliance/wasmtime
Pull request #6023 (2023-03-15 00:25:03)

x64: Add support for the `pblendw` instruction
This commit adds another case for `shuffle` lowering to the x64 backend for the `{,v}pblendw` instruction. This instruction selects 16-bit values from either of the inputs corresponding to an immediate 8-bit-mask where each bit selects the corresponding lane from the inputs.

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

- [ ] This has been discussed in issue #..., or if not, please tell us why
  here.
- [ ] A short description of what this does, why it is needed; if the
  description becomes long, the matter should probably be discussed in an issue
  first.
- [ ] This PR contains test cases, if meaningful.
- [ ] A reviewer from the core maintainer team has been assigned for this PR.
  If you don't know who could review this, please indicate so. The list of
  suggested reviewers on the right can help you.

Please ensure all communication adheres to the [code of
conduct](https://github.com/bytecodealliance/wasmtime/blob/master/CODE_OF_CONDUCT.md).
-->


github-actions[bot]: #### Subscribe to Label Action

cc @cfallin, @fitzgen

<details>
This issue or pull request has been labeled: "cranelift", "cranelift:area:x64", "isle"

Thus the following users have been cc'd because of the following labels:

* cfallin: isle
* fitzgen: isle

To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.

[Learn more.](https://github.com/bytecodealliance/subscribe-to-label-action)
</details>

Patch:
diff --git a/cranelift/codegen/src/isa/x64/inst.isle b/cranelift/codegen/src/isa/x64/inst.isle
index faf5bc045..63580dc63 100644
--- a/cranelift/codegen/src/isa/x64/inst.isle
+++ b/cranelift/codegen/src/isa/x64/inst.isle
@@ -170,7 +170,8 @@
 
        ;; Loads the memory address of addr into dst.
        (LoadEffectiveAddress (addr SyntheticAmode)
-                             (dst WritableGpr))
+                             (dst WritableGpr)
+                             (size OperandSize))
 
        ;; Sign-extended loads and moves: movs (bl bq wl wq lq) addr reg.
        (MovsxRmR (ext_mode ExtMode)
@@ -917,6 +918,7 @@
             Punpcklqdq
             Pshuflw
             Pshufhw
+            Pblendw
           ))
 
 (type CmpOpcode extern
@@ -990,25 +992,6 @@
              ;; the given MachLabel.
              (RipRelative (target MachLabel))))
 
-;; Some Amode constructor helpers.
-
-(decl amode_with_flags (Amode MemFlags) Amode)
-(extern constructor amode_with_flags amode_with_flags)
-
-(decl amode_imm_reg (u32 Gpr) Amode)
-(extern constructor amode_imm_reg amode_imm_reg)
-
-(decl amode_imm_reg_flags (u32 Gpr MemFlags) Amode)
-(rule (amode_imm_reg_flags offset base flags)
-      (amode_with_flags (amode_imm_reg offset base) flags))
-
-(decl amode_imm_reg_reg_shift (u32 Gpr Gpr u8) Amode)
-(extern constructor amode_imm_reg_reg_shift amode_imm_reg_reg_shift)
-
-(decl amode_imm_reg_reg_shift_flags (u32 Gpr Gpr u8 MemFlags) Amode)
-(rule (amode_imm_reg_reg_shift_flags offset base index shift flags)
-      (amode_with_flags (amode_imm_reg_reg_shift offset base index shift) flags))
-
 ;; A helper to both check that the `Imm64` and `Offset32` values sum to less
 ;; than 32-bits AND return this summed `u32` value. Also, the `Imm64` will be
 ;; zero-extended from `Type` up to 64 bits. This is useful for `to_amode`.
@@ -1017,168 +1000,59 @@
 
 ;;;; Amode lowering ;;;;
 
-;; To generate an address for a memory access, we can pattern-match
-;; various CLIF sub-trees to x64's complex addressing modes (`Amode`).
-;;
-;; Information about available addressing modes is available in
-;; Intel's Software Developer's Manual, volume 2, section 2.1.5,
-;; "Addressing-Mode Encoding of ModR/M and SIB Bytes."
-;;
-;; The general strategy to build an `Amode` is to traverse over the
-;; input expression's addends, recursively deconstructing a tree of
-;; `iadd` operators that add up parts of the address, updating the
-;; `Amode` in an incremental fashion as we add in each piece.
-;;
-;; We start with an "immediate + register" form that encapsulates the
-;; load/store's built-in `Offset32` and `invalid_reg` as the
-;; register. This is given by `amode_initial`. Then we add `Value`s
-;; one at a time with `amode_add`. (Why start with `invalid_reg` at
-;; all? Because we don't want to special-case the first input and
-;; duplicate rules; this lets us use the "add a value" logic even for
-;; the first value.)
-;;
-;; It is always valid to use `amode_add` to add the one single
-;; `address` input to the load/store (i.e., the `Value` given to
-;; `to_amode`). In the fallback case, this is what we do. Then we get
-;; an `Amode.ImmReg` with the `Offset32` and `Value` below and nothing
-;; else; this always works and is not *that* bad.
-;;
-;; But we can often do better. The toplevel rule for `iadd` below will
-;; turn an `(amode_add amode (iadd a b))` into two invocations of
-;; `amode_add`, for each operand of the `iadd`. This is what allows us
-;; to handle sums of many parts.
-;;
-;; Then we "just" need to work out how we can incorporate a new
-;; component into an existing addressing mode:
-;;
-;; - Case 1: When we have an `ImmReg` and the register is
-;;   `invalid_reg` (the initial `Amode` above), we can put the new
-;;   addend into a register and insert it into the `ImmReg`.
-;;
-;; - Case 2: When we have an `ImmReg` with a valid register already,
-;;   and we have another register to add, we can transition to an
-;;   `ImmRegRegShift`.
-;;
-;; - Case 3: When we're adding an `ishl`, we can refine the above rule
-;;   and use the built-in multiplier of 1, 2, 4, 8 to implement a
-;;   left-shift by 0, 1, 2, 3.
-;;
-;; - Case 4: When we are adding another constant offset, we can fold
-;;   it into the existing offset, as long as the sum still fits into
-;;   the signed 32-bit field.
-;;
-;; - Case 5: And as a general fallback, we can generate a new `add`
-;;   instruction and add the new addend to an existing component of
-;;   the `Amode`.
+;; Converts a `Value` and a static offset into an `Amode` for x64, attempting
+;; to be as fancy as possible with offsets/registers/shifts/etc to make maximal
+;; use of the x64 addressing modes.
 (decl to_amode (MemFlags Value Offset32) Amode)
 
-;; Initial step in amode processing: create an ImmReg with
-;; (invalid_reg) and encapsulating the flags and offset from the
-;; load/store.
-(decl amode_initial (MemFlags Offset32) Amode)
-(rule (amode_initial flags (offset32 off))
-      (Amode.ImmReg off (invalid_reg) flags))
+;; Base case, "just put it in a register"
+(rule (to_amode flags base offset)
+      (Amode.ImmReg offset base flags))
 
-;; One step in amode processing: take an existing amode and add
-;; another value to it.
-(decl amode_add (Amode Value) Amode)
+;; Slightly-more-fancy case, if the address is the addition of two things then
+;; delegate to the `to_amode_add` helper.
+(rule 1 (to_amode flags (iadd x y) offset)
+      (to_amode_add flags x y offset))
 
-;; -- Top-level driver: pull apart the addends.
-;;
-;; Any amode can absorb an `iadd` by absorbing first the LHS of the
-;; add, then the RHS.
-;;
-;; Priority 2 to take this above fallbacks and ensure we traverse the
-;; `iadd` tree fully.
-(rule 2 (amode_add amode (iadd x y))
-      (let ((amode1 Amode (amode_add amode x))
-            (amode2 Amode (amode_add amode1 y)))
-        amode2))
-
-;; -- Case 1 (adding a register to the initial Amode with invalid_reg).
-;;
-;; An Amode.ImmReg with invalid_reg (initial state) can absorb a
-;; register as the base register.
-(rule (amode_add (Amode.ImmReg off (invalid_reg) flags) value)
-      (Amode.ImmReg off value flags))
+;; Same as `to_amode`, except that the base address is computed via the addition
+;; of the two `Value` arguments provided.
+(decl to_amode_add (MemFlags Value Value Offset32) Amode)
 
-;; -- Case 2 (adding a register to an Amode with a register already).
-;;
-;; An Amode.ImmReg can absorb another register as the index register.
-(rule (amode_add (Amode.ImmReg off (valid_reg base) flags) value)
-      ;; Shift of 0 --> base + 1*value.
-      (Amode.ImmRegRegShift off base value 0 flags))
+;; Base case, "just put things in registers". Note that the shift value of 0
+;; here  means `x + (y << 0)` which is the same as `x + y`.
+(rule (to_amode_add flags x y offset)
+      (Amode.ImmRegRegShift offset x y 0 flags))
 
-;; -- Case 3 (adding a shifted value to an Amode).
-;;
-;; An Amode.ImmReg can absorb a shift of another register as the index register.
-;;
-;; Priority 2 to take these rules above generic case.
-(rule 2 (amode_add (Amode.ImmReg off (valid_reg base) flags) (ishl index (iconst (uimm8 shift))))
+;; If the one of the arguments being added is itself a constant shift then
+;; that can be modeled directly so long as the shift is a modestly small amount.
+(rule 1 (to_amode_add flags x (ishl y (iconst (uimm8 shift))) offset)
+      (if (u32_lteq (u8_as_u32 shift) 3))
+      (Amode.ImmRegRegShift offset x y shift flags))
+(rule 2 (to_amode_add flags (ishl y (iconst (uimm8 shift))) x offset)
       (if (u32_lteq (u8_as_u32 shift) 3))
-      (Amode.ImmRegRegShift off base index shift flags))
+      (Amode.ImmRegRegShift offset x y shift flags))
 
-;; -- Case 4 (absorbing constant offsets).
+;; Constant extraction rules.
 ;;
-;; An Amode can absorb a constant (i64, or extended i32) as long as
-;; the sum still fits in the signed-32-bit offset.
+;; These rules attempt to find a constant within one of `x` or `y`, or deeper
+;; within them if they have their own adds. These only succeed if the constant
+;; itself can be represented with 32-bits and can be infallibly added to the
+;; offset that we already have.
 ;;
-;; Priority 3 in order to take this option above the fallback
-;; (immediate in register). Two rules, for imm+reg and
-;; imm+reg+scale*reg cases.
-(rule 3 (amode_add (Amode.ImmReg off base flags)
-                   (iconst (simm32 c)))
-      (if-let sum (s32_add_fallible off c))
-      (Amode.ImmReg sum base flags))
-(rule 3 (amode_add (Amode.ImmRegRegShift off base index shift flags)
-                   (iconst (simm32 c)))
-      (if-let sum (s32_add_fallible off c))
-      (Amode.ImmRegRegShift sum base index shift flags))
-
-;; Likewise for a zero-extended i32 const, as long as the constant
-;; wasn't negative. (Why nonnegative? Because adding a
-;; non-sign-extended negative to a 64-bit address is not the same as
-;; adding in simm32-space.)
-(rule 3 (amode_add (Amode.ImmReg off base flags)
-                   (uextend (iconst (simm32 (u32_nonnegative c)))))
-      (if-let sum (s32_add_fallible off c))
-      (Amode.ImmReg sum base flags))
-(rule 3 (amode_add (Amode.ImmRegRegShift off base index shift flags)
-                   (uextend (iconst (simm32 (u32_nonnegative c)))))
-      (if-let sum (s32_add_fallible off c))
-      (Amode.ImmRegRegShift sum base index shift flags))
-
-;; Likewise for a sign-extended i32 const.
-(rule 3 (amode_add (Amode.ImmReg off base flags)
-                   (sextend (iconst (simm32 c))))
-      (if-let sum (s32_add_fallible off c))
-      (Amode.ImmReg sum base flags))
-(rule 3 (amode_add (Amode.ImmRegRegShift off base index shift flags)
-                   (sextend (iconst (simm32 c))))
-      (if-let sum (s32_add_fallible off c))
-      (Amode.ImmRegRegShift sum base index shift flags))
-
-;; -- Case 5 (fallback to add a new value to an imm+reg+scale*reg).
-;;
-;; An Amode.ImmRegRegShift can absorb any other value by creating a
-;; new add instruction and replacing the base with
-;; (base+value).
-(rule (amode_add (Amode.ImmRegRegShift off base index shift flags) value)
-      (let ((sum Gpr (x64_add $I64 base value)))
-        (Amode.ImmRegRegShift off sum index shift flags)))
-
-;; Finally, define the toplevel `to_amode`.
-(rule (to_amode flags base @ (value_type (ty_addr64 _)) offset)
-      (amode_finalize (amode_add (amode_initial flags offset) base)))
-
-;; If an amode has no registers at all and only offsets (a constant
-;; value), we need to "finalize" it by sticking in a zero'd reg in
-;; place of the (invalid_reg) produced by (amode_initial).
-(decl amode_finalize (Amode) Amode)
-(rule 1 (amode_finalize (Amode.ImmReg off (invalid_reg) flags))
-      (Amode.ImmReg off (imm $I64 0) flags))
-(rule 0 (amode_finalize amode)
-      amode)
+;; Note the recursion here where this rule is defined in terms of itself to
+;; "peel" layers of constants.
+(rule 3 (to_amode_add flags (iadd x (iconst (simm32 c))) y offset)
+      (if-let sum (s32_add_fallible offset c))
+      (to_amode_add flags x y sum))
+(rule 4 (to_amode_add flags x (iadd y (iconst (simm32 c))) offset)
+      (if-let sum (s32_add_fallible offset c))
+      (to_amode_add flags x y sum))
+(rule 5 (to_amode_add flags x (iconst (simm32 c)) offset)
+      (if-let sum (s32_add_fallible offset c))
+      (to_amode flags x sum))
+(rule 6 (to_amode_add flags (iconst (simm32 c)) x offset)
+      (if-let sum (s32_add_fallible offset c))
+      (to_amode flags x sum))
 
 ;; Offsetting an Amode. Used when we need to do consecutive
 ;; loads/stores to adjacent addresses.
@@ -1417,6 +1291,7 @@
             Vpextrw
             Vpextrd
             Vpextrq
+            Vpblendw
           ))
 
 (type Avx512Opcode extern
@@ -3094,6 +2969,14 @@
       (if-let $true (has_avx))
       (xmm_rmr_blend_vex (AvxOpcode.Vpblendvb) src1 src2 mask))
 
+;; Helper for creating `pblendw` instructions.
+(decl x64_pblendw (Xmm XmmMem u8) Xmm)
+(rule 0 (x64_pblendw src1 src2 imm)
+      (xmm_rm_r_imm (SseOpcode.Pblendw) src1 src2 imm (OperandSize.Size32)))
+(rule 1 (x64_pblendw src1 src2 imm)
+      (if-let $true (has_avx))
+      (xmm_rmr_imm_vex (AvxOpcode.Vpblendw) src1 src2 imm))
+
 ;; Helper for creating a `movsd` instruction which creates a new vector
 ;; register where the upper 64-bits are from the first operand and the low
 ;; 64-bits are from the second operand.
@@ -3787,10 +3670,10 @@
             (inst MInst (MInst.Neg size src dst)))
         (ProducesFlags.ProducesFlagsReturnsResultWithConsumer inst dst)))
 
-(decl x64_lea (SyntheticAmode) Gpr)
-(rule (x64_lea addr)
+(decl x64_lea (Type SyntheticAmode) Gpr)
+(rule (x64_lea ty addr)
       (let ((dst WritableGpr (temp_writable_gpr))
-            (_ Unit (emit (MInst.LoadEffectiveAddress addr dst))))
+            (_ Unit (emit (MInst.LoadEffectiveAddress addr dst (operand_size_of_type_32_64 ty)))))
         dst))
 
 ;; Helper for creating `ud2` instructions.
diff --git a/cranelift/codegen/src/isa/x64/inst/args.rs b/cranelift/codegen/src/isa/x64/inst/args.rs
index 024313c45..0c2db35cd 100644
--- a/cranelift/codegen/src/isa/x64/inst/args.rs
+++ b/cranelift/codegen/src/isa/x64/inst/args.rs
@@ -1125,6 +1125,7 @@ pub enum SseOpcode {
     Punpcklqdq,
     Pshuflw,
     Pshufhw,
+    Pblendw,
 }
 
 impl SseOpcode {
@@ -1318,7 +1319,8 @@ impl SseOpcode {
             | SseOpcode::Roundps
             | SseOpcode::Roundpd
             | SseOpcode::Roundss
-            | SseOpcode::Roundsd => SSE41,
+            | SseOpcode::Roundsd
+            | SseOpcode::Pblendw => SSE41,
 
             SseOpcode::Pcmpgtq => SSE42,
         }
@@ -1521,6 +1523,7 @@ impl fmt::Debug for SseOpcode {
             SseOpcode::Punpckhqdq => "punpckhqdq",
             SseOpcode::Pshuflw => "pshuflw",
             SseOpcode::Pshufhw => "pshufhw",
+            SseOpcode::Pblendw => "pblendw",
         };
         write!(fmt, "{}", name)
     }
@@ -1705,7 +1708,8 @@ impl AvxOpcode {
             | AvxOpcode::Vpextrb
             | AvxOpcode::Vpextrw
             | AvxOpcode::Vpextrd
-            | AvxOpcode::Vpextrq => {
+            | AvxOpcode::Vpextrq
+            | AvxOpcode::Vpblendw => {
                 smallvec![InstructionSet::AVX]
             }
         }
diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs
index 4e409979d..bc3db10e3 100644
--- a/cranelift/codegen/src/isa/x64/inst/emit.rs
+++ b/cranelift/codegen/src/isa/x64/inst/emit.rs
@@ -869,20 +869,84 @@ pub(crate) fn emit(
             )
         }
 
-        Inst::LoadEffectiveAddress { addr, dst } => {
+        Inst::LoadEffectiveAddress { addr, dst, size } => {
             let dst = allocs.next(dst.to_reg().to_reg());
             let amode = addr.finalize(state, sink).with_allocs(allocs);
 
-            emit_std_reg_mem(
-                sink,
-                LegacyPrefixes::None,
-                0x8D,
-                1,
-                dst,
-                &amode,
-                RexFlags::set_w(),
-                0,
-            );
+            // If this `lea` can actually get encoded as an `add` then do that
+            // instead. Currently all candidate `iadd`s become an `lea`
+            // pseudo-instruction here but maximizing the sue of `lea` is not
+            // necessarily optimal. The `lea` instruction goes through dedicated
+            // address units on cores which are finite and disjoint from the
+            // general ALU, so if everything uses `lea` then those units can get
+            // saturated while leaving the ALU idle.
+            //
+            // To help make use of more parts of a cpu, this attempts to use
+            // `add` when it's semantically equivalent to `lea`, or otherwise
+            // when the `dst` register is the same as the `base` or `index`
+            // register.
+            //
+            // FIXME: ideally regalloc is informed of this constraint. Register
+            // allocation of `lea` should "attempt" to put the `base` in the
+            // same register as `dst` but not at the expense of generating a
+            // `mov` instruction. Currently that's not possible but perhaps one
+            // day it may be worth it.
+            match amode {
+                // If `base == dst` then this is `add $imm, %dst`, so encode
+                // that instead.
+                Amode::ImmReg {
+                    simm32,
+                    base,
+                    flags: _,
+                } if base == dst => {
+                    let inst = Inst::alu_rmi_r(
+                        *size,
+                        AluRmiROpcode::Add,
+                        RegMemImm::imm(simm32),
+                        Writable::from_reg(dst),
+                    );
+                    inst.emit(&[], sink, info, state);
+                }
+                // If the offset is 0 and the shift is 0 (meaning multiplication
+                // by 1) then:
+                //
+                // * If `base == dst`, then this is `add %index, %base`
+                // * If `index == dst`, then this is `add %base, %index`
+                //
+                // Encode the appropriate instruction here in that case.
+                Amode::ImmRegRegShift {
+                    simm32: 0,
+                    base,
+                    index,
+                    shift: 0,
+                    flags: _,
+                } if base == dst || index == dst => {
+                    let (dst, operand) = if base == dst {
+                        (base, index)
+                    } else {
+                        (index, base)
+                    };
+                    let inst = Inst::alu_rmi_r(
+                        *size,
+                        AluRmiROpcode::Add,
+                        RegMemImm::reg(operand.to_reg()),
+                        Writable::from_reg(dst.to_reg()),
+                    );
+                    inst.emit(&[], sink, info, state);
+                }
+
+                // If `lea`'s 3-operand mode is leveraged by regalloc, or if
+                // it's fancy like imm-plus-shift-plus-base, then `lea` is
+                // actually emitted.
+                _ => {
+                    let flags = match size {
+                        OperandSize::Size32 => RexFlags::clear_w(),
+                        OperandSize::Size64 => RexFlags::set_w(),
+                        _ => unreachable!(),
+                    };
+                    emit_std_reg_mem(sink, LegacyPrefixes::None, 0x8D, 1, dst, &amode, flags, 0);
+                }
+            };
         }
 
         Inst::MovsxRmR { ext_mode, src, dst } => {
@@ -2199,6 +2263,7 @@ pub(crate) fn emit(
                 AvxOpcode::Vpalignr => (false, LegacyPrefixes::_66, OpcodeMap::_0F3A, 0x0F),
                 AvxOpcode::Vinsertps => (false, LegacyPrefixes::_66, OpcodeMap::_0F3A, 0x21),
                 AvxOpcode::Vshufps => (false, LegacyPrefixes::None, OpcodeMap::_0F, 0xC6),
+                AvxOpcode::Vpblendw => (false, LegacyPrefixes::_66, OpcodeMap::_0F3A, 0x0E),
                 _ => panic!("unexpected rmr_imm_vex opcode {op:?}"),
             };
 
@@ -2655,6 +2720,7 @@ pub(crate) fn emit(
                 SseOpcode::Pinsrw => (LegacyPrefixes::_66, 0x0FC4, 2),
                 SseOpcode::Pinsrd => (LegacyPrefixes::_66, 0x0F3A22, 3),
                 SseOpcode::Shufps => (LegacyPrefixes::None, 0x0FC6, 2),
+                SseOpcode::Pblendw => (LegacyPrefixes::_66, 0x0F3A0E, 3),
                 _ => unimplemented!("Opcode {:?} not implemented", op),
             };
             let rex = RexFlags::from(*size);
diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs
index b7865b21b..77689c642 100644
--- a/cranelift/codegen/src/isa/x64/inst/mod.rs
+++ b/cranelift/codegen/src/isa/x64/inst/mod.rs
@@ -429,6 +429,7 @@ impl Inst {
         Inst::LoadEffectiveAddress {
             addr: addr.into(),
             dst: WritableGpr::from_writable_reg(dst).unwrap(),
+            size: OperandSize::Size64,
         }
     }
 
@@ -1432,8 +1433,8 @@ impl PrettyPrint for Inst {
                 format!("{} {}, {}", ljustify("movq".to_string()), src, dst)
             }
 
-            Inst::LoadEffectiveAddress { addr, dst } => {
-                let dst = pretty_print_reg(dst.to_reg().to_reg(), 8, allocs);
+            Inst::LoadEffectiveAddress { addr, dst, size } => {
+                let dst = pretty_print_reg(dst.to_reg().to_reg(), size.to_bytes(), allocs);
                 let addr = addr.pretty_print(8, allocs);
                 format!("{} {}, {}", ljustify("lea".to_string()), addr, dst)
             }
@@ -2173,7 +2174,7 @@ fn x64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandCol
             collector.reg_def(dst.to_writable_reg());
             src.get_operands(collector);
         }
-        Inst::LoadEffectiveAddress { addr: src, dst } => {
+        Inst::LoadEffectiveAddress { addr: src, dst, .. } => {
             collector.reg_def(dst.to_writable_reg());
             src.get_operands(collector);
         }
diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle
index b5fcffe48..c532459e0 100644
--- a/cranelift/codegen/src/isa/x64/lower.isle
+++ b/cranelift/codegen/src/isa/x64/lower.isle
@@ -41,17 +41,27 @@
 
 ;; `i64` and smaller.
 
-;; Add two registers.
-(rule -5 (lower (has_type (fits_in_64 ty)
+;; Base case for 8 and 16-bit types
+(rule -6 (lower (has_type (fits_in_16 ty)
                        (iadd x y)))
       (x64_add ty x y))
 
-;; The above case handles when the rhs is an immediate or a sinkable load, but
-;; additionally add lhs meets these criteria.
-
+;; Base case for 32 and 64-bit types which might end up using the `lea`
+;; instruction to fold multiple operations into one.
+;;
+;; Note that at this time this always generates a `lea` pseudo-instruction,
+;; but the actual instruction emitted might be an `add` if it's equivalent.
+;; For more details on this see the `emit.rs` logic to emit
+;; `LoadEffectiveAddress`.
+(rule -5 (lower (has_type (ty_32_or_64 ty) (iadd x y)))
+      (x64_lea ty (to_amode_add (mem_flags_trusted) x y (zero_offset))))
+
+;; Higher-priority cases than the previous two where a load can be sunk into
+;; the add instruction itself. Note that both operands are tested for
+;; sink-ability since addition is commutative
 (rule -4 (lower (has_type (fits_in_64 ty)
-                       (iadd (simm32_from_value x) y)))
-      (x64_add ty y x))
+                       (iadd x (sinkable_load y))))
+      (x64_add ty x y))
 (rule -3 (lower (has_type (fits_in_64 ty)
                        (iadd (sinkable_load x) y)))
       (x64_add ty y x))
@@ -442,13 +452,14 @@
 (extern constructor ishl_i8x16_mask_table ishl_i8x16_mask_table)
 (rule (ishl_i8x16_mask (RegMemImm.Reg amt))
       (let ((mask_table SyntheticAmode (ishl_i8x16_mask_table))
-            (base_mask_addr Gpr (x64_lea mask_table))
+            (base_mask_addr Gpr (x64_lea $I64 mask_table))
             (mask_offset Gpr (x64_shl $I64 amt
                                   (imm8_to_imm8_gpr 4))))
-        (amode_imm_reg_reg_shift 0
-                                 base_mask_addr
-                                 mask_offset
-                                 0)))
+        (Amode.ImmRegRegShift 0
+                              base_mask_addr
+                              mask_offset
+                              0
+                              (mem_flags_trusted))))
 
 (rule (ishl_i8x16_mask (RegMemImm.Mem amt))
       (ishl_i8x16_mask (RegMemImm.Reg (x64_load $I64 amt (ExtKind.None)))))
@@ -546,14 +557,15 @@
 (extern constructor ushr_i8x16_mask_table ushr_i8x16_mask_table)
 (rule (ushr_i8x16_mask (RegMemImm.Reg amt))
       (let ((mask_table SyntheticAmode (ushr_i8x16_mask_table))
-            (base_mask_addr Gpr (x64_lea mask_table))
+            (base_mask_addr Gpr (x64_lea $I64 mask_table))
             (mask_offset Gpr (x64_shl $I64
                                   amt
                                   (imm8_to_imm8_gpr 4))))
-        (amode_imm_reg_reg_shift 0
-                                 base_mask_addr
-                                 mask_offset
-                                 0)))
+        (Amode.ImmRegRegShift 0
+                              base_mask_addr
+                              mask_offset
+                              0
+                              (mem_flags_trusted))))
 
 (rule (ushr_i8x16_mask (RegMemImm.Mem amt))
       (ushr_i8x16_mask (RegMemImm.Reg (x64_load $I64 amt (ExtKind.None)))))
@@ -3692,6 +3704,15 @@
 
 ;; Rules for `shuffle` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+;; Special case for `pblendw` which takes an 8-bit immediate where each bit
+;; indicates which lane of the two operands is chosen for the output. A bit of
+;; 0 chooses the corresponding 16-it lane from `a` and a bit of 1 chooses the
+;; corresponding 16-bit lane from `b`.
+(rule 14 (lower (shuffle a b (pblendw_imm n)))
+         (x64_pblendw a b n))
+(decl pblendw_imm (u8) Immediate)
+(extern extractor pblendw_imm pblendw_imm)
+
 ;; When the shuffle looks like "concatenate `a` and `b` and shift right by n*8
 ;; bytes", that's a `palignr` instruction. Note that the order of operands are
 ;; swapped in the instruction here. The `palignr` instruction uses the second
diff --git a/cranelift/codegen/src/isa/x64/lower/isle.rs b/cranelift/codegen/src/isa/x64/lower/isle.rs
index 4d0a96015..66b8091f7 100644
--- a/cranelift/codegen/src/isa/x64/lower/isle.rs
+++ b/cranelift/codegen/src/isa/x64/lower/isle.rs
@@ -315,21 +315,6 @@ impl Context for IsleContext<'_, '_, MInst, X64Backend> {
         RegMem::mem(addr.clone())
     }
 
-    #[inline]
-    fn amode_imm_reg_reg_shift(&mut self, simm32: u32, base: Gpr, index: Gpr, shift: u8) -> Amode {
-        Amode::imm_reg_reg_shift(simm32, base, index, shift)
-    }
-
-    #[inline]
-    fn amode_imm_reg(&mut self, simm32: u32, base: Gpr) -> Amode {
-        Amode::imm_reg(simm32, base.to_reg())
-    }
-
-    #[inline]
-    fn amode_with_flags(&mut self, amode: &Amode, flags: MemFlags) -> Amode {
-        amode.with_flags(flags)
-    }
-
     #[inline]
     fn amode_to_synthetic_amode(&mut self, amode: &Amode) -> SyntheticAmode {
         amode.clone().into()
@@ -995,6 +980,41 @@ impl Context for IsleContext<'_, '_, MInst, X64Backend> {
             None
         }
     }
+
+    fn pblendw_imm(&mut self, imm: Immediate) -> Option<u8> {
+        // First make sure that the shuffle immediate is selecting 16-bit lanes.
+        let (a, b, c, d, e, f, g, h) = self.shuffle16_from_imm(imm)?;
+
+        // Next build up an 8-bit mask from each of the bits of the selected
+        // lanes above. This instruction can only be used when each lane
+        // selector chooses from the corresponding lane in either of the two
+        // operands, meaning the Nth lane selection must satisfy `lane % 8 ==
+        // N`.
+        //
+        // This helper closure is used to calculate the value of the
+        // corresponding bit.
+        let bit = |x: u8, c: u8| {
+            if x % 8 == c {
+                if x < 8 {
+                    Some(0)
+                } else {
+                    Some(1 << c)
+                }
+            } else {
+                None
+            }
+        };
+        Some(
+            bit(a, 0)?
+                | bit(b, 1)?
+                | bit(c, 2)?
+                | bit(d, 3)?
+                | bit(e, 4)?
+                | bit(f, 5)?
+                | bit(g, 6)?
+                | bit(h, 7)?,
+        )
+    }
 }
 
 impl IsleContext<'_, '_, MInst, X64Backend> {
diff --git a/cranelift/codegen/src/isle_prelude.rs b/cranelift/codegen/src/isle_prelude.rs
index 9d78044b3..cf0caac32 100644
--- a/cranelift/codegen/src/isle_prelude.rs
+++ b/cranelift/codegen/src/isle_prelude.rs
@@ -648,6 +648,11 @@ macro_rules! isle_common_prelude_methods {
             offset as u32
         }
 
+        #[inline]
+        fn u32_to_offset32(&mut self, offset: u32) -> Offset32 {
+            Offset32::new(offset as i32)
+        }
+
         fn range(&mut self, start: usize, end: usize) -> Range {
             (start, end)
         }
diff --git a/cranelift/codegen/src/prelude.isle b/cranelift/codegen/src/prelude.isle
index 4815cf635..ef2741570 100644
--- a/cranelift/codegen/src/prelude.isle
+++ b/cranelift/codegen/src/prelude.isle
@@ -439,6 +439,10 @@
 (decl pure offset32_to_u32 (Offset32) u32)
 (extern constructor offset32_to_u32 offset32_to_u32)
 
+;; Convert a number to an `Offset32`
+(decl pure u32_to_offset32 (u32) Offset32)
+(extern constructor u32_to_offset32 u32_to_offset32)
+
 ;; This is a direct import of `IntCC::unsigned`.
 ;; Get the corresponding IntCC with the signed component removed.
 ;; For conditions without a signed component, this is a no-op.
@@ -491,3 +495,4 @@
 ;;;; Automatic conversions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (convert Offset32 u32 offset32_to_u32)
+(convert u32 Offset32 u32_to_offset32)
diff --git a/crates/jit/src/profiling/jitdump_linux.rs b/crates/jit/src/profiling/jitdump_linux.rs
index 1336bf215..4dcab8bc6 100644
--- a/crates/jit/src/profiling/jitdump_linux.rs
+++ b/crates/jit/src/profiling/jitdump_linux.rs
@@ -24,61 +24,43 @@ use object::elf;
 
 /// Interface for driving the creation of jitdump files
 pub struct JitDumpAgent {
-    // Note that we use a mutex internally to serialize writing out to our
-    // `jitdump_file` within this process, since multiple threads may be sharing
-    // this jit agent.
-    state: Mutex<State>,
-}
-
-struct State {
-    jitdump_file: JitDumpFile,
-
     /// Flag for experimenting with dumping code load record
     /// after each function (true) or after each module. This
     /// flag is currently set to true.
     dump_funcs: bool,
 }
 
+/// Process-wide JIT dump file. Perf only accepts a unique file per process, in the injection step.
+static JITDUMP_FILE: Mutex<Option<JitDumpFile>> = Mutex::new(None);
+
 impl JitDumpAgent {
-    /// Intialize a JitDumpAgent and write out the header
+    /// Intialize a JitDumpAgent and write out the header.
     pub fn new() -> Result<Self> {
-        let filename = format!("./jit-{}.dump", process::id());
-
-        let e_machine = match target_lexicon::HOST.architecture {
-            Architecture::X86_64 => elf::EM_X86_64 as u32,
-            Architecture::X86_32(_) => elf::EM_386 as u32,
-            Architecture::Arm(_) => elf::EM_ARM as u32,
-            Architecture::Aarch64(_) => elf::EM_AARCH64 as u32,
-            Architecture::S390x => elf::EM_S390 as u32,
-            _ => unimplemented!("unrecognized architecture"),
-        };
-
-        let jitdump_file = JitDumpFile::new(filename, e_machine)?;
+        let mut jitdump_file = JITDUMP_FILE.lock().unwrap();
+
+        if jitdump_file.is_none() {
+            let filename = format!("./jit-{}.dump", process::id());
+            let e_machine = match target_lexicon::HOST.architecture {
+                Architecture::X86_64 => elf::EM_X86_64 as u32,
+                Architecture::X86_32(_) => elf::EM_386 as u32,
+                Architecture::Arm(_) => elf::EM_ARM as u32,
+                Architecture::Aarch64(_) => elf::EM_AARCH64 as u32,
+                Architecture::S390x => elf::EM_S390 as u32,
+                _ => unimplemented!("unrecognized architecture"),
+            };
+            *jitdump_file = Some(JitDumpFile::new(filename, e_machine)?);
+        }
 
-        Ok(JitDumpAgent {
-            state: Mutex::new(State {
-                jitdump_file,
-                dump_funcs: true,
-            }),
-        })
+        Ok(JitDumpAgent { dump_funcs: true })
     }
 }
 
 impl ProfilingAgent for JitDumpAgent {
+    /// Sent when a method is compiled and loaded into memory by the VM.
     fn module_load(&self, module: &CompiledModule, dbg_image: Option<&[u8]>) {
-        self.state.lock().unwrap().module_load(module, dbg_image);
-    }
-    fn load_single_trampoline(&self, name: &str, addr: *const u8, size: usize, pid: u32, tid: u32) {
-        self.state
-            .lock()
-            .unwrap()
-            .load_single_trampoline(name, addr, size, pid, tid);
-    }
-}
+        let mut jitdump_file = JITDUMP_FILE.lock().unwrap();
+        let jitdump_file = jitdump_file.as_mut().unwrap();
 
-impl State {
-    /// Sent when a method is compiled and loaded into memory by the VM.
-    pub fn module_load(&mut self, module: &CompiledModule, dbg_image: Option<&[u8]>) {
         let pid = process::id();
         let tid = pid; // ThreadId does appear to track underlying thread. Using PID.
 
@@ -86,18 +68,19 @@ impl State {
             let addr = func.as_ptr();
             let len = func.len();
             if let Some(img) = &dbg_image {
-                if let Err(err) = self.dump_from_debug_image(img, "wasm", addr, len, pid, tid) {
+                if let Err(err) =
+                    self.dump_from_debug_image(jitdump_file, img, "wasm", addr, len, pid, tid)
+                {
                     println!(
                         "Jitdump: module_load failed dumping from debug image: {:?}\n",
                         err
                     );
                 }
             } else {
-                let timestamp = self.jitdump_file.get_time_stamp();
+                let timestamp = jitdump_file.get_time_stamp();
                 let name = super::debug_name(module, idx);
-                if let Err(err) = self
-                    .jitdump_file
-                    .dump_code_load_record(&name, addr, len, timestamp, pid, tid)
+                if let Err(err) =
+                    jitdump_file.dump_code_load_record(&name, addr, len, timestamp, pid, tid)
                 {
                     println!("Jitdump: write_code_load_failed_record failed: {:?}\n", err);
                 }
@@ -107,38 +90,34 @@ impl State {
         // Note: these are the trampolines into exported functions.
         for (idx, func, len) in module.trampolines() {
             let (addr, len) = (func as usize as *const u8, len);
-            let timestamp = self.jitdump_file.get_time_stamp();
+            let timestamp = jitdump_file.get_time_stamp();
             let name = format!("wasm::trampoline[{}]", idx.index());
-            if let Err(err) = self
-                .jitdump_file
-                .dump_code_load_record(&name, addr, len, timestamp, pid, tid)
+            if let Err(err) =
+                jitdump_file.dump_code_load_record(&name, addr, len, timestamp, pid, tid)
             {
                 println!("Jitdump: write_code_load_failed_record failed: {:?}\n", err);
             }
         }
     }
 
-    fn load_single_trampoline(
-        &mut self,
-        name: &str,
-        addr: *const u8,
-        size: usize,
-        pid: u32,
-        tid: u32,
-    ) {
-        let timestamp = self.jitdump_file.get_time_stamp();
-        if let Err(err) = self
-            .jitdump_file
-            .dump_code_load_record(&name, addr, size, timestamp, pid, tid)
+    fn load_single_trampoline(&self, name: &str, addr: *const u8, size: usize, pid: u32, tid: u32) {
+        let mut jitdump_file = JITDUMP_FILE.lock().unwrap();
+        let jitdump_file = jitdump_file.as_mut().unwrap();
+
+        let timestamp = jitdump_file.get_time_stamp();
+        if let Err(err) = jitdump_file.dump_code_load_record(&name, addr, size, timestamp, pid, tid)
         {
             println!("Jitdump: write_code_load_failed_record failed: {:?}\n", err);
         }
     }
+}
 
+impl JitDumpAgent {
     /// Attempts to dump debuginfo data structures, adding method and line level
     /// for the jitted function.
     pub fn dump_from_debug_image(
-        &mut self,
+        &self,
+        jitdump_file: &mut JitDumpFile,
         dbg_image: &[u8],
         module_name: &str,
         addr: *const u8,
@@ -178,16 +157,15 @@ impl State {
                     return Ok(());
                 }
             };
-            self.dump_entries(unit, &dwarf, module_name, addr, len, pid, tid)?;
+            self.dump_entries(jitdump_file, unit, &dwarf, module_name, addr, len, pid, tid)?;
             // TODO: Temp exit to avoid duplicate addresses being covered by only
             // processing the top unit
             break;
         }
         if !self.dump_funcs {
-            let timestamp = self.jitdump_file.get_time_stamp();
+            let timestamp = jitdump_file.get_time_stamp();
             if let Err(err) =
-                self.jitdump_file
-                    .dump_code_load_record(module_name, addr, len, timestamp, pid, tid)
+                jitdump_file.dump_code_load_record(module_name, addr, len, timestamp, pid, tid)
             {
                 println!("Jitdump: write_code_load_failed_record failed: {:?}\n", err);
             }
@@ -196,7 +174,8 @@ impl State {
     }
 
     fn dump_entries<R: Reader>(
-        &mut self,
+        &self,
+        jitdump_file: &mut JitDumpFile,
         unit: gimli::Unit<R>,
         dwarf: &gimli::Dwarf<R>,
         module_name: &str,
@@ -285,17 +264,15 @@ impl State {
                     clr.header.record_size = mem::size_of::<CodeLoadRecord>() as u32
                         + (clr_name.len() + 1) as u32
                         + clr.size as u32;
-                    clr.index = self.jitdump_file.next_code_index();
-                    self.dump_debug_info(&unit, &dwarf, clr.address, clr.size, None)?;
+                    clr.index = jitdump_file.next_code_index();
+                    self.dump_debug_info(jitdump_file, &unit, &dwarf, clr.address, clr.size, None)?;
 
-                    clr.header.timestamp = self.jitdump_file.get_time_stamp();
+                    clr.header.timestamp = jitdump_file.get_time_stamp();
 
                     unsafe {
                         let code_buffer: &[u8] =
                             std::slice::from_raw_parts(clr.address as *const u8, clr.size as usize);
-                        let _ =
-                            self.jitdump_file
-                                .write_code_load_record(&clr_name, clr, code_buffer);
+                        let _ = jitdump_file.write_code_load_record(&clr_name, clr, code_buffer);
                     }
                 }
             } else {
@@ -353,6 +330,7 @@ impl State {
                         continue;
                     }
                     self.dump_debug_info(
+                        jitdump_file,
                         &unit,
                         &dwarf,
                         func_addr,
@@ -366,14 +344,15 @@ impl State {
     }
 
     fn dump_debug_info<R: Reader>(
-        &mut self,
+        &self,
+        jitdump_file: &mut JitDumpFile,
         unit: &gimli::Unit<R>,
         dwarf: &gimli::Dwarf<R>,
         address: u64,
         size: u64,
         file_suffix: Option<&str>,
     ) -> Result<()> {
-        let timestamp = self.jitdump_file.get_time_stamp();
+        let timestamp = jitdump_file.get_time_stamp();
         if let Some(program) = unit.line_program.clone() {
             let mut debug_info_record = DebugInfoRecord {
                 header: RecordHeader {
@@ -430,8 +409,8 @@ impl State {
             debug_info_record.header.record_size =
                 mem::size_of::<DebugInfoRecord>() as u32 + debug_entries_size as u32;
 
-            let _ = self.jitdump_file.write_debug_info_record(debug_info_record);
-            let _ = self.jitdump_file.write_debug_info_entries(debug_entries);
+            let _ = jitdump_file.write_debug_info_record(debug_info_record);
+            let _ = jitdump_file.write_debug_info_entries(debug_entries);
         }
         Ok(())
     }


Test patch:
diff --git a/cranelift/filetests/filetests/isa/x64/amode-opt.clif b/cranelift/filetests/filetests/isa/x64/amode-opt.clif
index eef1d2893..e3d689998 100644
--- a/cranelift/filetests/filetests/isa/x64/amode-opt.clif
+++ b/cranelift/filetests/filetests/isa/x64/amode-opt.clif
@@ -1,4 +1,6 @@
 test compile precise-output
+set use_egraphs=true
+set opt_level=speed
 target x86_64
 
 function %amode_add(i64, i64) -> i64 {
@@ -244,8 +246,7 @@ block0(v0: i64, v1: i32, v2: i32):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movq    %rsi, %r8
-;   addl    %r8d, %edx, %r8d
+;   lea     0(%rsi,%rdx,1), %r8d
 ;   shll    $2, %r8d, %r8d
 ;   movq    -1(%rdi,%r8,1), %rax
 ;   movq    %rbp, %rsp
@@ -257,8 +258,7 @@ block0(v0: i64, v1: i32, v2: i32):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movq %rsi, %r8
-;   addl %edx, %r8d
+;   leal (%rsi, %rdx), %r8d
 ;   shll $2, %r8d
 ;   movq -1(%rdi, %r8), %rax ; trap: heap_oob
 ;   movq %rbp, %rsp
diff --git a/cranelift/filetests/filetests/isa/x64/basic.clif b/cranelift/filetests/filetests/isa/x64/basic.clif
index d10885cd0..01fac2deb 100644
--- a/cranelift/filetests/filetests/isa/x64/basic.clif
+++ b/cranelift/filetests/filetests/isa/x64/basic.clif
@@ -11,8 +11,7 @@ block0(v0: i32, v1: i32):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movq    %rdi, %rax
-;   addl    %eax, %esi, %eax
+;   lea     0(%rdi,%rsi,1), %eax
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -22,8 +21,7 @@ block0(v0: i32, v1: i32):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movq %rdi, %rax
-;   addl %esi, %eax
+;   leal (%rdi, %rsi), %eax
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
diff --git a/cranelift/filetests/filetests/isa/x64/branches.clif b/cranelift/filetests/filetests/isa/x64/branches.clif
index 01d9c3abd..bdaf6b5b6 100644
--- a/cranelift/filetests/filetests/isa/x64/branches.clif
+++ b/cranelift/filetests/filetests/isa/x64/branches.clif
@@ -784,8 +784,7 @@ block5(v5: i32):
 ;   movl    $4, %esi
 ;   jmp     label7
 ; block7:
-;   movq    %rdi, %rax
-;   addl    %eax, %esi, %eax
+;   lea     0(%rdi,%rsi,1), %eax
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -825,8 +824,7 @@ block5(v5: i32):
 ; block6: ; offset 0x59
 ;   movl $4, %esi
 ; block7: ; offset 0x5e
-;   movq %rdi, %rax
-;   addl %esi, %eax
+;   leal (%rdi, %rsi), %eax
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
diff --git a/cranelift/filetests/filetests/isa/x64/immediates.clif b/cranelift/filetests/filetests/isa/x64/immediates.clif
index bdbd7ece6..62528f0b6 100644
--- a/cranelift/filetests/filetests/isa/x64/immediates.clif
+++ b/cranelift/filetests/filetests/isa/x64/immediates.clif
@@ -19,15 +19,15 @@ block0(v0: i64, v1: i64):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movq    %rdi, %r9
-;   addq    %r9, const(0), %r9
-;   movq    %r9, 0(%rsi)
-;   movq    %rdi, %r10
-;   subq    %r10, const(0), %r10
-;   movq    %r10, 0(%rsi)
+;   movabsq $-18765284782900, %r9
+;   lea     0(%rdi,%r9,1), %r11
+;   movq    %r11, 0(%rsi)
 ;   movq    %rdi, %r11
-;   andq    %r11, const(0), %r11
+;   subq    %r11, const(0), %r11
 ;   movq    %r11, 0(%rsi)
+;   movq    %rdi, %rax
+;   andq    %rax, const(0), %rax
+;   movq    %rax, 0(%rsi)
 ;   orq     %rdi, const(0), %rdi
 ;   movq    %rdi, 0(%rsi)
 ;   movq    %rbp, %rsp
@@ -39,24 +39,21 @@ block0(v0: i64, v1: i64):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movq %rdi, %r9
-;   addq 0x32(%rip), %r9
-;   movq %r9, (%rsi) ; trap: heap_oob
-;   movq %rdi, %r10
-;   subq 0x25(%rip), %r10
-;   movq %r10, (%rsi) ; trap: heap_oob
+;   movabsq $18446725308424768716, %r9
+;   leaq (%rdi, %r9), %r11
+;   movq %r11, (%rsi) ; trap: heap_oob
 ;   movq %rdi, %r11
-;   andq 0x18(%rip), %r11
+;   subq 0x20(%rip), %r11
 ;   movq %r11, (%rsi) ; trap: heap_oob
-;   orq 0xe(%rip), %rdi
+;   movq %rdi, %rax
+;   andq 0x13(%rip), %rax
+;   movq %rax, (%rsi) ; trap: heap_oob
+;   orq 9(%rip), %rdi
 ;   movq %rdi, (%rsi) ; trap: heap_oob
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   int3
+;   addb %cl, %ah
 ;   int3
 ;   fstp %st(5)
 ;   outb %al, %dx
diff --git a/cranelift/filetests/filetests/isa/x64/lea.clif b/cranelift/filetests/filetests/isa/x64/lea.clif
new file mode 100644
index 000000000..4dc8182bd
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/x64/lea.clif
@@ -0,0 +1,271 @@
+test compile precise-output
+target x86_64
+
+function %add_i32(i32, i32) -> i32 {
+block0(v0: i32, v1: i32):
+  v2 = iadd v0, v1
+  return v2
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   lea     0(%rdi,%rsi,1), %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   leal (%rdi, %rsi), %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %add_i64(i64, i64) -> i64 {
+block0(v0: i64, v1: i64):
+  v2 = iadd v0, v1
+  return v2
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   lea     0(%rdi,%rsi,1), %rax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   leaq (%rdi, %rsi), %rax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %add_i32_const(i32) -> i32 {
+block0(v0: i32):
+  v1 = iconst.i32 100
+  v2 = iadd v0, v1
+  return v2
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   lea     100(%rdi), %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   leal 0x64(%rdi), %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %add_i64_const(i64) -> i64 {
+block0(v0: i64):
+  v1 = iconst.i64 100
+  v2 = iadd v0, v1
+  return v2
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   lea     100(%rdi), %rax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   leaq 0x64(%rdi), %rax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %add_i32_i32_const(i32, i32) -> i32 {
+block0(v0: i32, v1: i32):
+  v2 = iconst.i32 100
+  v3 = iadd v0, v1
+  v4 = iadd v3, v2
+  return v4
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   lea     100(%rdi,%rsi,1), %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   leal 0x64(%rdi, %rsi), %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %add_i64_i64_const(i64, i64) -> i64 {
+block0(v0: i64, v1: i64):
+  v2 = iconst.i64 100
+  v3 = iadd v0, v1
+  v4 = iadd v3, v2
+  return v4
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   lea     100(%rdi,%rsi,1), %rax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   leaq 0x64(%rdi, %rsi), %rax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %add_i32_i32_mul_const(i32, i32) -> i32 {
+block0(v0: i32, v1: i32):
+  v2 = iconst.i32 100
+  v3 = iconst.i32 2
+  v4 = ishl v1, v3
+  v5 = iadd v0, v4
+  v6 = iadd v5, v2
+  return v6
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   lea     100(%rdi,%rsi,4), %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   leal 0x64(%rdi, %rsi, 4), %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %add_i64_i64_mul_const(i64, i64) -> i64 {
+block0(v0: i64, v1: i64):
+  v2 = iconst.i64 100
+  v3 = iconst.i64 2
+  v4 = ishl v1, v3
+  v5 = iadd v0, v4
+  v6 = iadd v5, v2
+  return v6
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   lea     100(%rdi,%rsi,4), %rax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   leaq 0x64(%rdi, %rsi, 4), %rax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %add_i32_i32_mul(i32, i32) -> i32 {
+block0(v0: i32, v1: i32):
+  v3 = iconst.i32 2
+  v4 = ishl v1, v3
+  v5 = iadd v0, v4
+  return v5
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   lea     0(%rdi,%rsi,4), %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   leal (%rdi, %rsi, 4), %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %add_i64_i64_mul(i64, i64) -> i64 {
+block0(v0: i64, v1: i64):
+  v3 = iconst.i64 2
+  v4 = ishl v1, v3
+  v5 = iadd v0, v4
+  return v5
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   lea     0(%rdi,%rsi,4), %rax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   leaq (%rdi, %rsi, 4), %rax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
diff --git a/cranelift/filetests/filetests/isa/x64/load-op.clif b/cranelift/filetests/filetests/isa/x64/load-op.clif
index ab140cb5f..3c4e5fde9 100644
--- a/cranelift/filetests/filetests/isa/x64/load-op.clif
+++ b/cranelift/filetests/filetests/isa/x64/load-op.clif
@@ -155,8 +155,7 @@ block0(v0: i64, v1: i64):
 ;   movq    %rsp, %rbp
 ; block0:
 ;   movq    0(%rdi), %r8
-;   movq    %r8, %r9
-;   addq    %r9, %rdi, %r9
+;   lea     0(%r8,%rdi,1), %r9
 ;   movq    %r9, 0(%rsi)
 ;   movq    0(%r8,%rdi,1), %rax
 ;   movq    %rbp, %rsp
@@ -169,8 +168,7 @@ block0(v0: i64, v1: i64):
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
 ;   movq (%rdi), %r8 ; trap: heap_oob
-;   movq %r8, %r9
-;   addq %rdi, %r9
+;   leaq (%r8, %rdi), %r9
 ;   movq %r9, (%rsi) ; trap: heap_oob
 ;   movq (%r8, %rdi), %rax ; trap: heap_oob
 ;   movq %rbp, %rsp
diff --git a/cranelift/filetests/filetests/isa/x64/pinned-reg.clif b/cranelift/filetests/filetests/isa/x64/pinned-reg.clif
index 26bc0b280..36797fb11 100644
--- a/cranelift/filetests/filetests/isa/x64/pinned-reg.clif
+++ b/cranelift/filetests/filetests/isa/x64/pinned-reg.clif
@@ -14,9 +14,9 @@ block0:
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movq    %r15, %rsi
-;   addq    %rsi, $1, %rsi
-;   movq    %rsi, %r15
+;   movq    %r15, %rdi
+;   lea     1(%rdi), %rdi
+;   movq    %rdi, %r15
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -26,9 +26,9 @@ block0:
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movq %r15, %rsi
-;   addq $1, %rsi
-;   movq %rsi, %r15
+;   movq %r15, %rdi
+;   addq $1, %rdi
+;   movq %rdi, %r15
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
@@ -45,12 +45,12 @@ block0:
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ;   subq    %rsp, $16, %rsp
-;   movq    %rsi, 0(%rsp)
+;   movq    %rdi, 0(%rsp)
 ; block0:
-;   movq    %r15, %rsi
-;   addq    %rsi, $1, %rsi
-;   movq    %rsi, %r15
-;   movq    0(%rsp), %rsi
+;   movq    %r15, %rdi
+;   lea     1(%rdi), %rdi
+;   movq    %rdi, %r15
+;   movq    0(%rsp), %rdi
 ;   addq    %rsp, $16, %rsp
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -61,12 +61,12 @@ block0:
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ;   subq $0x10, %rsp
-;   movq %rsi, (%rsp)
+;   movq %rdi, (%rsp)
 ; block1: ; offset 0xc
-;   movq %r15, %rsi
-;   addq $1, %rsi
-;   movq %rsi, %r15
-;   movq (%rsp), %rsi
+;   movq %r15, %rdi
+;   addq $1, %rdi
+;   movq %rdi, %r15
+;   movq (%rsp), %rdi
 ;   addq $0x10, %rsp
 ;   movq %rbp, %rsp
 ;   popq %rbp
diff --git a/cranelift/filetests/filetests/isa/x64/shuffle-avx.clif b/cranelift/filetests/filetests/isa/x64/shuffle-avx.clif
index 30cf9721e..06aa6da5a 100644
--- a/cranelift/filetests/filetests/isa/x64/shuffle-avx.clif
+++ b/cranelift/filetests/filetests/isa/x64/shuffle-avx.clif
@@ -114,3 +114,31 @@ block0(v0: i64x2, v1: i64x2):
 ;   popq %rbp
 ;   retq
 
+function %pblendw_0b10011001(i16x8, i16x8) -> i16x8 {
+block0(v0: i16x8, v1: i16x8):
+    v2 = bitcast.i8x16 little v0
+    v3 = bitcast.i8x16 little v1
+    v4 = shuffle v2, v3, [16 17 2 3 4 5 22 23 24 25 10 11 12 13 30 31]
+    v5 = bitcast.i16x8 little v4
+    return v5
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vpblendw $153, %xmm0, %xmm1, %xmm0
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vpblendw $0x99, %xmm1, %xmm0, %xmm0
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
diff --git a/cranelift/filetests/filetests/isa/x64/shuffle.clif b/cranelift/filetests/filetests/isa/x64/shuffle.clif
index f8f9b613e..cf58cd916 100644
--- a/cranelift/filetests/filetests/isa/x64/shuffle.clif
+++ b/cranelift/filetests/filetests/isa/x64/shuffle.clif
@@ -654,9 +654,7 @@ block0(v0: i8x16, v1: i8x16):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqa  %xmm0, %xmm4
-;   movdqa  %xmm1, %xmm0
-;   palignr $0, %xmm0, %xmm4, %xmm0
+;   pblendw $0, %xmm0, %xmm1, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -666,9 +664,7 @@ block0(v0: i8x16, v1: i8x16):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqa %xmm0, %xmm4
-;   movdqa %xmm1, %xmm0
-;   palignr $0, %xmm4, %xmm0
+;   pblendw $0, %xmm1, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
@@ -770,9 +766,7 @@ block0(v0: i8x16, v1: i8x16):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqa  %xmm0, %xmm4
-;   movdqa  %xmm1, %xmm0
-;   palignr $16, %xmm0, %xmm4, %xmm0
+;   pblendw $255, %xmm0, %xmm1, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -782,9 +776,35 @@ block0(v0: i8x16, v1: i8x16):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqa %xmm0, %xmm4
-;   movdqa %xmm1, %xmm0
-;   palignr $0x10, %xmm4, %xmm0
+;   pblendw $0xff, %xmm1, %xmm0
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %pblendw_0b10011001(i16x8, i16x8) -> i16x8 {
+block0(v0: i16x8, v1: i16x8):
+    v2 = bitcast.i8x16 little v0
+    v3 = bitcast.i8x16 little v1
+    v4 = shuffle v2, v3, [16 17 2 3 4 5 22 23 24 25 10 11 12 13 30 31]
+    v5 = bitcast.i16x8 little v4
+    return v5
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   pblendw $153, %xmm0, %xmm1, %xmm0
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   pblendw $0x99, %xmm1, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
diff --git a/cranelift/filetests/filetests/isa/x64/table.clif b/cranelift/filetests/filetests/isa/x64/table.clif
index 101debb9b..0bfe7a35f 100644
--- a/cranelift/filetests/filetests/isa/x64/table.clif
+++ b/cranelift/filetests/filetests/isa/x64/table.clif
@@ -26,11 +26,10 @@ block0(v0: i32, v1: r64, v2: i64):
 ; block1:
 ;   movl    %edi, %ecx
 ;   movq    0(%rdx), %rax
-;   movq    %rax, %rdx
-;   addq    %rdx, %rcx, %rdx
+;   lea     0(%rax,%rcx,1), %rcx
 ;   cmpl    %r11d, %edi
-;   cmovnbq %rax, %rdx, %rdx
-;   movq    %rsi, 0(%rdx)
+;   cmovnbq %rax, %rcx, %rcx
+;   movq    %rsi, 0(%rcx)
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -44,18 +43,17 @@ block0(v0: i32, v1: r64, v2: i64):
 ; block1: ; offset 0x4
 ;   movl 8(%rdx), %r11d
 ;   cmpl %r11d, %edi
-;   jae 0x2b
+;   jae 0x28
 ; block2: ; offset 0x11
 ;   movl %edi, %ecx
 ;   movq (%rdx), %rax
-;   movq %rax, %rdx
-;   addq %rcx, %rdx
+;   addq %rax, %rcx
 ;   cmpl %r11d, %edi
-;   cmovaeq %rax, %rdx
-;   movq %rsi, (%rdx)
+;   cmovaeq %rax, %rcx
+;   movq %rsi, (%rcx)
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
-; block3: ; offset 0x2b
+; block3: ; offset 0x28
 ;   ud2 ; trap: table_oob
 
diff --git a/cranelift/filetests/filetests/isa/x64/uextend-elision.clif b/cranelift/filetests/filetests/isa/x64/uextend-elision.clif
index faf3a6763..d4e306f50 100644
--- a/cranelift/filetests/filetests/isa/x64/uextend-elision.clif
+++ b/cranelift/filetests/filetests/isa/x64/uextend-elision.clif
@@ -12,8 +12,7 @@ block0(v0: i32, v1: i32):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movq    %rdi, %rax
-;   addl    %eax, %esi, %eax
+;   lea     0(%rdi,%rsi,1), %eax
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -23,8 +22,7 @@ block0(v0: i32, v1: i32):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movq %rdi, %rax
-;   addl %esi, %eax
+;   leal (%rdi, %rsi), %eax
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
index b53718fbb..3010a8185 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -45,17 +45,17 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r11d
-;;   movq    %r11, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r8d
+;;   movq    %r8, %r11
+;;   addq    %r11, const(0), %r11
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rdx), %rax
-;;   cmpq    %rax, %rdi
+;;   movq    8(%rdx), %rdi
+;;   cmpq    %rdi, %r11
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rdx), %rdi
-;;   addq    %rdi, const(0), %rdi
-;;   movl    %esi, 0(%rdi,%r11,1)
+;;   addq    %r8, 0(%rdx), %r8
+;;   movl    $-65536, %eax
+;;   movl    %esi, 0(%r8,%rax,1)
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
@@ -70,17 +70,17 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r11d
-;;   movq    %r11, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r8d
+;;   movq    %r8, %r11
+;;   addq    %r11, const(0), %r11
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rsi), %rax
-;;   cmpq    %rax, %rdi
+;;   movq    8(%rsi), %rdi
+;;   cmpq    %rdi, %r11
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rsi), %rsi
-;;   addq    %rsi, const(0), %rsi
-;;   movl    0(%rsi,%r11,1), %eax
+;;   addq    %r8, 0(%rsi), %r8
+;;   movl    $-65536, %edi
+;;   movl    0(%r8,%rdi,1), %eax
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
index b8c74b7a2..5c3c1ac1e 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -45,17 +45,17 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r11d
-;;   movq    %r11, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r8d
+;;   movq    %r8, %r11
+;;   addq    %r11, const(0), %r11
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rdx), %rax
-;;   cmpq    %rax, %rdi
+;;   movq    8(%rdx), %rdi
+;;   cmpq    %rdi, %r11
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rdx), %rdi
-;;   addq    %rdi, const(0), %rdi
-;;   movb    %sil, 0(%rdi,%r11,1)
+;;   addq    %r8, 0(%rdx), %r8
+;;   movl    $-65536, %eax
+;;   movb    %sil, 0(%r8,%rax,1)
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
@@ -70,17 +70,17 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r11d
-;;   movq    %r11, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r8d
+;;   movq    %r8, %r11
+;;   addq    %r11, const(0), %r11
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rsi), %rax
-;;   cmpq    %rax, %rdi
+;;   movq    8(%rsi), %rdi
+;;   cmpq    %rdi, %r11
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rsi), %rsi
-;;   addq    %rsi, const(0), %rsi
-;;   movzbq  0(%rsi,%r11,1), %rax
+;;   addq    %r8, 0(%rsi), %r8
+;;   movl    $-65536, %edi
+;;   movzbq  0(%r8,%rdi,1), %rax
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
index 8bc688f26..3c42b63e6 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
@@ -48,13 +48,12 @@
 ;;   movl    %edi, %edi
 ;;   movabsq $-4100, %rax
 ;;   addq    %rax, 8(%rdx), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rdx), %r11
-;;   addq    %r11, $4096, %r11
-;;   xorq    %rcx, %rcx, %rcx
+;;   movq    0(%rdx), %rcx
+;;   lea     4096(%rcx,%rdi,1), %rcx
+;;   xorq    %rdx, %rdx, %rdx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r11, %r11
-;;   movl    %esi, 0(%r11)
+;;   cmovnbeq %rdx, %rcx, %rcx
+;;   movl    %esi, 0(%rcx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -70,15 +69,14 @@
 ;;   movl    %edi, %edi
 ;;   movabsq $-4100, %rax
 ;;   addq    %rax, 8(%rsi), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rsi), %r11
-;;   addq    %r11, $4096, %r11
-;;   xorq    %rsi, %rsi, %rsi
+;;   movq    0(%rsi), %rcx
+;;   lea     4096(%rcx,%rdi,1), %rsi
+;;   xorq    %rcx, %rcx, %rcx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rsi, %r11, %r11
-;;   movl    0(%r11), %eax
+;;   cmovnbeq %rcx, %rsi, %rsi
+;;   movl    0(%rsi), %eax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
index f4f79fff1..412b47919 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
@@ -45,17 +45,18 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r8d
-;;   movq    %r8, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r11d
+;;   movq    %r11, %rax
+;;   addq    %rax, const(0), %rax
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rdx), %rax
-;;   addq    %r8, 0(%rdx), %r8
-;;   addq    %r8, const(0), %r8
-;;   xorq    %rcx, %rcx, %rcx
-;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r8, %r8
-;;   movl    %esi, 0(%r8)
+;;   movq    8(%rdx), %rcx
+;;   addq    %r11, 0(%rdx), %r11
+;;   movl    $-65536, %edx
+;;   lea     0(%r11,%rdx,1), %rdx
+;;   xorq    %r8, %r8, %r8
+;;   cmpq    %rcx, %rax
+;;   cmovnbeq %r8, %rdx, %rdx
+;;   movl    %esi, 0(%rdx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -68,19 +69,20 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r8d
-;;   movq    %r8, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r11d
+;;   movq    %r11, %rax
+;;   addq    %rax, const(0), %rax
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rsi), %rax
-;;   addq    %r8, 0(%rsi), %r8
-;;   addq    %r8, const(0), %r8
-;;   xorq    %rcx, %rcx, %rcx
-;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r8, %r8
-;;   movl    0(%r8), %eax
+;;   movq    8(%rsi), %rcx
+;;   addq    %r11, 0(%rsi), %r11
+;;   movl    $-65536, %edx
+;;   lea     0(%r11,%rdx,1), %rdx
+;;   xorq    %r8, %r8, %r8
+;;   cmpq    %rcx, %rax
+;;   cmovnbeq %r8, %rdx, %rdx
+;;   movl    0(%rdx), %eax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
index f10feb9cb..69169611b 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
@@ -48,13 +48,12 @@
 ;;   movl    %edi, %edi
 ;;   movabsq $-4097, %rax
 ;;   addq    %rax, 8(%rdx), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rdx), %r11
-;;   addq    %r11, $4096, %r11
-;;   xorq    %rcx, %rcx, %rcx
+;;   movq    0(%rdx), %rcx
+;;   lea     4096(%rcx,%rdi,1), %rcx
+;;   xorq    %rdx, %rdx, %rdx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r11, %r11
-;;   movb    %sil, 0(%r11)
+;;   cmovnbeq %rdx, %rcx, %rcx
+;;   movb    %sil, 0(%rcx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -70,15 +69,14 @@
 ;;   movl    %edi, %edi
 ;;   movabsq $-4097, %rax
 ;;   addq    %rax, 8(%rsi), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rsi), %r11
-;;   addq    %r11, $4096, %r11
-;;   xorq    %rsi, %rsi, %rsi
+;;   movq    0(%rsi), %rcx
+;;   lea     4096(%rcx,%rdi,1), %rsi
+;;   xorq    %rcx, %rcx, %rcx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rsi, %r11, %r11
-;;   movzbq  0(%r11), %rax
+;;   cmovnbeq %rcx, %rsi, %rsi
+;;   movzbq  0(%rsi), %rax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
index c68204b5d..a4adf2663 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
@@ -45,17 +45,18 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r8d
-;;   movq    %r8, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r11d
+;;   movq    %r11, %rax
+;;   addq    %rax, const(0), %rax
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rdx), %rax
-;;   addq    %r8, 0(%rdx), %r8
-;;   addq    %r8, const(0), %r8
-;;   xorq    %rcx, %rcx, %rcx
-;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r8, %r8
-;;   movb    %sil, 0(%r8)
+;;   movq    8(%rdx), %rcx
+;;   addq    %r11, 0(%rdx), %r11
+;;   movl    $-65536, %edx
+;;   lea     0(%r11,%rdx,1), %rdx
+;;   xorq    %r8, %r8, %r8
+;;   cmpq    %rcx, %rax
+;;   cmovnbeq %r8, %rdx, %rdx
+;;   movb    %sil, 0(%rdx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -68,19 +69,20 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r8d
-;;   movq    %r8, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r11d
+;;   movq    %r11, %rax
+;;   addq    %rax, const(0), %rax
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rsi), %rax
-;;   addq    %r8, 0(%rsi), %r8
-;;   addq    %r8, const(0), %r8
-;;   xorq    %rcx, %rcx, %rcx
-;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r8, %r8
-;;   movzbq  0(%r8), %rax
+;;   movq    8(%rsi), %rcx
+;;   addq    %r11, 0(%rsi), %r11
+;;   movl    $-65536, %edx
+;;   lea     0(%r11,%rdx,1), %rdx
+;;   xorq    %r8, %r8, %r8
+;;   cmpq    %rcx, %rax
+;;   cmovnbeq %r8, %rdx, %rdx
+;;   movzbq  0(%rdx), %rax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
index 41697bf72..2b8019e85 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -45,17 +45,17 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r11d
-;;   movq    %r11, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r8d
+;;   movq    %r8, %r11
+;;   addq    %r11, const(0), %r11
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rdx), %rax
-;;   cmpq    %rax, %rdi
+;;   movq    8(%rdx), %rdi
+;;   cmpq    %rdi, %r11
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rdx), %rdi
-;;   addq    %rdi, const(0), %rdi
-;;   movl    %esi, 0(%rdi,%r11,1)
+;;   addq    %r8, 0(%rdx), %r8
+;;   movl    $-65536, %eax
+;;   movl    %esi, 0(%r8,%rax,1)
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
@@ -70,17 +70,17 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r11d
-;;   movq    %r11, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r8d
+;;   movq    %r8, %r11
+;;   addq    %r11, const(0), %r11
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rsi), %rax
-;;   cmpq    %rax, %rdi
+;;   movq    8(%rsi), %rdi
+;;   cmpq    %rdi, %r11
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rsi), %rsi
-;;   addq    %rsi, const(0), %rsi
-;;   movl    0(%rsi,%r11,1), %eax
+;;   addq    %r8, 0(%rsi), %r8
+;;   movl    $-65536, %edi
+;;   movl    0(%r8,%rdi,1), %eax
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
index cc2c6f792..29ff03b82 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -45,17 +45,17 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r11d
-;;   movq    %r11, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r8d
+;;   movq    %r8, %r11
+;;   addq    %r11, const(0), %r11
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rdx), %rax
-;;   cmpq    %rax, %rdi
+;;   movq    8(%rdx), %rdi
+;;   cmpq    %rdi, %r11
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rdx), %rdi
-;;   addq    %rdi, const(0), %rdi
-;;   movb    %sil, 0(%rdi,%r11,1)
+;;   addq    %r8, 0(%rdx), %r8
+;;   movl    $-65536, %eax
+;;   movb    %sil, 0(%r8,%rax,1)
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
@@ -70,17 +70,17 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r11d
-;;   movq    %r11, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r8d
+;;   movq    %r8, %r11
+;;   addq    %r11, const(0), %r11
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rsi), %rax
-;;   cmpq    %rax, %rdi
+;;   movq    8(%rsi), %rdi
+;;   cmpq    %rdi, %r11
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rsi), %rsi
-;;   addq    %rsi, const(0), %rsi
-;;   movzbq  0(%rsi,%r11,1), %rax
+;;   addq    %r8, 0(%rsi), %r8
+;;   movl    $-65536, %edi
+;;   movzbq  0(%r8,%rdi,1), %rax
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
index e9cc1c103..9b8f9e4b3 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
@@ -48,13 +48,12 @@
 ;;   movl    %edi, %edi
 ;;   movabsq $-4100, %rax
 ;;   addq    %rax, 8(%rdx), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rdx), %r11
-;;   addq    %r11, $4096, %r11
-;;   xorq    %rcx, %rcx, %rcx
+;;   movq    0(%rdx), %rcx
+;;   lea     4096(%rcx,%rdi,1), %rcx
+;;   xorq    %rdx, %rdx, %rdx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r11, %r11
-;;   movl    %esi, 0(%r11)
+;;   cmovnbeq %rdx, %rcx, %rcx
+;;   movl    %esi, 0(%rcx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -70,15 +69,14 @@
 ;;   movl    %edi, %edi
 ;;   movabsq $-4100, %rax
 ;;   addq    %rax, 8(%rsi), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rsi), %r11
-;;   addq    %r11, $4096, %r11
-;;   xorq    %rsi, %rsi, %rsi
+;;   movq    0(%rsi), %rcx
+;;   lea     4096(%rcx,%rdi,1), %rsi
+;;   xorq    %rcx, %rcx, %rcx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rsi, %r11, %r11
-;;   movl    0(%r11), %eax
+;;   cmovnbeq %rcx, %rsi, %rsi
+;;   movl    0(%rsi), %eax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
index f4ffb0d0f..37401d352 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
@@ -45,17 +45,18 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r8d
-;;   movq    %r8, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r11d
+;;   movq    %r11, %rax
+;;   addq    %rax, const(0), %rax
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rdx), %rax
-;;   addq    %r8, 0(%rdx), %r8
-;;   addq    %r8, const(0), %r8
-;;   xorq    %rcx, %rcx, %rcx
-;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r8, %r8
-;;   movl    %esi, 0(%r8)
+;;   movq    8(%rdx), %rcx
+;;   addq    %r11, 0(%rdx), %r11
+;;   movl    $-65536, %edx
+;;   lea     0(%r11,%rdx,1), %rdx
+;;   xorq    %r8, %r8, %r8
+;;   cmpq    %rcx, %rax
+;;   cmovnbeq %r8, %rdx, %rdx
+;;   movl    %esi, 0(%rdx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -68,19 +69,20 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r8d
-;;   movq    %r8, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r11d
+;;   movq    %r11, %rax
+;;   addq    %rax, const(0), %rax
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rsi), %rax
-;;   addq    %r8, 0(%rsi), %r8
-;;   addq    %r8, const(0), %r8
-;;   xorq    %rcx, %rcx, %rcx
-;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r8, %r8
-;;   movl    0(%r8), %eax
+;;   movq    8(%rsi), %rcx
+;;   addq    %r11, 0(%rsi), %r11
+;;   movl    $-65536, %edx
+;;   lea     0(%r11,%rdx,1), %rdx
+;;   xorq    %r8, %r8, %r8
+;;   cmpq    %rcx, %rax
+;;   cmovnbeq %r8, %rdx, %rdx
+;;   movl    0(%rdx), %eax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
index a5d43ce9c..99113750d 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
@@ -48,13 +48,12 @@
 ;;   movl    %edi, %edi
 ;;   movabsq $-4097, %rax
 ;;   addq    %rax, 8(%rdx), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rdx), %r11
-;;   addq    %r11, $4096, %r11
-;;   xorq    %rcx, %rcx, %rcx
+;;   movq    0(%rdx), %rcx
+;;   lea     4096(%rcx,%rdi,1), %rcx
+;;   xorq    %rdx, %rdx, %rdx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r11, %r11
-;;   movb    %sil, 0(%r11)
+;;   cmovnbeq %rdx, %rcx, %rcx
+;;   movb    %sil, 0(%rcx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -70,15 +69,14 @@
 ;;   movl    %edi, %edi
 ;;   movabsq $-4097, %rax
 ;;   addq    %rax, 8(%rsi), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rsi), %r11
-;;   addq    %r11, $4096, %r11
-;;   xorq    %rsi, %rsi, %rsi
+;;   movq    0(%rsi), %rcx
+;;   lea     4096(%rcx,%rdi,1), %rsi
+;;   xorq    %rcx, %rcx, %rcx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rsi, %r11, %r11
-;;   movzbq  0(%r11), %rax
+;;   cmovnbeq %rcx, %rsi, %rsi
+;;   movzbq  0(%rsi), %rax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
index a67a3975a..05ca250ad 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
@@ -45,17 +45,18 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r8d
-;;   movq    %r8, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r11d
+;;   movq    %r11, %rax
+;;   addq    %rax, const(0), %rax
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rdx), %rax
-;;   addq    %r8, 0(%rdx), %r8
-;;   addq    %r8, const(0), %r8
-;;   xorq    %rcx, %rcx, %rcx
-;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r8, %r8
-;;   movb    %sil, 0(%r8)
+;;   movq    8(%rdx), %rcx
+;;   addq    %r11, 0(%rdx), %r11
+;;   movl    $-65536, %edx
+;;   lea     0(%r11,%rdx,1), %rdx
+;;   xorq    %r8, %r8, %r8
+;;   cmpq    %rcx, %rax
+;;   cmovnbeq %r8, %rdx, %rdx
+;;   movb    %sil, 0(%rdx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -68,19 +69,20 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movl    %edi, %r8d
-;;   movq    %r8, %rdi
-;;   addq    %rdi, const(1), %rdi
+;;   movl    %edi, %r11d
+;;   movq    %r11, %rax
+;;   addq    %rax, const(0), %rax
 ;;   jnb ; ud2 heap_oob ;
-;;   movq    8(%rsi), %rax
-;;   addq    %r8, 0(%rsi), %r8
-;;   addq    %r8, const(0), %r8
-;;   xorq    %rcx, %rcx, %rcx
-;;   cmpq    %rax, %rdi
-;;   cmovnbeq %rcx, %r8, %r8
-;;   movzbq  0(%r8), %rax
+;;   movq    8(%rsi), %rcx
+;;   addq    %r11, 0(%rsi), %r11
+;;   movl    $-65536, %edx
+;;   lea     0(%r11,%rdx,1), %rdx
+;;   xorq    %r8, %r8, %r8
+;;   cmpq    %rcx, %rax
+;;   cmovnbeq %r8, %rdx, %rdx
+;;   movzbq  0(%rdx), %rax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
index 583769bad..277b469a8 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -46,15 +46,15 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movq    %rdi, %r10
-;;   addq    %r10, const(1), %r10
+;;   addq    %r10, const(0), %r10
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rdx), %r11
 ;;   cmpq    %r11, %r10
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rdx), %rax
-;;   addq    %rax, const(0), %rax
-;;   movl    %esi, 0(%rax,%rdi,1)
+;;   addq    %rdi, 0(%rdx), %rdi
+;;   movl    $-65536, %eax
+;;   movl    %esi, 0(%rdi,%rax,1)
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
@@ -70,15 +70,15 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movq    %rdi, %r10
-;;   addq    %r10, const(1), %r10
+;;   addq    %r10, const(0), %r10
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rsi), %r11
 ;;   cmpq    %r11, %r10
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rsi), %r11
-;;   addq    %r11, const(0), %r11
-;;   movl    0(%r11,%rdi,1), %eax
+;;   addq    %rdi, 0(%rsi), %rdi
+;;   movl    $-65536, %esi
+;;   movl    0(%rdi,%rsi,1), %eax
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
index fb540d9fb..a790538c9 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -46,15 +46,15 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movq    %rdi, %r10
-;;   addq    %r10, const(1), %r10
+;;   addq    %r10, const(0), %r10
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rdx), %r11
 ;;   cmpq    %r11, %r10
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rdx), %rax
-;;   addq    %rax, const(0), %rax
-;;   movb    %sil, 0(%rax,%rdi,1)
+;;   addq    %rdi, 0(%rdx), %rdi
+;;   movl    $-65536, %eax
+;;   movb    %sil, 0(%rdi,%rax,1)
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
@@ -70,15 +70,15 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movq    %rdi, %r10
-;;   addq    %r10, const(1), %r10
+;;   addq    %r10, const(0), %r10
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rsi), %r11
 ;;   cmpq    %r11, %r10
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rsi), %r11
-;;   addq    %r11, const(0), %r11
-;;   movzbq  0(%r11,%rdi,1), %rax
+;;   addq    %rdi, 0(%rsi), %rdi
+;;   movl    $-65536, %esi
+;;   movzbq  0(%rdi,%rsi,1), %rax
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
index 6a2274169..ca9a9ac97 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
@@ -47,13 +47,12 @@
 ;; block0:
 ;;   movabsq $-4100, %rax
 ;;   addq    %rax, 8(%rdx), %rax
-;;   movq    %rdi, %r10
-;;   addq    %r10, 0(%rdx), %r10
-;;   addq    %r10, $4096, %r10
-;;   xorq    %r11, %r11, %r11
+;;   movq    0(%rdx), %rcx
+;;   lea     4096(%rcx,%rdi,1), %r11
+;;   xorq    %rcx, %rcx, %rcx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %r11, %r10, %r10
-;;   movl    %esi, 0(%r10)
+;;   cmovnbeq %rcx, %r11, %r11
+;;   movl    %esi, 0(%r11)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -66,18 +65,16 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rsi, %rax
-;;   movabsq $-4100, %rsi
-;;   addq    %rsi, 8(%rax), %rsi
-;;   movq    %rdi, %r10
-;;   addq    %r10, 0(%rax), %r10
-;;   addq    %r10, $4096, %r10
-;;   xorq    %r11, %r11, %r11
-;;   cmpq    %rsi, %rdi
-;;   cmovnbeq %r11, %r10, %r10
-;;   movl    0(%r10), %eax
+;;   movabsq $-4100, %rcx
+;;   addq    %rcx, 8(%rsi), %rcx
+;;   movq    0(%rsi), %rsi
+;;   lea     4096(%rsi,%rdi,1), %r11
+;;   xorq    %rax, %rax, %rax
+;;   cmpq    %rcx, %rdi
+;;   cmovnbeq %rax, %r11, %r11
+;;   movl    0(%r11), %eax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
index 0a1c3e7e4..369f5146a 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
@@ -45,17 +45,18 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %rcx
-;;   addq    %rcx, const(1), %rcx
+;;   movq    %rdi, %r8
+;;   addq    %r8, const(0), %r8
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rdx), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rdx), %r11
-;;   addq    %r11, const(0), %r11
+;;   movq    %rdi, %rcx
+;;   addq    %rcx, 0(%rdx), %rcx
+;;   movl    $-65536, %edi
+;;   lea     0(%rcx,%rdi,1), %rcx
 ;;   xorq    %rdi, %rdi, %rdi
-;;   cmpq    %rax, %rcx
-;;   cmovnbeq %rdi, %r11, %r11
-;;   movl    %esi, 0(%r11)
+;;   cmpq    %rax, %r8
+;;   cmovnbeq %rdi, %rcx, %rcx
+;;   movl    %esi, 0(%rcx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -68,19 +69,20 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %rcx
-;;   addq    %rcx, const(1), %rcx
+;;   movq    %rdi, %rdx
+;;   addq    %rdx, const(0), %rdx
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rsi), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rsi), %r11
-;;   addq    %r11, const(0), %r11
-;;   xorq    %rsi, %rsi, %rsi
-;;   cmpq    %rax, %rcx
-;;   cmovnbeq %rsi, %r11, %r11
-;;   movl    0(%r11), %eax
+;;   movq    %rdi, %rcx
+;;   addq    %rcx, 0(%rsi), %rcx
+;;   movl    $-65536, %edi
+;;   lea     0(%rcx,%rdi,1), %rcx
+;;   xorq    %rdi, %rdi, %rdi
+;;   cmpq    %rax, %rdx
+;;   cmovnbeq %rdi, %rcx, %rcx
+;;   movl    0(%rcx), %eax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
index 7e1de03d1..28522fed9 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
@@ -47,13 +47,12 @@
 ;; block0:
 ;;   movabsq $-4097, %rax
 ;;   addq    %rax, 8(%rdx), %rax
-;;   movq    %rdi, %r10
-;;   addq    %r10, 0(%rdx), %r10
-;;   addq    %r10, $4096, %r10
-;;   xorq    %r11, %r11, %r11
+;;   movq    0(%rdx), %rcx
+;;   lea     4096(%rcx,%rdi,1), %r11
+;;   xorq    %rcx, %rcx, %rcx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %r11, %r10, %r10
-;;   movb    %sil, 0(%r10)
+;;   cmovnbeq %rcx, %r11, %r11
+;;   movb    %sil, 0(%r11)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -66,18 +65,16 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rsi, %rax
-;;   movabsq $-4097, %rsi
-;;   addq    %rsi, 8(%rax), %rsi
-;;   movq    %rdi, %r10
-;;   addq    %r10, 0(%rax), %r10
-;;   addq    %r10, $4096, %r10
-;;   xorq    %r11, %r11, %r11
-;;   cmpq    %rsi, %rdi
-;;   cmovnbeq %r11, %r10, %r10
-;;   movzbq  0(%r10), %rax
+;;   movabsq $-4097, %rcx
+;;   addq    %rcx, 8(%rsi), %rcx
+;;   movq    0(%rsi), %rsi
+;;   lea     4096(%rsi,%rdi,1), %r11
+;;   xorq    %rax, %rax, %rax
+;;   cmpq    %rcx, %rdi
+;;   cmovnbeq %rax, %r11, %r11
+;;   movzbq  0(%r11), %rax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
index b29744517..e3aa79c86 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
@@ -45,17 +45,18 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %rcx
-;;   addq    %rcx, const(1), %rcx
+;;   movq    %rdi, %r8
+;;   addq    %r8, const(0), %r8
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rdx), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rdx), %r11
-;;   addq    %r11, const(0), %r11
+;;   movq    %rdi, %rcx
+;;   addq    %rcx, 0(%rdx), %rcx
+;;   movl    $-65536, %edi
+;;   lea     0(%rcx,%rdi,1), %rcx
 ;;   xorq    %rdi, %rdi, %rdi
-;;   cmpq    %rax, %rcx
-;;   cmovnbeq %rdi, %r11, %r11
-;;   movb    %sil, 0(%r11)
+;;   cmpq    %rax, %r8
+;;   cmovnbeq %rdi, %rcx, %rcx
+;;   movb    %sil, 0(%rcx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -68,19 +69,20 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %rcx
-;;   addq    %rcx, const(1), %rcx
+;;   movq    %rdi, %rdx
+;;   addq    %rdx, const(0), %rdx
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rsi), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rsi), %r11
-;;   addq    %r11, const(0), %r11
-;;   xorq    %rsi, %rsi, %rsi
-;;   cmpq    %rax, %rcx
-;;   cmovnbeq %rsi, %r11, %r11
-;;   movzbq  0(%r11), %rax
+;;   movq    %rdi, %rcx
+;;   addq    %rcx, 0(%rsi), %rcx
+;;   movl    $-65536, %edi
+;;   lea     0(%rcx,%rdi,1), %rcx
+;;   xorq    %rdi, %rdi, %rdi
+;;   cmpq    %rax, %rdx
+;;   cmovnbeq %rdi, %rcx, %rcx
+;;   movzbq  0(%rcx), %rax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
index 3f4ec47b0..95d01f56a 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -46,15 +46,15 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movq    %rdi, %r10
-;;   addq    %r10, const(1), %r10
+;;   addq    %r10, const(0), %r10
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rdx), %r11
 ;;   cmpq    %r11, %r10
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rdx), %rax
-;;   addq    %rax, const(0), %rax
-;;   movl    %esi, 0(%rax,%rdi,1)
+;;   addq    %rdi, 0(%rdx), %rdi
+;;   movl    $-65536, %eax
+;;   movl    %esi, 0(%rdi,%rax,1)
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
@@ -70,15 +70,15 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movq    %rdi, %r10
-;;   addq    %r10, const(1), %r10
+;;   addq    %r10, const(0), %r10
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rsi), %r11
 ;;   cmpq    %r11, %r10
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rsi), %r11
-;;   addq    %r11, const(0), %r11
-;;   movl    0(%r11,%rdi,1), %eax
+;;   addq    %rdi, 0(%rsi), %rdi
+;;   movl    $-65536, %esi
+;;   movl    0(%rdi,%rsi,1), %eax
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
index 9d2072729..ebc17c889 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -46,15 +46,15 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movq    %rdi, %r10
-;;   addq    %r10, const(1), %r10
+;;   addq    %r10, const(0), %r10
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rdx), %r11
 ;;   cmpq    %r11, %r10
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rdx), %rax
-;;   addq    %rax, const(0), %rax
-;;   movb    %sil, 0(%rax,%rdi,1)
+;;   addq    %rdi, 0(%rdx), %rdi
+;;   movl    $-65536, %eax
+;;   movb    %sil, 0(%rdi,%rax,1)
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
@@ -70,15 +70,15 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movq    %rdi, %r10
-;;   addq    %r10, const(1), %r10
+;;   addq    %r10, const(0), %r10
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rsi), %r11
 ;;   cmpq    %r11, %r10
 ;;   jnbe    label3; j label1
 ;; block1:
-;;   movq    0(%rsi), %r11
-;;   addq    %r11, const(0), %r11
-;;   movzbq  0(%r11,%rdi,1), %rax
+;;   addq    %rdi, 0(%rsi), %rdi
+;;   movl    $-65536, %esi
+;;   movzbq  0(%rdi,%rsi,1), %rax
 ;;   jmp     label2
 ;; block2:
 ;;   movq    %rbp, %rsp
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
index 7e7b96928..99f3c89c1 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
@@ -47,13 +47,12 @@
 ;; block0:
 ;;   movabsq $-4100, %rax
 ;;   addq    %rax, 8(%rdx), %rax
-;;   movq    %rdi, %r10
-;;   addq    %r10, 0(%rdx), %r10
-;;   addq    %r10, $4096, %r10
-;;   xorq    %r11, %r11, %r11
+;;   movq    0(%rdx), %rcx
+;;   lea     4096(%rcx,%rdi,1), %r11
+;;   xorq    %rcx, %rcx, %rcx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %r11, %r10, %r10
-;;   movl    %esi, 0(%r10)
+;;   cmovnbeq %rcx, %r11, %r11
+;;   movl    %esi, 0(%r11)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -66,18 +65,16 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rsi, %rax
-;;   movabsq $-4100, %rsi
-;;   addq    %rsi, 8(%rax), %rsi
-;;   movq    %rdi, %r10
-;;   addq    %r10, 0(%rax), %r10
-;;   addq    %r10, $4096, %r10
-;;   xorq    %r11, %r11, %r11
-;;   cmpq    %rsi, %rdi
-;;   cmovnbeq %r11, %r10, %r10
-;;   movl    0(%r10), %eax
+;;   movabsq $-4100, %rcx
+;;   addq    %rcx, 8(%rsi), %rcx
+;;   movq    0(%rsi), %rsi
+;;   lea     4096(%rsi,%rdi,1), %r11
+;;   xorq    %rax, %rax, %rax
+;;   cmpq    %rcx, %rdi
+;;   cmovnbeq %rax, %r11, %r11
+;;   movl    0(%r11), %eax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
index 636878960..95a7e4aff 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
@@ -45,17 +45,18 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %rcx
-;;   addq    %rcx, const(1), %rcx
+;;   movq    %rdi, %r8
+;;   addq    %r8, const(0), %r8
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rdx), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rdx), %r11
-;;   addq    %r11, const(0), %r11
+;;   movq    %rdi, %rcx
+;;   addq    %rcx, 0(%rdx), %rcx
+;;   movl    $-65536, %edi
+;;   lea     0(%rcx,%rdi,1), %rcx
 ;;   xorq    %rdi, %rdi, %rdi
-;;   cmpq    %rax, %rcx
-;;   cmovnbeq %rdi, %r11, %r11
-;;   movl    %esi, 0(%r11)
+;;   cmpq    %rax, %r8
+;;   cmovnbeq %rdi, %rcx, %rcx
+;;   movl    %esi, 0(%rcx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -68,19 +69,20 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %rcx
-;;   addq    %rcx, const(1), %rcx
+;;   movq    %rdi, %rdx
+;;   addq    %rdx, const(0), %rdx
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rsi), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rsi), %r11
-;;   addq    %r11, const(0), %r11
-;;   xorq    %rsi, %rsi, %rsi
-;;   cmpq    %rax, %rcx
-;;   cmovnbeq %rsi, %r11, %r11
-;;   movl    0(%r11), %eax
+;;   movq    %rdi, %rcx
+;;   addq    %rcx, 0(%rsi), %rcx
+;;   movl    $-65536, %edi
+;;   lea     0(%rcx,%rdi,1), %rcx
+;;   xorq    %rdi, %rdi, %rdi
+;;   cmpq    %rax, %rdx
+;;   cmovnbeq %rdi, %rcx, %rcx
+;;   movl    0(%rcx), %eax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
index ba1cf0055..a0cffc83b 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
@@ -47,13 +47,12 @@
 ;; block0:
 ;;   movabsq $-4097, %rax
 ;;   addq    %rax, 8(%rdx), %rax
-;;   movq    %rdi, %r10
-;;   addq    %r10, 0(%rdx), %r10
-;;   addq    %r10, $4096, %r10
-;;   xorq    %r11, %r11, %r11
+;;   movq    0(%rdx), %rcx
+;;   lea     4096(%rcx,%rdi,1), %r11
+;;   xorq    %rcx, %rcx, %rcx
 ;;   cmpq    %rax, %rdi
-;;   cmovnbeq %r11, %r10, %r10
-;;   movb    %sil, 0(%r10)
+;;   cmovnbeq %rcx, %r11, %r11
+;;   movb    %sil, 0(%r11)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -66,18 +65,16 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rsi, %rax
-;;   movabsq $-4097, %rsi
-;;   addq    %rsi, 8(%rax), %rsi
-;;   movq    %rdi, %r10
-;;   addq    %r10, 0(%rax), %r10
-;;   addq    %r10, $4096, %r10
-;;   xorq    %r11, %r11, %r11
-;;   cmpq    %rsi, %rdi
-;;   cmovnbeq %r11, %r10, %r10
-;;   movzbq  0(%r10), %rax
+;;   movabsq $-4097, %rcx
+;;   addq    %rcx, 8(%rsi), %rcx
+;;   movq    0(%rsi), %rsi
+;;   lea     4096(%rsi,%rdi,1), %r11
+;;   xorq    %rax, %rax, %rax
+;;   cmpq    %rcx, %rdi
+;;   cmovnbeq %rax, %r11, %r11
+;;   movzbq  0(%r11), %rax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
index 003dd6aa8..20977fe01 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
@@ -45,17 +45,18 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %rcx
-;;   addq    %rcx, const(1), %rcx
+;;   movq    %rdi, %r8
+;;   addq    %r8, const(0), %r8
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rdx), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rdx), %r11
-;;   addq    %r11, const(0), %r11
+;;   movq    %rdi, %rcx
+;;   addq    %rcx, 0(%rdx), %rcx
+;;   movl    $-65536, %edi
+;;   lea     0(%rcx,%rdi,1), %rcx
 ;;   xorq    %rdi, %rdi, %rdi
-;;   cmpq    %rax, %rcx
-;;   cmovnbeq %rdi, %r11, %r11
-;;   movb    %sil, 0(%r11)
+;;   cmpq    %rax, %r8
+;;   cmovnbeq %rdi, %rcx, %rcx
+;;   movb    %sil, 0(%rcx)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -68,19 +69,20 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %rcx
-;;   addq    %rcx, const(1), %rcx
+;;   movq    %rdi, %rdx
+;;   addq    %rdx, const(0), %rdx
 ;;   jnb ; ud2 heap_oob ;
 ;;   movq    8(%rsi), %rax
-;;   movq    %rdi, %r11
-;;   addq    %r11, 0(%rsi), %r11
-;;   addq    %r11, const(0), %r11
-;;   xorq    %rsi, %rsi, %rsi
-;;   cmpq    %rax, %rcx
-;;   cmovnbeq %rsi, %r11, %r11
-;;   movzbq  0(%r11), %rax
+;;   movq    %rdi, %rcx
+;;   addq    %rcx, 0(%rsi), %rcx
+;;   movl    $-65536, %edi
+;;   lea     0(%rcx,%rdi,1), %rcx
+;;   xorq    %rdi, %rdi, %rdi
+;;   cmpq    %rax, %rdx
+;;   cmovnbeq %rdi, %rcx, %rcx
+;;   movzbq  0(%rcx), %rax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
index 2f434668a..3a6c1b9dc 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
@@ -44,13 +44,12 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movl    %edi, %r11d
-;;   movq    %r11, %r9
-;;   addq    %r9, 0(%rdx), %r9
-;;   addq    %r9, $4096, %r9
-;;   xorq    %r10, %r10, %r10
+;;   movq    0(%rdx), %rdi
+;;   lea     4096(%rdi,%r11,1), %r10
+;;   xorq    %rdi, %rdi, %rdi
 ;;   cmpq    $268431356, %r11
-;;   cmovnbeq %r10, %r9, %r9
-;;   movl    %esi, 0(%r9)
+;;   cmovnbeq %rdi, %r10, %r10
+;;   movl    %esi, 0(%r10)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -64,15 +63,14 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movl    %edi, %r11d
-;;   movq    %r11, %r9
-;;   addq    %r9, 0(%rsi), %r9
-;;   addq    %r9, $4096, %r9
-;;   xorq    %r10, %r10, %r10
+;;   movq    0(%rsi), %rsi
+;;   lea     4096(%rsi,%r11,1), %r10
+;;   xorq    %rsi, %rsi, %rsi
 ;;   cmpq    $268431356, %r11
-;;   cmovnbeq %r10, %r9, %r9
-;;   movl    0(%r9), %eax
+;;   cmovnbeq %rsi, %r10, %r10
+;;   movl    0(%r10), %eax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
index 7b8d88b48..70caad3ef 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
@@ -44,13 +44,12 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movl    %edi, %r11d
-;;   movq    %r11, %r9
-;;   addq    %r9, 0(%rdx), %r9
-;;   addq    %r9, $4096, %r9
-;;   xorq    %r10, %r10, %r10
+;;   movq    0(%rdx), %rdi
+;;   lea     4096(%rdi,%r11,1), %r10
+;;   xorq    %rdi, %rdi, %rdi
 ;;   cmpq    $268431359, %r11
-;;   cmovnbeq %r10, %r9, %r9
-;;   movb    %sil, 0(%r9)
+;;   cmovnbeq %rdi, %r10, %r10
+;;   movb    %sil, 0(%r10)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -64,15 +63,14 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
 ;;   movl    %edi, %r11d
-;;   movq    %r11, %r9
-;;   addq    %r9, 0(%rsi), %r9
-;;   addq    %r9, $4096, %r9
-;;   xorq    %r10, %r10, %r10
+;;   movq    0(%rsi), %rsi
+;;   lea     4096(%rsi,%r11,1), %r10
+;;   xorq    %rsi, %rsi, %rsi
 ;;   cmpq    $268431359, %r11
-;;   cmovnbeq %r10, %r9, %r9
-;;   movzbq  0(%r9), %rax
+;;   cmovnbeq %rsi, %r10, %r10
+;;   movzbq  0(%r10), %rax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
index 4bf94389c..bdab2846d 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
@@ -65,4 +65,4 @@
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
index 3abcc96da..8f925ce9c 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
@@ -65,4 +65,4 @@
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
index 22ca45d73..068f359bc 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
@@ -65,4 +65,4 @@
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
index 9174a582c..818bd94e0 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
@@ -65,4 +65,4 @@
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
index cb65508f6..cc461ab9f 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat
@@ -43,13 +43,12 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %r8
-;;   addq    %r8, 0(%rdx), %r8
-;;   addq    %r8, $4096, %r8
-;;   xorq    %r9, %r9, %r9
+;;   movq    0(%rdx), %r10
+;;   lea     4096(%r10,%rdi,1), %r9
+;;   xorq    %r10, %r10, %r10
 ;;   cmpq    $268431356, %rdi
-;;   cmovnbeq %r9, %r8, %r8
-;;   movl    %esi, 0(%r8)
+;;   cmovnbeq %r10, %r9, %r9
+;;   movl    %esi, 0(%r9)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -62,15 +61,14 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %r8
-;;   addq    %r8, 0(%rsi), %r8
-;;   addq    %r8, $4096, %r8
-;;   xorq    %r9, %r9, %r9
+;;   movq    0(%rsi), %r10
+;;   lea     4096(%r10,%rdi,1), %r9
+;;   xorq    %r10, %r10, %r10
 ;;   cmpq    $268431356, %rdi
-;;   cmovnbeq %r9, %r8, %r8
-;;   movl    0(%r8), %eax
+;;   cmovnbeq %r10, %r9, %r9
+;;   movl    0(%r9), %eax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
index d706afe92..ed9ca6fad 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat
@@ -43,13 +43,12 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %r8
-;;   addq    %r8, 0(%rdx), %r8
-;;   addq    %r8, $4096, %r8
-;;   xorq    %r9, %r9, %r9
+;;   movq    0(%rdx), %r10
+;;   lea     4096(%r10,%rdi,1), %r9
+;;   xorq    %r10, %r10, %r10
 ;;   cmpq    $268431359, %rdi
-;;   cmovnbeq %r9, %r8, %r8
-;;   movb    %sil, 0(%r8)
+;;   cmovnbeq %r10, %r9, %r9
+;;   movb    %sil, 0(%r9)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -62,15 +61,14 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %r8
-;;   addq    %r8, 0(%rsi), %r8
-;;   addq    %r8, $4096, %r8
-;;   xorq    %r9, %r9, %r9
+;;   movq    0(%rsi), %r10
+;;   lea     4096(%r10,%rdi,1), %r9
+;;   xorq    %r10, %r10, %r10
 ;;   cmpq    $268431359, %rdi
-;;   cmovnbeq %r9, %r8, %r8
-;;   movzbq  0(%r8), %rax
+;;   cmovnbeq %r10, %r9, %r9
+;;   movzbq  0(%r9), %rax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
index 9758a1e0c..5917c8e75 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat
@@ -43,13 +43,12 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %r8
-;;   addq    %r8, 0(%rdx), %r8
-;;   addq    %r8, $4096, %r8
-;;   xorq    %r9, %r9, %r9
+;;   movq    0(%rdx), %r10
+;;   lea     4096(%r10,%rdi,1), %r9
+;;   xorq    %r10, %r10, %r10
 ;;   cmpq    $268431356, %rdi
-;;   cmovnbeq %r9, %r8, %r8
-;;   movl    %esi, 0(%r8)
+;;   cmovnbeq %r10, %r9, %r9
+;;   movl    %esi, 0(%r9)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -62,15 +61,14 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %r8
-;;   addq    %r8, 0(%rsi), %r8
-;;   addq    %r8, $4096, %r8
-;;   xorq    %r9, %r9, %r9
+;;   movq    0(%rsi), %r10
+;;   lea     4096(%r10,%rdi,1), %r9
+;;   xorq    %r10, %r10, %r10
 ;;   cmpq    $268431356, %rdi
-;;   cmovnbeq %r9, %r8, %r8
-;;   movl    0(%r8), %eax
+;;   cmovnbeq %r10, %r9, %r9
+;;   movl    0(%r9), %eax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
index 29284edfc..16dd75e52 100644
--- a/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/x64/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat
@@ -43,13 +43,12 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %r8
-;;   addq    %r8, 0(%rdx), %r8
-;;   addq    %r8, $4096, %r8
-;;   xorq    %r9, %r9, %r9
+;;   movq    0(%rdx), %r10
+;;   lea     4096(%r10,%rdi,1), %r9
+;;   xorq    %r10, %r10, %r10
 ;;   cmpq    $268431359, %rdi
-;;   cmovnbeq %r9, %r8, %r8
-;;   movb    %sil, 0(%r8)
+;;   cmovnbeq %r10, %r9, %r9
+;;   movb    %sil, 0(%r9)
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
@@ -62,15 +61,14 @@
 ;;   movq    %rsp, %rbp
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 }
 ;; block0:
-;;   movq    %rdi, %r8
-;;   addq    %r8, 0(%rsi), %r8
-;;   addq    %r8, $4096, %r8
-;;   xorq    %r9, %r9, %r9
+;;   movq    0(%rsi), %r10
+;;   lea     4096(%r10,%rdi,1), %r9
+;;   xorq    %r10, %r10, %r10
 ;;   cmpq    $268431359, %rdi
-;;   cmovnbeq %r9, %r8, %r8
-;;   movzbq  0(%r8), %rax
+;;   cmovnbeq %r10, %r9, %r9
+;;   movzbq  0(%r9), %rax
 ;;   jmp     label1
 ;; block1:
 ;;   movq    %rbp, %rsp
 ;;   popq    %rbp
-;;   ret
\ No newline at end of file
+;;   ret
diff --git a/cranelift/filetests/filetests/runtests/simd-shuffle.clif b/cranelift/filetests/filetests/runtests/simd-shuffle.clif
index 2ef1671e2..cdf2adfc5 100644
--- a/cranelift/filetests/filetests/runtests/simd-shuffle.clif
+++ b/cranelift/filetests/filetests/runtests/simd-shuffle.clif
@@ -553,3 +553,13 @@ block0(v0: i64x2, v1: i64x2):
     return v5
 }
 ; run: %aarch64_rev64_words([0x0102030405060708 0x0807060504030201], [0 0]) == [0x0506070801020304 0x0403020108070605]
+
+function %pblendw_0b10011001(i16x8, i16x8) -> i16x8 {
+block0(v0: i16x8, v1: i16x8):
+    v2 = bitcast.i8x16 little v0
+    v3 = bitcast.i8x16 little v1
+    v4 = shuffle v2, v3, [16 17 2 3 4 5 22 23 24 25 10 11 12 13 30 31]
+    v5 = bitcast.i16x8 little v4
+    return v5
+}
+; run: %pblendw_0b10011001([1 2 3 4 5 6 7 8], [9 10 11 12 13 14 15 16]) == [9 2 3 12 13 6 7 16]