|
| 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:1(i64 vmctx, i64, i32) tail { |
| 37 | +;; gv0 = vmctx |
| 38 | +;; gv1 = load.i64 notrap aligned readonly gv0+8 |
| 39 | +;; gv2 = load.i64 notrap aligned gv1+16 |
| 40 | +;; gv3 = vmctx |
| 41 | +;; gv4 = load.i64 notrap aligned gv3+72 |
| 42 | +;; gv5 = load.i64 notrap aligned readonly can_move checked gv3+64 |
| 43 | +;; sig0 = (i64 vmctx, i64) tail |
| 44 | +;; fn0 = u0:0 sig0 |
| 45 | +;; stack_limit = gv2 |
| 46 | +;; |
| 47 | +;; block0(v0: i64, v1: i64, v2: i32): |
| 48 | +;; @0028 v3 = iconst.i32 0 |
| 49 | +;; @0030 v6 = load.i64 notrap aligned readonly can_move v0+80 |
| 50 | +;; @0030 v7 = load.i64 notrap aligned readonly can_move v0+96 |
| 51 | +;; @0039 v13 = iconst.i64 0x0001_0000 |
| 52 | +;; @0039 v17 = iconst.i64 0 |
| 53 | +;; @0039 v15 = load.i64 notrap aligned readonly can_move checked v0+64 |
| 54 | +;; @003e v19 = iconst.i32 1 |
| 55 | +;; @002e jump block2(v3) ; v3 = 0 |
| 56 | +;; |
| 57 | +;; block2(v9: i32): |
| 58 | +;; @0030 call_indirect.i64 sig0, v6(v7, v0) |
| 59 | +;; v22 = iconst.i32 0 |
| 60 | +;; @0036 v10 = iadd.i32 v2, v9 |
| 61 | +;; @0039 v12 = uextend.i64 v10 |
| 62 | +;; v23 = iconst.i64 0x0001_0000 |
| 63 | +;; v24 = icmp ugt v12, v23 ; v23 = 0x0001_0000 |
| 64 | +;; @0039 v16 = iadd.i64 v15, v12 |
| 65 | +;; v25 = iconst.i64 0 |
| 66 | +;; v26 = select_spectre_guard v24, v25, v16 ; v25 = 0 |
| 67 | +;; @0039 store little heap v22, v26 ; v22 = 0 |
| 68 | +;; v27 = iconst.i32 1 |
| 69 | +;; v28 = iadd v9, v27 ; v27 = 1 |
| 70 | +;; @0043 jump block2(v28) |
| 71 | +;; } |
0 commit comments