Browse Source

Add more disassembly tests for call_indirect (#8202)

I found these tests useful in thinking about #8195, #8197, and #8200, so
I thought we should track our codegen for these specific cases over
time.
pull/8203/head
Jamey Sharp 8 months ago
committed by GitHub
parent
commit
c6d923ae3f
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 137
      tests/disas/icall-loop.wat
  2. 91
      tests/disas/readonly-funcrefs.wat

137
tests/disas/icall-loop.wat

@ -0,0 +1,137 @@
;;! target = "x86_64"
;;! test = "optimize"
;; When `call_indirect` is used in a loop with the same table index on every
;; iteration, we can hoist part of the work out of the loop. This test tracks
;; how much we're successfully pulling out.
(module
(type $fn (func (result i32)))
(table $fnptrs 2 2 funcref)
(func (param i32)
loop
local.get 0
call_indirect $fnptrs (type $fn)
br 0
end)
(func
loop
i32.const 1
call_indirect $fnptrs (type $fn)
br 0
end)
)
;; function u0:0(i64 vmctx, i64, i32) fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly gv0+8
;; gv2 = load.i64 notrap aligned gv1
;; gv3 = vmctx
;; gv4 = load.i64 notrap aligned gv3+72
;; sig0 = (i64 vmctx, i64) -> i32 fast
;; sig1 = (i64 vmctx, i32 uext, i32 uext) -> i64 system_v
;; stack_limit = gv2
;;
;; block0(v0: i64, v1: i64, v2: i32):
;; v16 -> v0
;; v20 -> v0
;; v29 -> v0
;; v3 -> v2
;; v28 -> v3
;; @002b v4 = iconst.i32 2
;; @002b v5 = icmp uge v2, v4 ; v4 = 2
;; @002b v10 = iconst.i64 0
;; @002b v6 = uextend.i64 v2
;; v30 = iconst.i64 3
;; @002b v8 = ishl v6, v30 ; v30 = 3
;; v31 = iconst.i64 -2
;; @002b v17 = load.i64 notrap aligned readonly v0+56
;; @002b v18 = load.i64 notrap aligned readonly v17+72
;; @002b v15 = iconst.i32 0
;; @002b v21 = load.i64 notrap aligned readonly v0+64
;; @002b v22 = load.i32 notrap aligned readonly v21
;; @0027 jump block2
;;
;; block2:
;; @002b v7 = load.i64 notrap aligned v0+72
;; @002b v9 = iadd v7, v8
;; v32 = iconst.i64 0
;; v33 = select_spectre_guard v5, v32, v9 ; v32 = 0
;; @002b v12 = load.i64 table_oob aligned table v33
;; v34 = iconst.i64 -2
;; v35 = band v12, v34 ; v34 = -2
;; @002b brif v12, block5(v35), block4
;;
;; block4 cold:
;; v36 = iconst.i32 0
;; @002b v19 = call_indirect.i64 sig1, v18(v0, v36, v2) ; v36 = 0
;; @002b jump block5(v19)
;;
;; block5(v14: i64):
;; @002b v23 = load.i32 icall_null aligned readonly v14+24
;; @002b v24 = icmp eq v23, v22
;; @002b brif v24, block7, block6
;;
;; block6 cold:
;; @002b trap bad_sig
;;
;; block7:
;; @002b v25 = load.i64 notrap aligned readonly v14+16
;; @002b v26 = load.i64 notrap aligned readonly v14+32
;; @002b v27 = call_indirect sig0, v25(v26, v0)
;; @002e jump block2
;; }
;;
;; function u0:1(i64 vmctx, i64) fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly gv0+8
;; gv2 = load.i64 notrap aligned gv1
;; gv3 = vmctx
;; gv4 = load.i64 notrap aligned gv3+72
;; sig0 = (i64 vmctx, i64) -> i32 fast
;; sig1 = (i64 vmctx, i32 uext, i32 uext) -> i64 system_v
;; stack_limit = gv2
;;
;; block0(v0: i64, v1: i64):
;; v15 -> v0
;; v19 -> v0
;; v27 -> v0
;; v38 = iconst.i64 8
;; v29 = iconst.i64 -2
;; @0038 v16 = load.i64 notrap aligned readonly v0+56
;; @0038 v17 = load.i64 notrap aligned readonly v16+72
;; @0038 v14 = iconst.i32 0
;; @0036 v2 = iconst.i32 1
;; @0038 v20 = load.i64 notrap aligned readonly v0+64
;; @0038 v21 = load.i32 notrap aligned readonly v20
;; @0034 jump block2
;;
;; block2:
;; @0038 v6 = load.i64 notrap aligned v0+72
;; v39 = iconst.i64 8
;; v40 = iadd v6, v39 ; v39 = 8
;; @0038 v11 = load.i64 table_oob aligned table v40
;; v41 = iconst.i64 -2
;; v42 = band v11, v41 ; v41 = -2
;; @0038 brif v11, block5(v42), block4
;;
;; block4 cold:
;; v43 = iconst.i32 0
;; v44 = iconst.i32 1
;; @0038 v18 = call_indirect.i64 sig1, v17(v0, v43, v44) ; v43 = 0, v44 = 1
;; @0038 jump block5(v18)
;;
;; block5(v13: i64):
;; @0038 v22 = load.i32 icall_null aligned readonly v13+24
;; @0038 v23 = icmp eq v22, v21
;; @0038 brif v23, block7, block6
;;
;; block6 cold:
;; @0038 trap bad_sig
;;
;; block7:
;; @0038 v24 = load.i64 notrap aligned readonly v13+16
;; @0038 v25 = load.i64 notrap aligned readonly v13+32
;; @0038 v26 = call_indirect sig0, v24(v25, v0)
;; @003b jump block2
;; }

91
tests/disas/readonly-funcrefs.wat

@ -0,0 +1,91 @@
;;! target = "x86_64"
;;! test = "optimize"
;; Current WebAssembly toolchains represent source-language function pointers
;; by constructing a single WebAssembly funcref table, initializing it with an
;; element section, and never writing to it again. This test tracks what code
;; we generate for that pattern.
;; Motivated by https://github.com/bytecodealliance/wasmtime/issues/8195
(module
(type $fn (func))
(table $fnptrs 2 2 funcref)
(func $callee)
(func $caller (param i32)
local.get 0
call_indirect $fnptrs (type $fn))
(elem $fnptrs (i32.const 1) func $callee)
)
;; function u0:0(i64 vmctx, i64) fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly gv0+8
;; gv2 = load.i64 notrap aligned gv1
;; sig0 = (i64 vmctx, i32 uext, i32 uext) -> i32 uext system_v
;; sig1 = (i64 vmctx, i32 uext) -> i32 uext system_v
;; stack_limit = gv2
;;
;; block0(v0: i64, v1: i64):
;; @002c jump block1
;;
;; block1:
;; @002c return
;; }
;;
;; function u0:1(i64 vmctx, i64, i32) fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly gv0+8
;; gv2 = load.i64 notrap aligned gv1
;; gv3 = vmctx
;; gv4 = load.i64 notrap aligned gv3+72
;; sig0 = (i64 vmctx, i64) fast
;; sig1 = (i64 vmctx, i32 uext, i32 uext) -> i64 system_v
;; sig2 = (i64 vmctx, i32 uext, i32 uext) -> i32 uext system_v
;; sig3 = (i64 vmctx, i32 uext) -> i32 uext system_v
;; stack_limit = gv2
;;
;; block0(v0: i64, v1: i64, v2: i32):
;; v15 -> v0
;; v19 -> v0
;; v26 -> v0
;; @0031 v6 = load.i64 notrap aligned v0+72
;; @0031 v3 = iconst.i32 2
;; @0031 v4 = icmp uge v2, v3 ; v3 = 2
;; @0031 v9 = iconst.i64 0
;; @0031 v5 = uextend.i64 v2
;; v27 = iconst.i64 3
;; @0031 v7 = ishl v5, v27 ; v27 = 3
;; @0031 v8 = iadd v6, v7
;; @0031 v10 = select_spectre_guard v4, v9, v8 ; v9 = 0
;; @0031 v11 = load.i64 table_oob aligned table v10
;; v28 = iconst.i64 -2
;; @0031 v12 = band v11, v28 ; v28 = -2
;; @0031 brif v11, block3(v12), block2
;;
;; block2 cold:
;; @0031 v16 = load.i64 notrap aligned readonly v0+56
;; @0031 v17 = load.i64 notrap aligned readonly v16+72
;; @0031 v14 = iconst.i32 0
;; @0031 v18 = call_indirect sig1, v17(v0, v14, v2) ; v14 = 0
;; @0031 jump block3(v18)
;;
;; block3(v13: i64):
;; @0031 v22 = load.i32 icall_null aligned readonly v13+24
;; @0031 v20 = load.i64 notrap aligned readonly v0+64
;; @0031 v21 = load.i32 notrap aligned readonly v20
;; @0031 v23 = icmp eq v22, v21
;; @0031 brif v23, block5, block4
;;
;; block4 cold:
;; @0031 trap bad_sig
;;
;; block5:
;; @0031 v24 = load.i64 notrap aligned readonly v13+16
;; @0031 v25 = load.i64 notrap aligned readonly v13+32
;; @0031 call_indirect sig0, v24(v25, v0)
;; @0034 jump block1
;;
;; block1:
;; @0034 return
;; }
Loading…
Cancel
Save