1;;! target = "x86_64" 2;;! test = "optimize" 3;;! flags = "-O memory-may-move=y -O memory-reservation=0" 4 5(module 6 (import "" "" (func $imp)) 7 8 ;; Minimum and maximum sizes are equal. Therefore, this memory should never 9 ;; move, regardless of any other memory-related settings. 10 (memory 1 1) 11 12 ;; And therefore, the heap base should be marked read-only and can-move and 13 ;; should get code-motioned up out of the loop below, even though we call some 14 ;; foreign function in the loop body. 15 (func $f (param $base i32) 16 (local $i i32) 17 18 (local.set $i (i32.const 0)) 19 20 (loop 21 ;; Call a foreign function. This would usually otherwise defeat 22 ;; code-motioning the heap base out of the loop. 23 (call $imp) 24 25 ;; Do a memory operation, which should use the heap base, but should be 26 ;; code-motioned above the loop, because its load should be marked both 27 ;; read-only and can-move. 28 (i32.store (i32.add (local.get $base) (local.get $i)) (i32.const 0)) 29 30 ;; Increment `i` and continue the loop. 31 (local.set $i (i32.add (local.get $i) (i32.const 1))) 32 (br 0) 33 ) 34 ) 35) 36;; function u0:0(i64 vmctx, i64, i32) tail { 37;; gv0 = vmctx 38;; gv1 = load.i64 notrap aligned readonly gv0+8 39;; gv2 = load.i64 notrap aligned gv1+24 40;; gv3 = vmctx 41;; gv4 = load.i64 notrap aligned gv3+64 42;; gv5 = load.i64 notrap aligned readonly can_move gv3+56 43;; sig0 = (i64 vmctx, i64) tail 44;; stack_limit = gv2 45;; 46;; block0(v0: i64, v1: i64, v2: i32): 47;; @0028 v3 = iconst.i32 0 48;; @0030 v7 = load.i64 notrap aligned readonly can_move v0+72 49;; @0030 v6 = load.i64 notrap aligned readonly can_move v0+88 50;; @0039 v13 = iconst.i64 0x0001_0000 51;; @0039 v17 = iconst.i64 0 52;; @0039 v15 = load.i64 notrap aligned readonly can_move v0+56 53;; @003e v19 = iconst.i32 1 54;; @002e jump block2(v3) ; v3 = 0 55;; 56;; block2(v9: i32): 57;; @0030 call_indirect.i64 sig0, v7(v6, v0) 58;; v22 = iconst.i32 0 59;; @0036 v10 = iadd.i32 v2, v9 60;; @0039 v12 = uextend.i64 v10 61;; v23 = iconst.i64 0x0001_0000 62;; v24 = icmp ugt v12, v23 ; v23 = 0x0001_0000 63;; @0039 v16 = iadd.i64 v15, v12 64;; v25 = iconst.i64 0 65;; v26 = select_spectre_guard v24, v25, v16 ; v25 = 0 66;; @0039 store little heap v22, v26 ; v22 = 0 67;; v27 = iconst.i32 1 68;; v28 = iadd v9, v27 ; v27 = 1 69;; @0043 jump block2(v28) 70;; } 71