1;;! target = "x86_64" 2;;! test = "optimize" 3 4;; Current WebAssembly toolchains represent source-language function pointers 5;; by constructing a single WebAssembly funcref table, initializing it with an 6;; element section, and never writing to it again. This test tracks what code 7;; we generate for that pattern. 8 9;; Motivated by https://github.com/bytecodealliance/wasmtime/issues/8195 10 11(module 12 (type $fn (func)) 13 (table $fnptrs 2 2 funcref) 14 (func $callee) 15 (func $caller (param i32) 16 local.get 0 17 call_indirect $fnptrs (type $fn)) 18 (elem $fnptrs (i32.const 1) func $callee) 19) 20 21;; function u0:0(i64 vmctx, i64) tail { 22;; gv0 = vmctx 23;; gv1 = load.i64 notrap aligned readonly gv0+8 24;; gv2 = load.i64 notrap aligned gv1+24 25;; stack_limit = gv2 26;; 27;; block0(v0: i64, v1: i64): 28;; @002c jump block1 29;; 30;; block1: 31;; @002c return 32;; } 33;; 34;; function u0:1(i64 vmctx, i64, i32) tail { 35;; gv0 = vmctx 36;; gv1 = load.i64 notrap aligned readonly gv0+8 37;; gv2 = load.i64 notrap aligned gv1+24 38;; gv3 = vmctx 39;; gv4 = load.i64 notrap aligned readonly can_move gv3+48 40;; sig0 = (i64 vmctx, i64) tail 41;; sig1 = (i64 vmctx, i32, i64) -> i64 tail 42;; fn0 = colocated u805306368:9 sig1 43;; stack_limit = gv2 44;; 45;; block0(v0: i64, v1: i64, v2: i32): 46;; @0031 v3 = iconst.i32 2 47;; @0031 v4 = icmp uge v2, v3 ; v3 = 2 48;; @0031 v9 = iconst.i64 0 49;; @0031 v6 = load.i64 notrap aligned readonly can_move v0+48 50;; @0031 v5 = uextend.i64 v2 51;; v26 = iconst.i64 3 52;; @0031 v7 = ishl v5, v26 ; v26 = 3 53;; @0031 v8 = iadd v6, v7 54;; @0031 v10 = select_spectre_guard v4, v9, v8 ; v9 = 0 55;; @0031 v11 = load.i64 user5 aligned table v10 56;; v25 = iconst.i64 -2 57;; @0031 v12 = band v11, v25 ; v25 = -2 58;; @0031 brif v11, block3(v12), block2 59;; 60;; block2 cold: 61;; @0031 v14 = iconst.i32 0 62;; @0031 v17 = call fn0(v0, v14, v5) ; v14 = 0 63;; @0031 jump block3(v17) 64;; 65;; block3(v13: i64): 66;; @0031 v21 = load.i32 user6 aligned readonly v13+16 67;; @0031 v19 = load.i64 notrap aligned readonly can_move v0+40 68;; @0031 v20 = load.i32 notrap aligned readonly can_move v19 69;; @0031 v22 = icmp eq v21, v20 70;; @0031 trapz v22, user7 71;; @0031 v23 = load.i64 notrap aligned readonly v13+8 72;; @0031 v24 = load.i64 notrap aligned readonly v13+24 73;; @0031 call_indirect sig0, v23(v24, v0) 74;; @0034 jump block1 75;; 76;; block1: 77;; @0034 return 78;; } 79