;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; RUN: foreach %s %t wasm-opt --merge-similar-functions -all -S -o - \ ;; RUN: | filecheck %s ;; Calls to functions $2 and $3 are the only differences between the contents ;; of $0 and $1, so we want to merge them and pass ref.funcs of $2 and $3. ;; However, their nominal types differ, so in nominal typing we cannot do so. (module ;; CHECK: (type $type$0 (sub (func))) (type $type$0 (sub (func))) (type $type$1 (sub (func))) (type $type$2 (sub (func))) (type $type$3 (sub (func (param f32) (result f32)))) (type $type$4 (sub (func (param f64) (result f64)))) ;; CHECK: (type $1 (func (param (ref $type$0)))) ;; CHECK: (elem declare func $2 $3) ;; CHECK: (func $0 (type $type$0) ;; CHECK-NEXT: (call $byn$mgfn-shared$0 ;; CHECK-NEXT: (ref.func $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $0 (type $type$0) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (call $2) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) ) ;; CHECK: (func $1 (type $type$0) ;; CHECK-NEXT: (call $byn$mgfn-shared$0 ;; CHECK-NEXT: (ref.func $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $1 (type $type$0) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (call $3) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) ) ;; CHECK: (func $2 (type $type$0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 17) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $2 (type $type$1) (drop (i32.const 17) ) ) ;; CHECK: (func $3 (type $type$0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 999) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $3 (type $type$2) (drop (i32.const 999) ) ) ) ;; CHECK: (func $byn$mgfn-shared$0 (type $1) (param $0 (ref $type$0)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (call_ref $type$0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (module ;; As above, but now the nominal types do match, so we can optimize in all ;; modes. ;; CHECK: (type $type$0 (sub (func))) (type $type$0 (sub (func))) (type $type$1 (sub (func))) (type $type$3 (sub (func (param f32) (result f32)))) (type $type$4 (sub (func (param f64) (result f64)))) ;; CHECK: (type $1 (func (param (ref $type$0)))) ;; CHECK: (global $global$0 (mut i32) (i32.const 10)) (global $global$0 (mut i32) (i32.const 10)) ;; CHECK: (memory $0 16 17 shared) (memory $0 16 17 shared) ;; CHECK: (elem declare func $2 $3) ;; CHECK: (func $0 (type $type$0) ;; CHECK-NEXT: (call $byn$mgfn-shared$0 ;; CHECK-NEXT: (ref.func $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $0 (type $type$0) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (call $2) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) ) ;; CHECK: (func $1 (type $type$0) ;; CHECK-NEXT: (call $byn$mgfn-shared$0 ;; CHECK-NEXT: (ref.func $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $1 (type $type$0) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (call $3) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) ) ;; CHECK: (func $2 (type $type$0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 17) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $2 (type $type$1) (drop (i32.const 17) ) ) ;; CHECK: (func $3 (type $type$0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 999) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $3 (type $type$1) (drop (i32.const 999) ) ) ) ;; CHECK: (func $byn$mgfn-shared$0 (type $1) (param $0 (ref $type$0)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (call_ref $type$0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: )