;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.

;; Test optimization decisions while varying the minimum benefit percentage
;; parameter. Zero means any benefit, no matter how small, is worthwhile, while
;; higher values demand more benefit before doing any work.
;;
;; Test with --traps-never-happen (tnh) here so that we optimize more, making it
;; easier to show the effects. This is also more realistic for toolchains like
;; Java/Kotlin/Dart, which is good coverage.

;; RUN: foreach %s %t wasm-opt --monomorphize                                         -all -tnh -S -o - | filecheck %s --check-prefix DEFAULT
;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@0   -all -tnh -S -o - | filecheck %s --check-prefix ZERO___
;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@33  -all -tnh -S -o - | filecheck %s --check-prefix THIRD__
;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@66  -all -tnh -S -o - | filecheck %s --check-prefix TWOTRDS
;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@100 -all -tnh -S -o - | filecheck %s --check-prefix HUNDRED

(module
  (memory 10 20)

  ;; DEFAULT:      (type $0 (func (param i32 i32 i32 i32 i32)))

  ;; DEFAULT:      (type $1 (func (param i32)))

  ;; DEFAULT:      (memory $0 10 20)

  ;; DEFAULT:      (func $target (type $0) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32)
  ;; DEFAULT-NEXT:  (i32.store
  ;; DEFAULT-NEXT:   (i32.const 10)
  ;; DEFAULT-NEXT:   (i32.div_s
  ;; DEFAULT-NEXT:    (local.get $0)
  ;; DEFAULT-NEXT:    (i32.add
  ;; DEFAULT-NEXT:     (local.get $0)
  ;; DEFAULT-NEXT:     (i32.const 1)
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (i32.store
  ;; DEFAULT-NEXT:   (i32.const 20)
  ;; DEFAULT-NEXT:   (i32.div_s
  ;; DEFAULT-NEXT:    (local.get $1)
  ;; DEFAULT-NEXT:    (i32.add
  ;; DEFAULT-NEXT:     (local.get $1)
  ;; DEFAULT-NEXT:     (i32.const 1)
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (i32.store
  ;; DEFAULT-NEXT:   (i32.const 30)
  ;; DEFAULT-NEXT:   (i32.div_s
  ;; DEFAULT-NEXT:    (local.get $2)
  ;; DEFAULT-NEXT:    (i32.add
  ;; DEFAULT-NEXT:     (local.get $2)
  ;; DEFAULT-NEXT:     (i32.const 1)
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (i32.store
  ;; DEFAULT-NEXT:   (i32.const 40)
  ;; DEFAULT-NEXT:   (i32.div_s
  ;; DEFAULT-NEXT:    (local.get $3)
  ;; DEFAULT-NEXT:    (i32.add
  ;; DEFAULT-NEXT:     (local.get $3)
  ;; DEFAULT-NEXT:     (i32.const 1)
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (i32.store
  ;; DEFAULT-NEXT:   (i32.const 50)
  ;; DEFAULT-NEXT:   (i32.div_s
  ;; DEFAULT-NEXT:    (local.get $4)
  ;; DEFAULT-NEXT:    (i32.add
  ;; DEFAULT-NEXT:     (local.get $4)
  ;; DEFAULT-NEXT:     (i32.const 1)
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT: )
  ;; ZERO___:      (type $0 (func (param i32)))

  ;; ZERO___:      (type $1 (func (param i32 i32 i32 i32 i32)))

  ;; ZERO___:      (type $2 (func))

  ;; ZERO___:      (type $3 (func (param i32 i32)))

  ;; ZERO___:      (type $4 (func (param i32 i32 i32)))

  ;; ZERO___:      (type $5 (func (param i32 i32 i32 i32)))

  ;; ZERO___:      (memory $0 10 20)

  ;; ZERO___:      (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32)
  ;; ZERO___-NEXT:  (i32.store
  ;; ZERO___-NEXT:   (i32.const 10)
  ;; ZERO___-NEXT:   (i32.div_s
  ;; ZERO___-NEXT:    (local.get $0)
  ;; ZERO___-NEXT:    (i32.add
  ;; ZERO___-NEXT:     (local.get $0)
  ;; ZERO___-NEXT:     (i32.const 1)
  ;; ZERO___-NEXT:    )
  ;; ZERO___-NEXT:   )
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (i32.store
  ;; ZERO___-NEXT:   (i32.const 20)
  ;; ZERO___-NEXT:   (i32.div_s
  ;; ZERO___-NEXT:    (local.get $1)
  ;; ZERO___-NEXT:    (i32.add
  ;; ZERO___-NEXT:     (local.get $1)
  ;; ZERO___-NEXT:     (i32.const 1)
  ;; ZERO___-NEXT:    )
  ;; ZERO___-NEXT:   )
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (i32.store
  ;; ZERO___-NEXT:   (i32.const 30)
  ;; ZERO___-NEXT:   (i32.div_s
  ;; ZERO___-NEXT:    (local.get $2)
  ;; ZERO___-NEXT:    (i32.add
  ;; ZERO___-NEXT:     (local.get $2)
  ;; ZERO___-NEXT:     (i32.const 1)
  ;; ZERO___-NEXT:    )
  ;; ZERO___-NEXT:   )
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (i32.store
  ;; ZERO___-NEXT:   (i32.const 40)
  ;; ZERO___-NEXT:   (i32.div_s
  ;; ZERO___-NEXT:    (local.get $3)
  ;; ZERO___-NEXT:    (i32.add
  ;; ZERO___-NEXT:     (local.get $3)
  ;; ZERO___-NEXT:     (i32.const 1)
  ;; ZERO___-NEXT:    )
  ;; ZERO___-NEXT:   )
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (i32.store
  ;; ZERO___-NEXT:   (i32.const 50)
  ;; ZERO___-NEXT:   (i32.div_s
  ;; ZERO___-NEXT:    (local.get $4)
  ;; ZERO___-NEXT:    (i32.add
  ;; ZERO___-NEXT:     (local.get $4)
  ;; ZERO___-NEXT:     (i32.const 1)
  ;; ZERO___-NEXT:    )
  ;; ZERO___-NEXT:   )
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT: )
  ;; THIRD__:      (type $0 (func (param i32)))

  ;; THIRD__:      (type $1 (func (param i32 i32 i32 i32 i32)))

  ;; THIRD__:      (type $2 (func))

  ;; THIRD__:      (type $3 (func (param i32 i32)))

  ;; THIRD__:      (memory $0 10 20)

  ;; THIRD__:      (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32)
  ;; THIRD__-NEXT:  (i32.store
  ;; THIRD__-NEXT:   (i32.const 10)
  ;; THIRD__-NEXT:   (i32.div_s
  ;; THIRD__-NEXT:    (local.get $0)
  ;; THIRD__-NEXT:    (i32.add
  ;; THIRD__-NEXT:     (local.get $0)
  ;; THIRD__-NEXT:     (i32.const 1)
  ;; THIRD__-NEXT:    )
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (i32.store
  ;; THIRD__-NEXT:   (i32.const 20)
  ;; THIRD__-NEXT:   (i32.div_s
  ;; THIRD__-NEXT:    (local.get $1)
  ;; THIRD__-NEXT:    (i32.add
  ;; THIRD__-NEXT:     (local.get $1)
  ;; THIRD__-NEXT:     (i32.const 1)
  ;; THIRD__-NEXT:    )
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (i32.store
  ;; THIRD__-NEXT:   (i32.const 30)
  ;; THIRD__-NEXT:   (i32.div_s
  ;; THIRD__-NEXT:    (local.get $2)
  ;; THIRD__-NEXT:    (i32.add
  ;; THIRD__-NEXT:     (local.get $2)
  ;; THIRD__-NEXT:     (i32.const 1)
  ;; THIRD__-NEXT:    )
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (i32.store
  ;; THIRD__-NEXT:   (i32.const 40)
  ;; THIRD__-NEXT:   (i32.div_s
  ;; THIRD__-NEXT:    (local.get $3)
  ;; THIRD__-NEXT:    (i32.add
  ;; THIRD__-NEXT:     (local.get $3)
  ;; THIRD__-NEXT:     (i32.const 1)
  ;; THIRD__-NEXT:    )
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (i32.store
  ;; THIRD__-NEXT:   (i32.const 50)
  ;; THIRD__-NEXT:   (i32.div_s
  ;; THIRD__-NEXT:    (local.get $4)
  ;; THIRD__-NEXT:    (i32.add
  ;; THIRD__-NEXT:     (local.get $4)
  ;; THIRD__-NEXT:     (i32.const 1)
  ;; THIRD__-NEXT:    )
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT: )
  ;; TWOTRDS:      (type $0 (func (param i32 i32 i32 i32 i32)))

  ;; TWOTRDS:      (type $1 (func (param i32)))

  ;; TWOTRDS:      (type $2 (func))

  ;; TWOTRDS:      (memory $0 10 20)

  ;; TWOTRDS:      (func $target (type $0) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32)
  ;; TWOTRDS-NEXT:  (i32.store
  ;; TWOTRDS-NEXT:   (i32.const 10)
  ;; TWOTRDS-NEXT:   (i32.div_s
  ;; TWOTRDS-NEXT:    (local.get $0)
  ;; TWOTRDS-NEXT:    (i32.add
  ;; TWOTRDS-NEXT:     (local.get $0)
  ;; TWOTRDS-NEXT:     (i32.const 1)
  ;; TWOTRDS-NEXT:    )
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (i32.store
  ;; TWOTRDS-NEXT:   (i32.const 20)
  ;; TWOTRDS-NEXT:   (i32.div_s
  ;; TWOTRDS-NEXT:    (local.get $1)
  ;; TWOTRDS-NEXT:    (i32.add
  ;; TWOTRDS-NEXT:     (local.get $1)
  ;; TWOTRDS-NEXT:     (i32.const 1)
  ;; TWOTRDS-NEXT:    )
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (i32.store
  ;; TWOTRDS-NEXT:   (i32.const 30)
  ;; TWOTRDS-NEXT:   (i32.div_s
  ;; TWOTRDS-NEXT:    (local.get $2)
  ;; TWOTRDS-NEXT:    (i32.add
  ;; TWOTRDS-NEXT:     (local.get $2)
  ;; TWOTRDS-NEXT:     (i32.const 1)
  ;; TWOTRDS-NEXT:    )
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (i32.store
  ;; TWOTRDS-NEXT:   (i32.const 40)
  ;; TWOTRDS-NEXT:   (i32.div_s
  ;; TWOTRDS-NEXT:    (local.get $3)
  ;; TWOTRDS-NEXT:    (i32.add
  ;; TWOTRDS-NEXT:     (local.get $3)
  ;; TWOTRDS-NEXT:     (i32.const 1)
  ;; TWOTRDS-NEXT:    )
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (i32.store
  ;; TWOTRDS-NEXT:   (i32.const 50)
  ;; TWOTRDS-NEXT:   (i32.div_s
  ;; TWOTRDS-NEXT:    (local.get $4)
  ;; TWOTRDS-NEXT:    (i32.add
  ;; TWOTRDS-NEXT:     (local.get $4)
  ;; TWOTRDS-NEXT:     (i32.const 1)
  ;; TWOTRDS-NEXT:    )
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT: )
  ;; HUNDRED:      (type $0 (func (param i32 i32 i32 i32 i32)))

  ;; HUNDRED:      (type $1 (func (param i32)))

  ;; HUNDRED:      (memory $0 10 20)

  ;; HUNDRED:      (func $target (type $0) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32)
  ;; HUNDRED-NEXT:  (i32.store
  ;; HUNDRED-NEXT:   (i32.const 10)
  ;; HUNDRED-NEXT:   (i32.div_s
  ;; HUNDRED-NEXT:    (local.get $0)
  ;; HUNDRED-NEXT:    (i32.add
  ;; HUNDRED-NEXT:     (local.get $0)
  ;; HUNDRED-NEXT:     (i32.const 1)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (i32.store
  ;; HUNDRED-NEXT:   (i32.const 20)
  ;; HUNDRED-NEXT:   (i32.div_s
  ;; HUNDRED-NEXT:    (local.get $1)
  ;; HUNDRED-NEXT:    (i32.add
  ;; HUNDRED-NEXT:     (local.get $1)
  ;; HUNDRED-NEXT:     (i32.const 1)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (i32.store
  ;; HUNDRED-NEXT:   (i32.const 30)
  ;; HUNDRED-NEXT:   (i32.div_s
  ;; HUNDRED-NEXT:    (local.get $2)
  ;; HUNDRED-NEXT:    (i32.add
  ;; HUNDRED-NEXT:     (local.get $2)
  ;; HUNDRED-NEXT:     (i32.const 1)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (i32.store
  ;; HUNDRED-NEXT:   (i32.const 40)
  ;; HUNDRED-NEXT:   (i32.div_s
  ;; HUNDRED-NEXT:    (local.get $3)
  ;; HUNDRED-NEXT:    (i32.add
  ;; HUNDRED-NEXT:     (local.get $3)
  ;; HUNDRED-NEXT:     (i32.const 1)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (i32.store
  ;; HUNDRED-NEXT:   (i32.const 50)
  ;; HUNDRED-NEXT:   (i32.div_s
  ;; HUNDRED-NEXT:    (local.get $4)
  ;; HUNDRED-NEXT:    (i32.add
  ;; HUNDRED-NEXT:     (local.get $4)
  ;; HUNDRED-NEXT:     (i32.const 1)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT: )
  (func $target (param $a i32) (param $b i32) (param $c i32) (param $d i32) (param $e i32)
    ;; This function takes five parameters and uses each one to do some work. In
    ;; Each of the following identical stores, when we know one of the five
    ;; params, we can compute in full the value stored. (The store offsets
    ;; differ to guard against a future dead store elimination.)
    (i32.store
      (i32.const 10)
      (i32.div_s
        (local.get $a)
        (i32.add
          (local.get $a)
          (i32.const 1)
        )
      )
    )
    (i32.store
      (i32.const 20)
      (i32.div_s
        (local.get $b)
        (i32.add
          (local.get $b)
          (i32.const 1)
        )
      )
    )
    (i32.store
      (i32.const 30)
      (i32.div_s
        (local.get $c)
        (i32.add
          (local.get $c)
          (i32.const 1)
        )
      )
    )
    (i32.store
      (i32.const 40)
      (i32.div_s
        (local.get $d)
        (i32.add
          (local.get $d)
          (i32.const 1)
        )
      )
    )
    (i32.store
      (i32.const 50)
      (i32.div_s
        (local.get $e)
        (i32.add
          (local.get $e)
          (i32.const 1)
        )
      )
    )
  )

  ;; DEFAULT:      (func $calls (type $1) (param $x i32)
  ;; DEFAULT-NEXT:  (call $target
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $target
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $target
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $target
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $target
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (i32.const 42)
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $target
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT: )
  ;; ZERO___:      (func $calls (type $0) (param $x i32)
  ;; ZERO___-NEXT:  (call $target_2)
  ;; ZERO___-NEXT:  (call $target_3
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $target_4
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $target_5
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $target_6
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $target
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT: )
  ;; THIRD__:      (func $calls (type $0) (param $x i32)
  ;; THIRD__-NEXT:  (call $target_2)
  ;; THIRD__-NEXT:  (call $target_3
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $target_4
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $target
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (i32.const 42)
  ;; THIRD__-NEXT:   (i32.const 42)
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $target
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (i32.const 42)
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $target
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT: )
  ;; TWOTRDS:      (func $calls (type $1) (param $x i32)
  ;; TWOTRDS-NEXT:  (call $target_2)
  ;; TWOTRDS-NEXT:  (call $target
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (i32.const 42)
  ;; TWOTRDS-NEXT:   (i32.const 42)
  ;; TWOTRDS-NEXT:   (i32.const 42)
  ;; TWOTRDS-NEXT:   (i32.const 42)
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $target
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (i32.const 42)
  ;; TWOTRDS-NEXT:   (i32.const 42)
  ;; TWOTRDS-NEXT:   (i32.const 42)
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $target
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (i32.const 42)
  ;; TWOTRDS-NEXT:   (i32.const 42)
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $target
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (i32.const 42)
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $target
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT: )
  ;; HUNDRED:      (func $calls (type $1) (param $x i32)
  ;; HUNDRED-NEXT:  (call $target
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (call $target
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (call $target
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (call $target
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (call $target
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (i32.const 42)
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (call $target
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:   (local.get $x)
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT: )
  (func $calls (param $x i32)
    ;; Call the target with an increasing amount of non-constant params, 0-5.
    ;;
    ;; With 5 unknowns, the call context is trivial and we do nothing. All the
    ;; differences are therefore on 0-4:
    ;;
    ;;  * ZERO monomorphizes all of  0-4.
    ;;  * THIRD monomorphizes only   0-2.
    ;;  * TWOTRDS monomorphizes just   0.
    ;;  * HUNDRED monomorphizes none at all.

    (call $target
      (i32.const 42)
      (i32.const 42)
      (i32.const 42)
      (i32.const 42)
      (i32.const 42)
    )
    (call $target
      (local.get $x)
      (i32.const 42)
      (i32.const 42)
      (i32.const 42)
      (i32.const 42)
    )
    (call $target
      (local.get $x)
      (local.get $x)
      (i32.const 42)
      (i32.const 42)
      (i32.const 42)
    )
    (call $target
      (local.get $x)
      (local.get $x)
      (local.get $x)
      (i32.const 42)
      (i32.const 42)
    )
    (call $target
      (local.get $x)
      (local.get $x)
      (local.get $x)
      (local.get $x)
      (i32.const 42)
    )
    (call $target
      (local.get $x)
      (local.get $x)
      (local.get $x)
      (local.get $x)
      (local.get $x)
    )
  )
)

;; ZERO___:      (func $target_2 (type $2)
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 10)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 20)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 30)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 40)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 50)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT: )

;; ZERO___:      (func $target_3 (type $0) (param $0 i32)
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 10)
;; ZERO___-NEXT:   (i32.div_s
;; ZERO___-NEXT:    (local.get $0)
;; ZERO___-NEXT:    (i32.add
;; ZERO___-NEXT:     (local.get $0)
;; ZERO___-NEXT:     (i32.const 1)
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 20)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 30)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 40)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 50)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT: )

;; ZERO___:      (func $target_4 (type $3) (param $0 i32) (param $1 i32)
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 10)
;; ZERO___-NEXT:   (i32.div_s
;; ZERO___-NEXT:    (local.get $0)
;; ZERO___-NEXT:    (i32.add
;; ZERO___-NEXT:     (local.get $0)
;; ZERO___-NEXT:     (i32.const 1)
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 20)
;; ZERO___-NEXT:   (i32.div_s
;; ZERO___-NEXT:    (local.get $1)
;; ZERO___-NEXT:    (i32.add
;; ZERO___-NEXT:     (local.get $1)
;; ZERO___-NEXT:     (i32.const 1)
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 30)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 40)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 50)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT: )

;; ZERO___:      (func $target_5 (type $4) (param $0 i32) (param $1 i32) (param $2 i32)
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 10)
;; ZERO___-NEXT:   (i32.div_s
;; ZERO___-NEXT:    (local.get $0)
;; ZERO___-NEXT:    (i32.add
;; ZERO___-NEXT:     (local.get $0)
;; ZERO___-NEXT:     (i32.const 1)
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 20)
;; ZERO___-NEXT:   (i32.div_s
;; ZERO___-NEXT:    (local.get $1)
;; ZERO___-NEXT:    (i32.add
;; ZERO___-NEXT:     (local.get $1)
;; ZERO___-NEXT:     (i32.const 1)
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 30)
;; ZERO___-NEXT:   (i32.div_s
;; ZERO___-NEXT:    (local.get $2)
;; ZERO___-NEXT:    (i32.add
;; ZERO___-NEXT:     (local.get $2)
;; ZERO___-NEXT:     (i32.const 1)
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 40)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 50)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT: )

;; ZERO___:      (func $target_6 (type $5) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 10)
;; ZERO___-NEXT:   (i32.div_s
;; ZERO___-NEXT:    (local.get $0)
;; ZERO___-NEXT:    (i32.add
;; ZERO___-NEXT:     (local.get $0)
;; ZERO___-NEXT:     (i32.const 1)
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 20)
;; ZERO___-NEXT:   (i32.div_s
;; ZERO___-NEXT:    (local.get $1)
;; ZERO___-NEXT:    (i32.add
;; ZERO___-NEXT:     (local.get $1)
;; ZERO___-NEXT:     (i32.const 1)
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 30)
;; ZERO___-NEXT:   (i32.div_s
;; ZERO___-NEXT:    (local.get $2)
;; ZERO___-NEXT:    (i32.add
;; ZERO___-NEXT:     (local.get $2)
;; ZERO___-NEXT:     (i32.const 1)
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 40)
;; ZERO___-NEXT:   (i32.div_s
;; ZERO___-NEXT:    (local.get $3)
;; ZERO___-NEXT:    (i32.add
;; ZERO___-NEXT:     (local.get $3)
;; ZERO___-NEXT:     (i32.const 1)
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (i32.store
;; ZERO___-NEXT:   (i32.const 50)
;; ZERO___-NEXT:   (i32.const 0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT: )

;; THIRD__:      (func $target_2 (type $2)
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 10)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 20)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 30)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 40)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 50)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT: )

;; THIRD__:      (func $target_3 (type $0) (param $0 i32)
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 10)
;; THIRD__-NEXT:   (i32.div_s
;; THIRD__-NEXT:    (local.get $0)
;; THIRD__-NEXT:    (i32.add
;; THIRD__-NEXT:     (local.get $0)
;; THIRD__-NEXT:     (i32.const 1)
;; THIRD__-NEXT:    )
;; THIRD__-NEXT:   )
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 20)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 30)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 40)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 50)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT: )

;; THIRD__:      (func $target_4 (type $3) (param $0 i32) (param $1 i32)
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 10)
;; THIRD__-NEXT:   (i32.div_s
;; THIRD__-NEXT:    (local.get $0)
;; THIRD__-NEXT:    (i32.add
;; THIRD__-NEXT:     (local.get $0)
;; THIRD__-NEXT:     (i32.const 1)
;; THIRD__-NEXT:    )
;; THIRD__-NEXT:   )
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 20)
;; THIRD__-NEXT:   (i32.div_s
;; THIRD__-NEXT:    (local.get $1)
;; THIRD__-NEXT:    (i32.add
;; THIRD__-NEXT:     (local.get $1)
;; THIRD__-NEXT:     (i32.const 1)
;; THIRD__-NEXT:    )
;; THIRD__-NEXT:   )
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 30)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 40)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (i32.store
;; THIRD__-NEXT:   (i32.const 50)
;; THIRD__-NEXT:   (i32.const 0)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT: )

;; TWOTRDS:      (func $target_2 (type $2)
;; TWOTRDS-NEXT:  (i32.store
;; TWOTRDS-NEXT:   (i32.const 10)
;; TWOTRDS-NEXT:   (i32.const 0)
;; TWOTRDS-NEXT:  )
;; TWOTRDS-NEXT:  (i32.store
;; TWOTRDS-NEXT:   (i32.const 20)
;; TWOTRDS-NEXT:   (i32.const 0)
;; TWOTRDS-NEXT:  )
;; TWOTRDS-NEXT:  (i32.store
;; TWOTRDS-NEXT:   (i32.const 30)
;; TWOTRDS-NEXT:   (i32.const 0)
;; TWOTRDS-NEXT:  )
;; TWOTRDS-NEXT:  (i32.store
;; TWOTRDS-NEXT:   (i32.const 40)
;; TWOTRDS-NEXT:   (i32.const 0)
;; TWOTRDS-NEXT:  )
;; TWOTRDS-NEXT:  (i32.store
;; TWOTRDS-NEXT:   (i32.const 50)
;; TWOTRDS-NEXT:   (i32.const 0)
;; TWOTRDS-NEXT:  )
;; TWOTRDS-NEXT: )
(module
  ;; DEFAULT:      (type $A (sub (struct (field i32))))
  ;; ZERO___:      (type $A (sub (struct (field i32))))
  ;; THIRD__:      (type $A (sub (struct (field i32))))
  ;; TWOTRDS:      (type $A (sub (struct (field i32))))
  ;; HUNDRED:      (type $A (sub (struct (field i32))))
  (type $A (sub (struct (field i32))))

  ;; DEFAULT:      (type $1 (func))

  ;; DEFAULT:      (type $2 (func (param anyref) (result (ref $A))))

  ;; DEFAULT:      (type $3 (func (param anyref i32)))

  ;; DEFAULT:      (type $4 (func (param (ref $A))))

  ;; DEFAULT:      (type $5 (func (param anyref)))

  ;; DEFAULT:      (type $6 (func (param i32)))

  ;; DEFAULT:      (import "a" "b" (func $import (type $1)))
  ;; ZERO___:      (type $1 (func))

  ;; ZERO___:      (type $2 (func (param anyref) (result (ref $A))))

  ;; ZERO___:      (type $3 (func (param anyref i32)))

  ;; ZERO___:      (type $4 (func (param anyref)))

  ;; ZERO___:      (type $5 (func (param i32) (result (ref $A))))

  ;; ZERO___:      (type $6 (func (param i32)))

  ;; ZERO___:      (type $7 (func (result (ref $A))))

  ;; ZERO___:      (type $8 (func (param (ref $A))))

  ;; ZERO___:      (import "a" "b" (func $import (type $1)))
  ;; THIRD__:      (type $1 (func))

  ;; THIRD__:      (type $2 (func (param anyref) (result (ref $A))))

  ;; THIRD__:      (type $3 (func (param anyref i32)))

  ;; THIRD__:      (type $4 (func (param i32)))

  ;; THIRD__:      (type $5 (func (param (ref $A))))

  ;; THIRD__:      (type $6 (func (param anyref)))

  ;; THIRD__:      (import "a" "b" (func $import (type $1)))
  ;; TWOTRDS:      (type $1 (func))

  ;; TWOTRDS:      (type $2 (func (param anyref) (result (ref $A))))

  ;; TWOTRDS:      (type $3 (func (param anyref i32)))

  ;; TWOTRDS:      (type $4 (func (param i32)))

  ;; TWOTRDS:      (type $5 (func (param (ref $A))))

  ;; TWOTRDS:      (type $6 (func (param anyref)))

  ;; TWOTRDS:      (import "a" "b" (func $import (type $1)))
  ;; HUNDRED:      (type $1 (func (param anyref) (result (ref $A))))

  ;; HUNDRED:      (type $2 (func (param anyref i32)))

  ;; HUNDRED:      (type $3 (func))

  ;; HUNDRED:      (type $4 (func (param (ref $A))))

  ;; HUNDRED:      (import "a" "b" (func $import (type $3)))
  (import "a" "b" (func $import))

  ;; DEFAULT:      (import "a" "c" (func $import2 (type $4) (param (ref $A))))
  ;; ZERO___:      (import "a" "c" (func $import2 (type $8) (param (ref $A))))
  ;; THIRD__:      (import "a" "c" (func $import2 (type $5) (param (ref $A))))
  ;; TWOTRDS:      (import "a" "c" (func $import2 (type $5) (param (ref $A))))
  ;; HUNDRED:      (import "a" "c" (func $import2 (type $4) (param (ref $A))))
  (import "a" "c" (func $import2 (param (ref $A))))

  ;; DEFAULT:      (func $target-long (type $2) (param $0 anyref) (result (ref $A))
  ;; DEFAULT-NEXT:  (local $1 i32)
  ;; DEFAULT-NEXT:  (local.set $1
  ;; DEFAULT-NEXT:   (i32.const 1000)
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (loop $loop
  ;; DEFAULT-NEXT:   (br_if $loop
  ;; DEFAULT-NEXT:    (local.tee $1
  ;; DEFAULT-NEXT:     (i32.add
  ;; DEFAULT-NEXT:      (local.get $1)
  ;; DEFAULT-NEXT:      (local.get $1)
  ;; DEFAULT-NEXT:     )
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (ref.cast (ref $A)
  ;; DEFAULT-NEXT:   (local.get $0)
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT: )
  ;; ZERO___:      (func $target-long (type $2) (param $0 anyref) (result (ref $A))
  ;; ZERO___-NEXT:  (local $1 i32)
  ;; ZERO___-NEXT:  (local.set $1
  ;; ZERO___-NEXT:   (i32.const 1000)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (loop $loop
  ;; ZERO___-NEXT:   (br_if $loop
  ;; ZERO___-NEXT:    (local.tee $1
  ;; ZERO___-NEXT:     (i32.add
  ;; ZERO___-NEXT:      (local.get $1)
  ;; ZERO___-NEXT:      (local.get $1)
  ;; ZERO___-NEXT:     )
  ;; ZERO___-NEXT:    )
  ;; ZERO___-NEXT:   )
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (ref.cast (ref $A)
  ;; ZERO___-NEXT:   (local.get $0)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT: )
  ;; THIRD__:      (func $target-long (type $2) (param $0 anyref) (result (ref $A))
  ;; THIRD__-NEXT:  (local $1 i32)
  ;; THIRD__-NEXT:  (local.set $1
  ;; THIRD__-NEXT:   (i32.const 1000)
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (loop $loop
  ;; THIRD__-NEXT:   (br_if $loop
  ;; THIRD__-NEXT:    (local.tee $1
  ;; THIRD__-NEXT:     (i32.add
  ;; THIRD__-NEXT:      (local.get $1)
  ;; THIRD__-NEXT:      (local.get $1)
  ;; THIRD__-NEXT:     )
  ;; THIRD__-NEXT:    )
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (ref.cast (ref $A)
  ;; THIRD__-NEXT:   (local.get $0)
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT: )
  ;; TWOTRDS:      (func $target-long (type $2) (param $0 anyref) (result (ref $A))
  ;; TWOTRDS-NEXT:  (local $1 i32)
  ;; TWOTRDS-NEXT:  (local.set $1
  ;; TWOTRDS-NEXT:   (i32.const 1000)
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (loop $loop
  ;; TWOTRDS-NEXT:   (br_if $loop
  ;; TWOTRDS-NEXT:    (local.tee $1
  ;; TWOTRDS-NEXT:     (i32.add
  ;; TWOTRDS-NEXT:      (local.get $1)
  ;; TWOTRDS-NEXT:      (local.get $1)
  ;; TWOTRDS-NEXT:     )
  ;; TWOTRDS-NEXT:    )
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (ref.cast (ref $A)
  ;; TWOTRDS-NEXT:   (local.get $0)
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT: )
  ;; HUNDRED:      (func $target-long (type $1) (param $0 anyref) (result (ref $A))
  ;; HUNDRED-NEXT:  (local $1 i32)
  ;; HUNDRED-NEXT:  (local.set $1
  ;; HUNDRED-NEXT:   (i32.const 1000)
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (loop $loop
  ;; HUNDRED-NEXT:   (br_if $loop
  ;; HUNDRED-NEXT:    (local.tee $1
  ;; HUNDRED-NEXT:     (i32.add
  ;; HUNDRED-NEXT:      (local.get $1)
  ;; HUNDRED-NEXT:      (local.get $1)
  ;; HUNDRED-NEXT:     )
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (ref.cast (ref $A)
  ;; HUNDRED-NEXT:   (local.get $0)
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT: )
  (func $target-long (param $any anyref) (result (ref $A))
    (local $temp i32)
    ;; This function does a cast, aside from a lot of other work. The other work
    ;; causes us to only optimize when we are ok with getting a very small % of
    ;; improvement.

    ;; A silly loop that might in theory end after a long time.
    (local.set $temp (i32.const 1000))
    (loop $loop
      (local.set $temp (i32.add (local.get $temp) (local.get $temp)))
      (br_if $loop (local.get $temp))
    )

    (ref.cast (ref $A)
      (local.get $any)
    )
  )

  ;; DEFAULT:      (func $target-short (type $2) (param $0 anyref) (result (ref $A))
  ;; DEFAULT-NEXT:  (ref.cast (ref $A)
  ;; DEFAULT-NEXT:   (local.get $0)
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT: )
  ;; ZERO___:      (func $target-short (type $2) (param $0 anyref) (result (ref $A))
  ;; ZERO___-NEXT:  (ref.cast (ref $A)
  ;; ZERO___-NEXT:   (local.get $0)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT: )
  ;; THIRD__:      (func $target-short (type $2) (param $0 anyref) (result (ref $A))
  ;; THIRD__-NEXT:  (ref.cast (ref $A)
  ;; THIRD__-NEXT:   (local.get $0)
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT: )
  ;; TWOTRDS:      (func $target-short (type $2) (param $0 anyref) (result (ref $A))
  ;; TWOTRDS-NEXT:  (ref.cast (ref $A)
  ;; TWOTRDS-NEXT:   (local.get $0)
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT: )
  ;; HUNDRED:      (func $target-short (type $1) (param $0 anyref) (result (ref $A))
  ;; HUNDRED-NEXT:  (ref.cast (ref $A)
  ;; HUNDRED-NEXT:   (local.get $0)
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT: )
  (func $target-short (param $any anyref) (result (ref $A))
    ;; As above, but without all the work in the middle: this is really just a
    ;; simple casting function, and we can remove almost all the work here when
    ;; we remove the cast, meaning we optimize in more cases.
    (ref.cast (ref $A)
      (local.get $any)
    )
  )

  ;; DEFAULT:      (func $calls-long (type $3) (param $x anyref) (param $y i32)
  ;; DEFAULT-NEXT:  (call $import2
  ;; DEFAULT-NEXT:   (call $target-long
  ;; DEFAULT-NEXT:    (local.get $x)
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (drop
  ;; DEFAULT-NEXT:   (call $target-long
  ;; DEFAULT-NEXT:    (local.get $x)
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $import2
  ;; DEFAULT-NEXT:   (call $target-long
  ;; DEFAULT-NEXT:    (struct.new $A
  ;; DEFAULT-NEXT:     (local.get $y)
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (drop
  ;; DEFAULT-NEXT:   (call $target-long
  ;; DEFAULT-NEXT:    (struct.new $A
  ;; DEFAULT-NEXT:     (local.get $y)
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $import2
  ;; DEFAULT-NEXT:   (call $target-long
  ;; DEFAULT-NEXT:    (struct.new $A
  ;; DEFAULT-NEXT:     (i32.const 42)
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (drop
  ;; DEFAULT-NEXT:   (call $target-long
  ;; DEFAULT-NEXT:    (struct.new $A
  ;; DEFAULT-NEXT:     (i32.const 42)
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT: )
  ;; ZERO___:      (func $calls-long (type $3) (param $x anyref) (param $y i32)
  ;; ZERO___-NEXT:  (call $import2
  ;; ZERO___-NEXT:   (call $target-long
  ;; ZERO___-NEXT:    (local.get $x)
  ;; ZERO___-NEXT:   )
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $target-long_6
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $import2
  ;; ZERO___-NEXT:   (call $target-long_7
  ;; ZERO___-NEXT:    (local.get $y)
  ;; ZERO___-NEXT:   )
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $target-long_8
  ;; ZERO___-NEXT:   (local.get $y)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $import2
  ;; ZERO___-NEXT:   (call $target-long_9)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $target-long_10)
  ;; ZERO___-NEXT: )
  ;; THIRD__:      (func $calls-long (type $3) (param $x anyref) (param $y i32)
  ;; THIRD__-NEXT:  (call $import2
  ;; THIRD__-NEXT:   (call $target-long
  ;; THIRD__-NEXT:    (local.get $x)
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (drop
  ;; THIRD__-NEXT:   (call $target-long
  ;; THIRD__-NEXT:    (local.get $x)
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $import2
  ;; THIRD__-NEXT:   (call $target-long
  ;; THIRD__-NEXT:    (struct.new $A
  ;; THIRD__-NEXT:     (local.get $y)
  ;; THIRD__-NEXT:    )
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $target-long_6
  ;; THIRD__-NEXT:   (local.get $y)
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $import2
  ;; THIRD__-NEXT:   (call $target-long
  ;; THIRD__-NEXT:    (struct.new $A
  ;; THIRD__-NEXT:     (i32.const 42)
  ;; THIRD__-NEXT:    )
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $target-long_7)
  ;; THIRD__-NEXT: )
  ;; TWOTRDS:      (func $calls-long (type $3) (param $x anyref) (param $y i32)
  ;; TWOTRDS-NEXT:  (call $import2
  ;; TWOTRDS-NEXT:   (call $target-long
  ;; TWOTRDS-NEXT:    (local.get $x)
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (drop
  ;; TWOTRDS-NEXT:   (call $target-long
  ;; TWOTRDS-NEXT:    (local.get $x)
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $import2
  ;; TWOTRDS-NEXT:   (call $target-long
  ;; TWOTRDS-NEXT:    (struct.new $A
  ;; TWOTRDS-NEXT:     (local.get $y)
  ;; TWOTRDS-NEXT:    )
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $target-long_6
  ;; TWOTRDS-NEXT:   (local.get $y)
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $import2
  ;; TWOTRDS-NEXT:   (call $target-long
  ;; TWOTRDS-NEXT:    (struct.new $A
  ;; TWOTRDS-NEXT:     (i32.const 42)
  ;; TWOTRDS-NEXT:    )
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $target-long_7)
  ;; TWOTRDS-NEXT: )
  ;; HUNDRED:      (func $calls-long (type $2) (param $x anyref) (param $y i32)
  ;; HUNDRED-NEXT:  (call $import2
  ;; HUNDRED-NEXT:   (call $target-long
  ;; HUNDRED-NEXT:    (local.get $x)
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (drop
  ;; HUNDRED-NEXT:   (call $target-long
  ;; HUNDRED-NEXT:    (local.get $x)
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (call $import2
  ;; HUNDRED-NEXT:   (call $target-long
  ;; HUNDRED-NEXT:    (struct.new $A
  ;; HUNDRED-NEXT:     (local.get $y)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (drop
  ;; HUNDRED-NEXT:   (call $target-long
  ;; HUNDRED-NEXT:    (struct.new $A
  ;; HUNDRED-NEXT:     (local.get $y)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (call $import2
  ;; HUNDRED-NEXT:   (call $target-long
  ;; HUNDRED-NEXT:    (struct.new $A
  ;; HUNDRED-NEXT:     (i32.const 42)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (drop
  ;; HUNDRED-NEXT:   (call $target-long
  ;; HUNDRED-NEXT:    (struct.new $A
  ;; HUNDRED-NEXT:     (i32.const 42)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT: )
  (func $calls-long (param $x anyref) (param $y i32)
    ;; Various calls to $target-long. Because of the large amount of work that
    ;; cannot be removed there, all we do here is:
    ;;  * Optimize in all cases when the minimum benefit is 0% (except the
    ;;    first call, which is a trivial call context). Removing a cast is
    ;;    enough to justify optimizing.
    ;;  * In 33% and 66% we optimize only two cases. There we remove both a cast
    ;;    and a struct.new, and the struct.new's high cost makes it worthwhile.
    ;;  * In 100% we optimize nothing at all.

    ;; Call with an unknown input and the output is sent to an import.
    (call $import2
      (call $target-long
        (local.get $x)
      )
    )
    ;; Ditto, but drop the output.
    (drop
      (call $target-long
        (local.get $x)
      )
    )
    ;; Calls with a struct.new input.
    (call $import2
      (call $target-long
        (struct.new $A
          (local.get $y)
        )
      )
    )
    (drop
      (call $target-long
        (struct.new $A
          (local.get $y)
        )
      )
    )
    ;; Now the struct.new has a constant input.
    (call $import2
      (call $target-long
        (struct.new $A
          (i32.const 42)
        )
      )
    )
    (drop
      (call $target-long
        (struct.new $A
          (i32.const 42)
        )
      )
    )
  )

  ;; DEFAULT:      (func $calls-short (type $3) (param $x anyref) (param $y i32)
  ;; DEFAULT-NEXT:  (call $import2
  ;; DEFAULT-NEXT:   (call $target-short
  ;; DEFAULT-NEXT:    (local.get $x)
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $target-short_6
  ;; DEFAULT-NEXT:   (local.get $x)
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $import2
  ;; DEFAULT-NEXT:   (call $target-short
  ;; DEFAULT-NEXT:    (struct.new $A
  ;; DEFAULT-NEXT:     (local.get $y)
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $target-short_7
  ;; DEFAULT-NEXT:   (local.get $y)
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $import2
  ;; DEFAULT-NEXT:   (call $target-short
  ;; DEFAULT-NEXT:    (struct.new $A
  ;; DEFAULT-NEXT:     (i32.const 42)
  ;; DEFAULT-NEXT:    )
  ;; DEFAULT-NEXT:   )
  ;; DEFAULT-NEXT:  )
  ;; DEFAULT-NEXT:  (call $target-short_8)
  ;; DEFAULT-NEXT: )
  ;; ZERO___:      (func $calls-short (type $3) (param $x anyref) (param $y i32)
  ;; ZERO___-NEXT:  (call $import2
  ;; ZERO___-NEXT:   (call $target-short
  ;; ZERO___-NEXT:    (local.get $x)
  ;; ZERO___-NEXT:   )
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $target-short_11
  ;; ZERO___-NEXT:   (local.get $x)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $import2
  ;; ZERO___-NEXT:   (call $target-short_12
  ;; ZERO___-NEXT:    (local.get $y)
  ;; ZERO___-NEXT:   )
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $target-short_13
  ;; ZERO___-NEXT:   (local.get $y)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $import2
  ;; ZERO___-NEXT:   (call $target-short_14)
  ;; ZERO___-NEXT:  )
  ;; ZERO___-NEXT:  (call $target-short_15)
  ;; ZERO___-NEXT: )
  ;; THIRD__:      (func $calls-short (type $3) (param $x anyref) (param $y i32)
  ;; THIRD__-NEXT:  (call $import2
  ;; THIRD__-NEXT:   (call $target-short
  ;; THIRD__-NEXT:    (local.get $x)
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $target-short_8
  ;; THIRD__-NEXT:   (local.get $x)
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $import2
  ;; THIRD__-NEXT:   (call $target-short
  ;; THIRD__-NEXT:    (struct.new $A
  ;; THIRD__-NEXT:     (local.get $y)
  ;; THIRD__-NEXT:    )
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $target-short_9
  ;; THIRD__-NEXT:   (local.get $y)
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $import2
  ;; THIRD__-NEXT:   (call $target-short
  ;; THIRD__-NEXT:    (struct.new $A
  ;; THIRD__-NEXT:     (i32.const 42)
  ;; THIRD__-NEXT:    )
  ;; THIRD__-NEXT:   )
  ;; THIRD__-NEXT:  )
  ;; THIRD__-NEXT:  (call $target-short_10)
  ;; THIRD__-NEXT: )
  ;; TWOTRDS:      (func $calls-short (type $3) (param $x anyref) (param $y i32)
  ;; TWOTRDS-NEXT:  (call $import2
  ;; TWOTRDS-NEXT:   (call $target-short
  ;; TWOTRDS-NEXT:    (local.get $x)
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $target-short_8
  ;; TWOTRDS-NEXT:   (local.get $x)
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $import2
  ;; TWOTRDS-NEXT:   (call $target-short
  ;; TWOTRDS-NEXT:    (struct.new $A
  ;; TWOTRDS-NEXT:     (local.get $y)
  ;; TWOTRDS-NEXT:    )
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $target-short_9
  ;; TWOTRDS-NEXT:   (local.get $y)
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $import2
  ;; TWOTRDS-NEXT:   (call $target-short
  ;; TWOTRDS-NEXT:    (struct.new $A
  ;; TWOTRDS-NEXT:     (i32.const 42)
  ;; TWOTRDS-NEXT:    )
  ;; TWOTRDS-NEXT:   )
  ;; TWOTRDS-NEXT:  )
  ;; TWOTRDS-NEXT:  (call $target-short_10)
  ;; TWOTRDS-NEXT: )
  ;; HUNDRED:      (func $calls-short (type $2) (param $x anyref) (param $y i32)
  ;; HUNDRED-NEXT:  (call $import2
  ;; HUNDRED-NEXT:   (call $target-short
  ;; HUNDRED-NEXT:    (local.get $x)
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (drop
  ;; HUNDRED-NEXT:   (call $target-short
  ;; HUNDRED-NEXT:    (local.get $x)
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (call $import2
  ;; HUNDRED-NEXT:   (call $target-short
  ;; HUNDRED-NEXT:    (struct.new $A
  ;; HUNDRED-NEXT:     (local.get $y)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (drop
  ;; HUNDRED-NEXT:   (call $target-short
  ;; HUNDRED-NEXT:    (struct.new $A
  ;; HUNDRED-NEXT:     (local.get $y)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (call $import2
  ;; HUNDRED-NEXT:   (call $target-short
  ;; HUNDRED-NEXT:    (struct.new $A
  ;; HUNDRED-NEXT:     (i32.const 42)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT:  (drop
  ;; HUNDRED-NEXT:   (call $target-short
  ;; HUNDRED-NEXT:    (struct.new $A
  ;; HUNDRED-NEXT:     (i32.const 42)
  ;; HUNDRED-NEXT:    )
  ;; HUNDRED-NEXT:   )
  ;; HUNDRED-NEXT:  )
  ;; HUNDRED-NEXT: )
  (func $calls-short (param $x anyref) (param $y i32)
    ;; As above, but now calling the short function:
    ;;  * 0% is the same with the long function: any improvement is enough.
    ;;  * 33% optimizes some, but not all (the first is a trivial call context;
    ;;    some of the others do not optimize because the struct.new is
    ;;    expensive, and if the output goes into another call, we cannot remove
    ;;    it).
    ;;  * 66% optimizes a few less cases: when the output isn't dropped then we
    ;;    can't do enough work to justify it.
    ;;  * 100% optimizes nothing.
    (call $import2
      (call $target-short
        (local.get $x)
      )
    )
    (drop
      (call $target-short
        (local.get $x)
      )
    )
    (call $import2
      (call $target-short
        (struct.new $A
          (local.get $y)
        )
      )
    )
    (drop
      (call $target-short
        (struct.new $A
          (local.get $y)
        )
      )
    )
    (call $import2
      (call $target-short
        (struct.new $A
          (i32.const 42)
        )
      )
    )
    (drop
      (call $target-short
        (struct.new $A
          (i32.const 42)
        )
      )
    )
  )
)
;; DEFAULT:      (func $target-short_6 (type $5) (param $0 anyref)
;; DEFAULT-NEXT:  (nop)
;; DEFAULT-NEXT: )

;; DEFAULT:      (func $target-short_7 (type $6) (param $0 i32)
;; DEFAULT-NEXT:  (nop)
;; DEFAULT-NEXT: )

;; DEFAULT:      (func $target-short_8 (type $1)
;; DEFAULT-NEXT:  (nop)
;; DEFAULT-NEXT: )

;; ZERO___:      (func $target-long_6 (type $4) (param $0 anyref)
;; ZERO___-NEXT:  (local $1 i32)
;; ZERO___-NEXT:  (local.set $1
;; ZERO___-NEXT:   (i32.const 1000)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (loop $loop
;; ZERO___-NEXT:   (br_if $loop
;; ZERO___-NEXT:    (local.tee $1
;; ZERO___-NEXT:     (i32.add
;; ZERO___-NEXT:      (local.get $1)
;; ZERO___-NEXT:      (local.get $1)
;; ZERO___-NEXT:     )
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT: )

;; ZERO___:      (func $target-long_7 (type $5) (param $0 i32) (result (ref $A))
;; ZERO___-NEXT:  (local $1 (ref (exact $A)))
;; ZERO___-NEXT:  (local.set $1
;; ZERO___-NEXT:   (struct.new $A
;; ZERO___-NEXT:    (local.get $0)
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (local.set $0
;; ZERO___-NEXT:   (i32.const 1000)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (loop $loop
;; ZERO___-NEXT:   (br_if $loop
;; ZERO___-NEXT:    (local.tee $0
;; ZERO___-NEXT:     (i32.add
;; ZERO___-NEXT:      (local.get $0)
;; ZERO___-NEXT:      (local.get $0)
;; ZERO___-NEXT:     )
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (local.get $1)
;; ZERO___-NEXT: )

;; ZERO___:      (func $target-long_8 (type $6) (param $0 i32)
;; ZERO___-NEXT:  (local.set $0
;; ZERO___-NEXT:   (i32.const 1000)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (loop $loop
;; ZERO___-NEXT:   (br_if $loop
;; ZERO___-NEXT:    (local.tee $0
;; ZERO___-NEXT:     (i32.add
;; ZERO___-NEXT:      (local.get $0)
;; ZERO___-NEXT:      (local.get $0)
;; ZERO___-NEXT:     )
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT: )

;; ZERO___:      (func $target-long_9 (type $7) (result (ref $A))
;; ZERO___-NEXT:  (local $0 i32)
;; ZERO___-NEXT:  (local $1 (ref (exact $A)))
;; ZERO___-NEXT:  (local.set $0
;; ZERO___-NEXT:   (i32.const 1000)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (loop $loop
;; ZERO___-NEXT:   (br_if $loop
;; ZERO___-NEXT:    (local.tee $0
;; ZERO___-NEXT:     (i32.add
;; ZERO___-NEXT:      (local.get $0)
;; ZERO___-NEXT:      (local.get $0)
;; ZERO___-NEXT:     )
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (local.set $1
;; ZERO___-NEXT:   (struct.new $A
;; ZERO___-NEXT:    (i32.const 42)
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (local.get $1)
;; ZERO___-NEXT: )

;; ZERO___:      (func $target-long_10 (type $1)
;; ZERO___-NEXT:  (local $0 i32)
;; ZERO___-NEXT:  (local.set $0
;; ZERO___-NEXT:   (i32.const 1000)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT:  (loop $loop
;; ZERO___-NEXT:   (br_if $loop
;; ZERO___-NEXT:    (local.tee $0
;; ZERO___-NEXT:     (i32.add
;; ZERO___-NEXT:      (local.get $0)
;; ZERO___-NEXT:      (local.get $0)
;; ZERO___-NEXT:     )
;; ZERO___-NEXT:    )
;; ZERO___-NEXT:   )
;; ZERO___-NEXT:  )
;; ZERO___-NEXT: )

;; ZERO___:      (func $target-short_11 (type $4) (param $0 anyref)
;; ZERO___-NEXT:  (nop)
;; ZERO___-NEXT: )

;; ZERO___:      (func $target-short_12 (type $5) (param $0 i32) (result (ref $A))
;; ZERO___-NEXT:  (struct.new $A
;; ZERO___-NEXT:   (local.get $0)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT: )

;; ZERO___:      (func $target-short_13 (type $6) (param $0 i32)
;; ZERO___-NEXT:  (nop)
;; ZERO___-NEXT: )

;; ZERO___:      (func $target-short_14 (type $7) (result (ref $A))
;; ZERO___-NEXT:  (struct.new $A
;; ZERO___-NEXT:   (i32.const 42)
;; ZERO___-NEXT:  )
;; ZERO___-NEXT: )

;; ZERO___:      (func $target-short_15 (type $1)
;; ZERO___-NEXT:  (nop)
;; ZERO___-NEXT: )

;; THIRD__:      (func $target-long_6 (type $4) (param $0 i32)
;; THIRD__-NEXT:  (local.set $0
;; THIRD__-NEXT:   (i32.const 1000)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (loop $loop
;; THIRD__-NEXT:   (br_if $loop
;; THIRD__-NEXT:    (local.tee $0
;; THIRD__-NEXT:     (i32.add
;; THIRD__-NEXT:      (local.get $0)
;; THIRD__-NEXT:      (local.get $0)
;; THIRD__-NEXT:     )
;; THIRD__-NEXT:    )
;; THIRD__-NEXT:   )
;; THIRD__-NEXT:  )
;; THIRD__-NEXT: )

;; THIRD__:      (func $target-long_7 (type $1)
;; THIRD__-NEXT:  (local $0 i32)
;; THIRD__-NEXT:  (local.set $0
;; THIRD__-NEXT:   (i32.const 1000)
;; THIRD__-NEXT:  )
;; THIRD__-NEXT:  (loop $loop
;; THIRD__-NEXT:   (br_if $loop
;; THIRD__-NEXT:    (local.tee $0
;; THIRD__-NEXT:     (i32.add
;; THIRD__-NEXT:      (local.get $0)
;; THIRD__-NEXT:      (local.get $0)
;; THIRD__-NEXT:     )
;; THIRD__-NEXT:    )
;; THIRD__-NEXT:   )
;; THIRD__-NEXT:  )
;; THIRD__-NEXT: )

;; THIRD__:      (func $target-short_8 (type $6) (param $0 anyref)
;; THIRD__-NEXT:  (nop)
;; THIRD__-NEXT: )

;; THIRD__:      (func $target-short_9 (type $4) (param $0 i32)
;; THIRD__-NEXT:  (nop)
;; THIRD__-NEXT: )

;; THIRD__:      (func $target-short_10 (type $1)
;; THIRD__-NEXT:  (nop)
;; THIRD__-NEXT: )

;; TWOTRDS:      (func $target-long_6 (type $4) (param $0 i32)
;; TWOTRDS-NEXT:  (local.set $0
;; TWOTRDS-NEXT:   (i32.const 1000)
;; TWOTRDS-NEXT:  )
;; TWOTRDS-NEXT:  (loop $loop
;; TWOTRDS-NEXT:   (br_if $loop
;; TWOTRDS-NEXT:    (local.tee $0
;; TWOTRDS-NEXT:     (i32.add
;; TWOTRDS-NEXT:      (local.get $0)
;; TWOTRDS-NEXT:      (local.get $0)
;; TWOTRDS-NEXT:     )
;; TWOTRDS-NEXT:    )
;; TWOTRDS-NEXT:   )
;; TWOTRDS-NEXT:  )
;; TWOTRDS-NEXT: )

;; TWOTRDS:      (func $target-long_7 (type $1)
;; TWOTRDS-NEXT:  (local $0 i32)
;; TWOTRDS-NEXT:  (local.set $0
;; TWOTRDS-NEXT:   (i32.const 1000)
;; TWOTRDS-NEXT:  )
;; TWOTRDS-NEXT:  (loop $loop
;; TWOTRDS-NEXT:   (br_if $loop
;; TWOTRDS-NEXT:    (local.tee $0
;; TWOTRDS-NEXT:     (i32.add
;; TWOTRDS-NEXT:      (local.get $0)
;; TWOTRDS-NEXT:      (local.get $0)
;; TWOTRDS-NEXT:     )
;; TWOTRDS-NEXT:    )
;; TWOTRDS-NEXT:   )
;; TWOTRDS-NEXT:  )
;; TWOTRDS-NEXT: )

;; TWOTRDS:      (func $target-short_8 (type $6) (param $0 anyref)
;; TWOTRDS-NEXT:  (nop)
;; TWOTRDS-NEXT: )

;; TWOTRDS:      (func $target-short_9 (type $4) (param $0 i32)
;; TWOTRDS-NEXT:  (nop)
;; TWOTRDS-NEXT: )

;; TWOTRDS:      (func $target-short_10 (type $1)
;; TWOTRDS-NEXT:  (nop)
;; TWOTRDS-NEXT: )
