;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up.

;; RUN: foreach %s %t wasm-opt --duplicate-function-elimination --all-features -S -o - | filecheck %s

;; --duplicate-function-elimination should not remove functions used in ref.func.
(module
  ;; CHECK:      (type $0 (func (result i32)))

  ;; CHECK:      (type $1 (func (result funcref)))

  ;; CHECK:      (elem declare func $0)

  ;; CHECK:      (func $0 (type $0) (result i32)
  ;; CHECK-NEXT:  (i32.const 0)
  ;; CHECK-NEXT: )
  (func $0 (result i32)
    (i32.const 0)
  )
  (func $1 (result i32)
    (i32.const 0)
  )
  ;; CHECK:      (func $test (type $1) (result funcref)
  ;; CHECK-NEXT:  (ref.func $0)
  ;; CHECK-NEXT: )
  (func $test (result funcref)
    (ref.func $1)
  )
)
;; renaming after deduplication must only affect functions
(module
 ;; CHECK:      (type $0 (func))

 ;; CHECK:      (global $bar i32 (i32.const 0))

 ;; CHECK:      (memory $foo 16 16)
 (memory $foo 16 16)
 (global $bar i32 (i32.const 0))
 ;; CHECK:      (export "memory" (memory $foo))
 (export "memory" (memory $foo))
 ;; CHECK:      (export "global" (global $bar))
 (export "global" (global $bar))
 ;; CHECK:      (func $bar (type $0)
 ;; CHECK-NEXT: )
 (func $bar ;; happens to share a name with the global
 )
 (func $foo ;; happens to share a name with the memory
 )
)
;; renaming after deduplication must update ref.funcs in globals
(module
 ;; CHECK:      (type $func (func (result i32)))
 (type $func (func (result i32)))
 ;; CHECK:      (global $global$0 (ref $func) (ref.func $foo))
 (global $global$0 (ref $func) (ref.func $bar))
 ;; These two identical functions can be merged. The ref.func in the global must
 ;; be updated accordingly.
 ;; CHECK:      (export "export" (func $export))

 ;; CHECK:      (func $foo (type $func) (result i32)
 ;; CHECK-NEXT:  (unreachable)
 ;; CHECK-NEXT: )
 (func $foo (result i32)
  (unreachable)
 )
 (func $bar (result i32)
  (unreachable)
 )
 ;; CHECK:      (func $export (type $func) (result i32)
 ;; CHECK-NEXT:  (call_ref $func
 ;; CHECK-NEXT:   (global.get $global$0)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT: )
 (func $export (export "export") (result i32)
  (call_ref $func
   (global.get $global$0)
  )
 )
)
