wasmtime-cli 44.0.1

Command-line interface for Wasmtime
Documentation
;;! target = "x86_64"
;;! test = "optimize"
;;! flags = "-O memory-may-move=y -O memory-reservation=0"

(module
  (import "" "" (func $imp))

  ;; Minimum and maximum sizes are equal. Therefore, this memory should never
  ;; move, regardless of any other memory-related settings.
  (memory 1 1)

  ;; And therefore, the heap base should be marked read-only and can-move and
  ;; should get code-motioned up out of the loop below, even though we call some
  ;; foreign function in the loop body.
  (func $f (param $base i32)
    (local $i i32)

    (local.set $i (i32.const 0))

    (loop
      ;; Call a foreign function. This would usually otherwise defeat
      ;; code-motioning the heap base out of the loop.
      (call $imp)

      ;; Do a memory operation, which should use the heap base, but should be
      ;; code-motioned above the loop, because its load should be marked both
      ;; read-only and can-move.
      (i32.store (i32.add (local.get $base) (local.get $i)) (i32.const 0))

      ;; Increment `i` and continue the loop.
      (local.set $i (i32.add (local.get $i) (i32.const 1)))
      (br 0)
    )
  )
)
;; function u0:0(i64 vmctx, i64, i32) tail {
;;     gv0 = vmctx
;;     gv1 = load.i64 notrap aligned readonly gv0+8
;;     gv2 = load.i64 notrap aligned gv1+24
;;     gv3 = vmctx
;;     gv4 = load.i64 notrap aligned gv3+64
;;     gv5 = load.i64 notrap aligned readonly can_move gv3+56
;;     sig0 = (i64 vmctx, i64) tail
;;     stack_limit = gv2
;;
;;                                 block0(v0: i64, v1: i64, v2: i32):
;; @0028                               v3 = iconst.i32 0
;; @0030                               v7 = load.i64 notrap aligned readonly can_move v0+72
;; @0030                               v6 = load.i64 notrap aligned readonly can_move v0+88
;; @0039                               v13 = iconst.i64 0x0001_0000
;; @0039                               v17 = iconst.i64 0
;; @0039                               v15 = load.i64 notrap aligned readonly can_move v0+56
;; @003e                               v19 = iconst.i32 1
;; @002e                               jump block2(v3)  ; v3 = 0
;;
;;                                 block2(v9: i32):
;; @0030                               call_indirect.i64 sig0, v7(v6, v0)
;;                                     v22 = iconst.i32 0
;; @0036                               v10 = iadd.i32 v2, v9
;; @0039                               v12 = uextend.i64 v10
;;                                     v23 = iconst.i64 0x0001_0000
;;                                     v24 = icmp ugt v12, v23  ; v23 = 0x0001_0000
;; @0039                               v16 = iadd.i64 v15, v12
;;                                     v25 = iconst.i64 0
;;                                     v26 = select_spectre_guard v24, v25, v16  ; v25 = 0
;; @0039                               store little heap v22, v26  ; v22 = 0
;;                                     v27 = iconst.i32 1
;;                                     v28 = iadd v9, v27  ; v27 = 1
;; @0043                               jump block2(v28)
;; }