diff options
Diffstat (limited to 'test/lit/passes')
-rw-r--r-- | test/lit/passes/abstract-type-refining.wast | 206 | ||||
-rw-r--r-- | test/lit/passes/cfp.wast | 71 |
2 files changed, 151 insertions, 126 deletions
diff --git a/test/lit/passes/abstract-type-refining.wast b/test/lit/passes/abstract-type-refining.wast index f373acd87..5fffa7972 100644 --- a/test/lit/passes/abstract-type-refining.wast +++ b/test/lit/passes/abstract-type-refining.wast @@ -1,7 +1,7 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt --abstract-type-refining --traps-never-happen -all --closed-world --nominal -S -o - | filecheck %s --check-prefix=YESTNH -;; RUN: foreach %s %t wasm-opt --abstract-type-refining -all --closed-world --nominal -S -o - | filecheck %s --check-prefix=NO_TNH +;; RUN: foreach %s %t wasm-opt --abstract-type-refining --remove-unused-types --traps-never-happen -all --closed-world -S -o - | filecheck %s --check-prefix=YESTNH +;; RUN: foreach %s %t wasm-opt --abstract-type-refining --remove-unused-types -all --closed-world -S -o - | filecheck %s --check-prefix=NO_TNH ;; Run in both TNH and non-TNH mode. @@ -11,32 +11,34 @@ ;; actually refer to a subtype of them (that has a struct.new). As a result, in ;; TNH mode $A and $D will also not be emitted in the output anymore. (module - ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) + ;; NO_TNH: (rec + ;; NO_TNH-NEXT: (type $none_=>_none (func)) - ;; NO_TNH: (type $A (struct )) + ;; NO_TNH: (type $A (struct )) (type $A (struct)) - ;; YESTNH: (type $B (struct )) - ;; NO_TNH: (type $B (struct_subtype $A)) - (type $B (struct_subtype $A)) + ;; YESTNH: (rec + ;; YESTNH-NEXT: (type $none_=>_none (func)) - ;; YESTNH: (type $anyref_=>_none (func (param anyref))) + ;; YESTNH: (type $B (struct )) + ;; NO_TNH: (type $B (struct_subtype $A)) + (type $B (struct_subtype $A)) - ;; YESTNH: (type $C (struct_subtype $B)) - ;; NO_TNH: (type $C (struct_subtype $B)) + ;; YESTNH: (type $C (struct_subtype $B)) + ;; NO_TNH: (type $C (struct_subtype $B)) (type $C (struct_subtype $B)) - ;; NO_TNH: (type $D (struct_subtype $C)) + ;; NO_TNH: (type $D (struct_subtype $C)) (type $D (struct_subtype $C)) - ;; YESTNH: (type $E (struct_subtype $C)) - ;; NO_TNH: (type $E (struct_subtype $D)) + ;; YESTNH: (type $E (struct_subtype $C)) + ;; NO_TNH: (type $E (struct_subtype $D)) (type $E (struct_subtype $D)) - ;; YESTNH: (type $none_=>_none (func)) + ;; YESTNH: (type $anyref_=>_none (func (param anyref))) ;; YESTNH: (global $global anyref (struct.new_default $B)) - ;; NO_TNH: (type $none_=>_none (func)) + ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) ;; NO_TNH: (global $global anyref (struct.new_default $B)) (global $global anyref (struct.new $B)) @@ -275,21 +277,27 @@ ;; $A has two subtypes. As a result, we cannot optimize it. (module - ;; YESTNH: (type $A (struct )) - ;; NO_TNH: (type $A (struct )) - (type $A (struct)) + (rec + ;; YESTNH: (rec + ;; YESTNH-NEXT: (type $A (struct )) + ;; NO_TNH: (rec + ;; NO_TNH-NEXT: (type $A (struct )) + (type $A (struct)) - ;; YESTNH: (type $B (struct_subtype $A)) - ;; NO_TNH: (type $B (struct_subtype $A)) - (type $B (struct_subtype $A)) + ;; YESTNH: (type $B1 (struct_subtype $A)) + + ;; YESTNH: (type $anyref_=>_none (func (param anyref))) - ;; YESTNH: (type $anyref_=>_none (func (param anyref))) + ;; YESTNH: (type $B (struct_subtype $A)) + ;; NO_TNH: (type $B1 (struct_subtype $A)) - ;; YESTNH: (type $B1 (struct_subtype $A)) - ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) + ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) - ;; NO_TNH: (type $B1 (struct_subtype $A)) - (type $B1 (struct_subtype $A)) ;; this is a new type + ;; NO_TNH: (type $B (struct_subtype $A)) + (type $B (struct_subtype $A)) + + (type $B1 (struct_subtype $A)) ;; this is a new type + ) ;; YESTNH: (global $global anyref (struct.new_default $B)) ;; NO_TNH: (global $global anyref (struct.new_default $B)) @@ -367,24 +375,28 @@ ;; As above, but now $B is never created, so we can optimize casts of $A to ;; $B1. (module - ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) - - ;; NO_TNH: (type $A (struct )) - (type $A (struct)) + (rec + ;; NO_TNH: (rec + ;; NO_TNH-NEXT: (type $A (struct )) + (type $A (struct)) - (type $B (struct_subtype $A)) + (type $B (struct_subtype $A)) - ;; YESTNH: (type $B1 (struct )) - ;; NO_TNH: (type $B1 (struct_subtype $A)) - (type $B1 (struct_subtype $A)) ;; this is a new type + ;; YESTNH: (rec + ;; YESTNH-NEXT: (type $B1 (struct )) + ;; NO_TNH: (type $B1 (struct_subtype $A)) + (type $B1 (struct_subtype $A)) ;; this is a new type + ) - ;; YESTNH: (type $anyref_=>_none (func (param anyref))) + ;; YESTNH: (type $anyref_=>_none (func (param anyref))) ;; YESTNH: (func $new (type $anyref_=>_none) (param $x anyref) ;; YESTNH-NEXT: (drop ;; YESTNH-NEXT: (struct.new_default $B1) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) + ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) + ;; NO_TNH: (func $new (type $anyref_=>_none) (param $x anyref) ;; NO_TNH-NEXT: (drop ;; NO_TNH-NEXT: (struct.new_default $B1) @@ -451,25 +463,27 @@ ;; A chain, $A :> $B :> $C, where we can optimize $A all the way to $C. (module - ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) - - ;; NO_TNH: (type $A (struct )) + ;; NO_TNH: (rec + ;; NO_TNH-NEXT: (type $A (struct )) (type $A (struct)) - ;; NO_TNH: (type $B (struct_subtype $A)) + ;; NO_TNH: (type $B (struct_subtype $A)) (type $B (struct_subtype $A)) - ;; YESTNH: (type $C (struct )) - ;; NO_TNH: (type $C (struct_subtype $B)) + ;; YESTNH: (rec + ;; YESTNH-NEXT: (type $C (struct )) + ;; NO_TNH: (type $C (struct_subtype $B)) (type $C (struct_subtype $B)) - ;; YESTNH: (type $anyref_=>_none (func (param anyref))) + ;; YESTNH: (type $anyref_=>_none (func (param anyref))) ;; YESTNH: (func $new (type $anyref_=>_none) (param $x anyref) ;; YESTNH-NEXT: (drop ;; YESTNH-NEXT: (struct.new_default $C) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) + ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) + ;; NO_TNH: (func $new (type $anyref_=>_none) (param $x anyref) ;; NO_TNH-NEXT: (drop ;; NO_TNH-NEXT: (struct.new_default $C) @@ -537,17 +551,20 @@ ;; More testing for cases where no types or subtypes are created. No type is ;; created here. No type needs to be emitted in the output. (module - (type $A (struct)) + (rec + (type $A (struct)) - (type $B (struct_subtype $A)) + (type $B (struct_subtype $A)) - (type $C1 (struct_subtype $B)) + (type $C1 (struct_subtype $B)) - (type $C2 (struct_subtype $B)) + (type $C2 (struct_subtype $B)) + ) - ;; YESTNH: (type $anyref_=>_none (func (param anyref))) + ;; YESTNH: (rec + ;; YESTNH-NEXT: (type $none_=>_none (func)) - ;; YESTNH: (type $none_=>_none (func)) + ;; YESTNH: (type $anyref_=>_none (func (param anyref))) ;; YESTNH: (func $ref.cast (type $anyref_=>_none) (param $x anyref) ;; YESTNH-NEXT: (drop @@ -571,9 +588,10 @@ ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) - ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) + ;; NO_TNH: (rec + ;; NO_TNH-NEXT: (type $none_=>_none (func)) - ;; NO_TNH: (type $none_=>_none (func)) + ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) ;; NO_TNH: (func $ref.cast (type $anyref_=>_none) (param $x anyref) ;; NO_TNH-NEXT: (drop @@ -817,23 +835,27 @@ ;; As above, but now $C1 is created. (module - ;; NO_TNH: (type $A (struct )) - (type $A (struct)) + (rec + ;; NO_TNH: (rec + ;; NO_TNH-NEXT: (type $anyref_=>_none (func (param anyref))) - ;; NO_TNH: (type $B (struct_subtype $A)) - (type $B (struct_subtype $A)) + ;; NO_TNH: (type $A (struct )) + (type $A (struct)) - ;; YESTNH: (type $C1 (struct )) - ;; NO_TNH: (type $C1 (struct_subtype $B)) - (type $C1 (struct_subtype $B)) + ;; NO_TNH: (type $B (struct_subtype $A)) + (type $B (struct_subtype $A)) - (type $C2 (struct_subtype $B)) + ;; YESTNH: (rec + ;; YESTNH-NEXT: (type $anyref_=>_none (func (param anyref))) - ;; YESTNH: (type $anyref_=>_none (func (param anyref))) + ;; YESTNH: (type $C1 (struct )) + ;; NO_TNH: (type $C1 (struct_subtype $B)) + (type $C1 (struct_subtype $B)) - ;; YESTNH: (global $global anyref (struct.new_default $C1)) - ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) + (type $C2 (struct_subtype $B)) + ) + ;; YESTNH: (global $global anyref (struct.new_default $C1)) ;; NO_TNH: (global $global anyref (struct.new_default $C1)) (global $global anyref (struct.new $C1)) @@ -978,25 +1000,27 @@ ;; Function subtyping, which is a TODO - for now we do nothing. (module - ;; YESTNH: (type $A (func)) - ;; NO_TNH: (type $A (func)) + ;; YESTNH: (rec + ;; YESTNH-NEXT: (type $A (func)) + ;; NO_TNH: (rec + ;; NO_TNH-NEXT: (type $A (func)) (type $A (func)) - ;; YESTNH: (type $funcref_=>_none (func (param funcref))) - - ;; YESTNH: (type $B (func_subtype $A)) - ;; NO_TNH: (type $funcref_=>_none (func (param funcref))) - - ;; NO_TNH: (type $B (func_subtype $A)) + ;; YESTNH: (type $B (func_subtype $A)) + ;; NO_TNH: (type $B (func_subtype $A)) (type $B (func_subtype $A)) - ;; YESTNH: (type $C (func_subtype $B)) - ;; NO_TNH: (type $C (func_subtype $B)) + ;; YESTNH: (type $C (func_subtype $B)) + ;; NO_TNH: (type $C (func_subtype $B)) (type $C (func_subtype $B)) + ;; YESTNH: (type $funcref_=>_none (func (param funcref))) + ;; YESTNH: (func $A (type $A) ;; YESTNH-NEXT: (nop) ;; YESTNH-NEXT: ) + ;; NO_TNH: (type $funcref_=>_none (func (param funcref))) + ;; NO_TNH: (func $A (type $A) ;; NO_TNH-NEXT: (nop) ;; NO_TNH-NEXT: ) @@ -1074,16 +1098,20 @@ ;; NO_TNH: (type $A (func)) (type $A (func)) - ;; YESTNH: (type $B (func_subtype $A)) - ;; NO_TNH: (type $B (func_subtype $A)) + ;; YESTNH: (rec + ;; YESTNH-NEXT: (type $funcref_=>_none (func (param funcref))) + + ;; YESTNH: (type $B (func_subtype $A)) + ;; NO_TNH: (rec + ;; NO_TNH-NEXT: (type $funcref_=>_none (func (param funcref))) + + ;; NO_TNH: (type $B (func_subtype $A)) (type $B (func_subtype $A)) - ;; YESTNH: (type $C (func_subtype $B)) - ;; NO_TNH: (type $C (func_subtype $B)) + ;; YESTNH: (type $C (func_subtype $B)) + ;; NO_TNH: (type $C (func_subtype $B)) (type $C (func_subtype $B)) - ;; YESTNH: (type $funcref_=>_none (func (param funcref))) - ;; YESTNH: (elem declare func $A $C) ;; YESTNH: (export "A" (func $A)) @@ -1093,8 +1121,6 @@ ;; YESTNH-NEXT: (ref.func $A) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) - ;; NO_TNH: (type $funcref_=>_none (func (param funcref))) - ;; NO_TNH: (elem declare func $A $C) ;; NO_TNH: (export "A" (func $A)) @@ -1184,26 +1210,28 @@ ;; Array subtyping, which is a TODO - for now we do nothing. (module - ;; YESTNH: (type $A (array (mut i32))) - ;; NO_TNH: (type $A (array (mut i32))) + ;; YESTNH: (rec + ;; YESTNH-NEXT: (type $anyref_=>_none (func (param anyref))) + + ;; YESTNH: (type $A (array (mut i32))) + ;; NO_TNH: (rec + ;; NO_TNH-NEXT: (type $anyref_=>_none (func (param anyref))) + + ;; NO_TNH: (type $A (array (mut i32))) (type $A (array (mut i32))) - ;; YESTNH: (type $B (array_subtype (mut i32) $A)) - ;; NO_TNH: (type $B (array_subtype (mut i32) $A)) + ;; YESTNH: (type $B (array_subtype (mut i32) $A)) + ;; NO_TNH: (type $B (array_subtype (mut i32) $A)) (type $B (array_subtype (mut i32) $A)) - ;; YESTNH: (type $C (array_subtype (mut i32) $B)) - ;; NO_TNH: (type $C (array_subtype (mut i32) $B)) + ;; YESTNH: (type $C (array_subtype (mut i32) $B)) + ;; NO_TNH: (type $C (array_subtype (mut i32) $B)) (type $C (array_subtype (mut i32) $B)) - ;; YESTNH: (type $anyref_=>_none (func (param anyref))) - ;; YESTNH: (global $A (ref $A) (array.new $A ;; YESTNH-NEXT: (i32.const 10) ;; YESTNH-NEXT: (i32.const 20) ;; YESTNH-NEXT: )) - ;; NO_TNH: (type $anyref_=>_none (func (param anyref))) - ;; NO_TNH: (global $A (ref $A) (array.new $A ;; NO_TNH-NEXT: (i32.const 10) ;; NO_TNH-NEXT: (i32.const 20) diff --git a/test/lit/passes/cfp.wast b/test/lit/passes/cfp.wast index 4647599e0..48b1210b7 100644 --- a/test/lit/passes/cfp.wast +++ b/test/lit/passes/cfp.wast @@ -1,5 +1,7 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt --nominal --remove-unused-names --cfp -all -S -o - | filecheck %s + +;; RUN: foreach %s %t wasm-opt --remove-unused-names --cfp -all -S -o - | filecheck %s + ;; (remove-unused-names is added to test fallthrough values without a block ;; name getting in the way) @@ -454,10 +456,10 @@ ;; Test a function reference instead of a number. (module - ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) - ;; CHECK: (type $struct (struct (field funcref))) (type $struct (struct funcref)) + ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) + ;; CHECK: (elem declare func $test) ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct)) @@ -549,11 +551,11 @@ ;; CHECK: (type $struct (struct (field i32))) (type $struct (struct i32)) - ;; CHECK: (type $ref?|$substruct|_=>_none (func (param (ref null $substruct)))) - ;; CHECK: (type $substruct (struct_subtype (field i32) $struct)) (type $substruct (struct_subtype i32 $struct)) + ;; CHECK: (type $ref?|$substruct|_=>_none (func (param (ref null $substruct)))) + ;; CHECK: (func $create (type $none_=>_none) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.new $struct @@ -596,11 +598,11 @@ (type $struct (struct (mut i32))) ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) - ;; CHECK: (type $ref?|$substruct|_=>_none (func (param (ref null $substruct)))) - ;; CHECK: (type $substruct (struct_subtype (field (mut i32)) $struct)) (type $substruct (struct_subtype (mut i32) $struct)) + ;; CHECK: (type $ref?|$substruct|_=>_none (func (param (ref null $substruct)))) + ;; CHECK: (func $create (type $ref?|$struct|_=>_none) (param $struct (ref null $struct)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.new $struct @@ -651,12 +653,11 @@ ;; CHECK: (type $none_=>_none (func)) ;; CHECK: (type $struct (struct (field i32))) + (type $struct (struct i32)) ;; CHECK: (type $substruct (struct_subtype (field i32) (field f64) $struct)) (type $substruct (struct_subtype i32 f64 $struct)) - (type $struct (struct i32)) - ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) ;; CHECK: (func $create (type $none_=>_none) @@ -815,13 +816,13 @@ ;; shared between the types, but we only create the substruct with ;; one value, so we can optimize. (module + ;; CHECK: (type $struct (struct (field i32))) + (type $struct (struct i32)) ;; CHECK: (type $substruct (struct_subtype (field i32) (field f64) $struct)) (type $substruct (struct_subtype i32 f64 $struct)) - (type $struct (struct i32)) - ;; CHECK: (type $none_=>_none (func)) ;; CHECK: (type $ref?|$substruct|_=>_none (func (param (ref null $substruct)))) @@ -939,16 +940,14 @@ ;; supertype but all the way as needed. (module ;; CHECK: (type $struct1 (struct (field i32))) + (type $struct1 (struct i32)) ;; CHECK: (type $struct2 (struct_subtype (field i32) (field f64) $struct1)) + (type $struct2 (struct_subtype i32 f64 $struct1)) ;; CHECK: (type $struct3 (struct_subtype (field i32) (field f64) (field anyref) $struct2)) (type $struct3 (struct_subtype i32 f64 anyref $struct2)) - (type $struct2 (struct_subtype i32 f64 $struct1)) - - (type $struct1 (struct i32)) - ;; CHECK: (type $none_=>_none (func)) ;; CHECK: (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none (func (param (ref null $struct1) (ref null $struct2) (ref null $struct3)))) @@ -1076,16 +1075,14 @@ ;; not the middle one. (module ;; CHECK: (type $struct1 (struct (field i32) (field i32))) + (type $struct1 (struct i32 i32)) ;; CHECK: (type $struct2 (struct_subtype (field i32) (field i32) (field f64) (field f64) $struct1)) + (type $struct2 (struct_subtype i32 i32 f64 f64 $struct1)) ;; CHECK: (type $struct3 (struct_subtype (field i32) (field i32) (field f64) (field f64) (field anyref) (field anyref) $struct2)) (type $struct3 (struct_subtype i32 i32 f64 f64 anyref anyref $struct2)) - (type $struct1 (struct i32 i32)) - - (type $struct2 (struct_subtype i32 i32 f64 f64 $struct1)) - ;; CHECK: (type $anyref_=>_none (func (param anyref))) ;; CHECK: (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none (func (param (ref null $struct1) (ref null $struct2) (ref null $struct3)))) @@ -1403,13 +1400,13 @@ ;; As above, but add not just a new of the middle class with a different value ;; but also a set. That prevents all optimizations. (module + ;; CHECK: (type $struct1 (struct (field (mut i32)))) + (type $struct1 (struct (mut i32))) ;; CHECK: (type $struct2 (struct_subtype (field (mut i32)) (field f64) $struct1)) (type $struct2 (struct_subtype (mut i32) f64 $struct1)) - (type $struct1 (struct (mut i32))) - ;; CHECK: (type $struct3 (struct_subtype (field (mut i32)) (field f64) (field anyref) $struct2)) (type $struct3 (struct_subtype (mut i32) f64 anyref $struct2)) @@ -1631,16 +1628,14 @@ ;; apply to it, preventing optimization. (module ;; CHECK: (type $A (struct (field (mut i32)))) + (type $A (struct (mut i32))) ;; CHECK: (type $B (struct_subtype (field (mut i32)) $A)) + (type $B (struct_subtype (mut i32) $A)) ;; CHECK: (type $C (struct_subtype (field (mut i32)) $B)) (type $C (struct_subtype (mut i32) $B)) - (type $A (struct (mut i32))) - - (type $B (struct_subtype (mut i32) $A)) - ;; CHECK: (type $none_=>_none (func)) ;; CHECK: (type $ref|$A|_=>_none (func (param (ref $A)))) @@ -1748,11 +1743,11 @@ (module ;; CHECK: (type $struct (struct (field (mut f32)) (field (mut i32)))) (type $struct (struct (mut f32) (mut i32))) - ;; CHECK: (type $ref?|$struct|_ref?|$other|_=>_none (func (param (ref null $struct) (ref null $other)))) - ;; CHECK: (type $other (struct (field (mut f64)) (field (mut i32)))) (type $other (struct (mut f64) (mut i32))) + ;; CHECK: (type $ref?|$struct|_ref?|$other|_=>_none (func (param (ref null $struct) (ref null $other)))) + ;; CHECK: (func $test (type $ref?|$struct|_ref?|$other|_=>_none) (param $struct (ref null $struct)) (param $other (ref null $other)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.new_default $struct) @@ -2064,11 +2059,10 @@ ;; Test a global type other than i32. Arrays of structs are a realistic case ;; as they are used to implement itables. - ;; CHECK: (type $itable (array (ref $vtable))) - ;; CHECK: (type $vtable (struct (field funcref))) (type $vtable (struct funcref)) + ;; CHECK: (type $itable (array (ref $vtable))) (type $itable (array (ref $vtable))) ;; CHECK: (type $object (struct (field $itable (ref $itable)))) @@ -2138,14 +2132,17 @@ ;; Test we handle packed fields properly. (module - ;; CHECK: (type $none_=>_none (func)) - - ;; CHECK: (type $A_8 (struct (field i8))) - (type $A_8 (struct (field i8))) - ;; CHECK: (type $A_16 (struct (field i16))) - (type $A_16 (struct (field i16))) - ;; CHECK: (type $B_16 (struct (field i16))) - (type $B_16 (struct (field i16))) + (rec + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A_8 (struct (field i8))) + (type $A_8 (struct (field i8))) + ;; CHECK: (type $A_16 (struct (field i16))) + (type $A_16 (struct (field i16))) + ;; CHECK: (type $B_16 (struct (field i16))) + (type $B_16 (struct (field i16))) + ) ;; CHECK: (import "a" "b" (global $g i32)) (import "a" "b" (global $g i32)) |