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

;; Test that global effects let us optimize more in a pass like simplify-locals.

;; RUN: foreach %s %t wasm-opt                           --simplify-locals -S -o - | filecheck %s --check-prefix NORMAL_EFFECTS
;; RUN: foreach %s %t wasm-opt --generate-global-effects --simplify-locals -S -o - | filecheck %s --check-prefix GLOBAL_EFFECTS

(module
  ;; NORMAL_EFFECTS:      (type $0 (func))

  ;; NORMAL_EFFECTS:      (global $global (mut i32) (i32.const 0))
  ;; GLOBAL_EFFECTS:      (type $0 (func))

  ;; GLOBAL_EFFECTS:      (global $global (mut i32) (i32.const 0))
  (global $global (mut i32) (i32.const 0))

  ;; NORMAL_EFFECTS:      (func $past-get
  ;; NORMAL_EFFECTS-NEXT:  (local $x i32)
  ;; NORMAL_EFFECTS-NEXT:  (local.set $x
  ;; NORMAL_EFFECTS-NEXT:   (global.get $global)
  ;; NORMAL_EFFECTS-NEXT:  )
  ;; NORMAL_EFFECTS-NEXT:  (call $get-global)
  ;; NORMAL_EFFECTS-NEXT:  (drop
  ;; NORMAL_EFFECTS-NEXT:   (local.get $x)
  ;; NORMAL_EFFECTS-NEXT:  )
  ;; NORMAL_EFFECTS-NEXT: )
  ;; GLOBAL_EFFECTS:      (func $past-get
  ;; GLOBAL_EFFECTS-NEXT:  (local $x i32)
  ;; GLOBAL_EFFECTS-NEXT:  (nop)
  ;; GLOBAL_EFFECTS-NEXT:  (call $get-global)
  ;; GLOBAL_EFFECTS-NEXT:  (drop
  ;; GLOBAL_EFFECTS-NEXT:   (global.get $global)
  ;; GLOBAL_EFFECTS-NEXT:  )
  ;; GLOBAL_EFFECTS-NEXT: )
  (func $past-get
    (local $x i32)
    ;; We can move this set past the call (when we have global effects), since
    ;; the call only reads the global.
    (local.set $x
      (global.get $global)
    )
    (call $get-global)
    (drop
      (local.get $x)
    )
  )

  ;; NORMAL_EFFECTS:      (func $past-set
  ;; NORMAL_EFFECTS-NEXT:  (local $x i32)
  ;; NORMAL_EFFECTS-NEXT:  (local.set $x
  ;; NORMAL_EFFECTS-NEXT:   (global.get $global)
  ;; NORMAL_EFFECTS-NEXT:  )
  ;; NORMAL_EFFECTS-NEXT:  (call $set-global)
  ;; NORMAL_EFFECTS-NEXT:  (drop
  ;; NORMAL_EFFECTS-NEXT:   (local.get $x)
  ;; NORMAL_EFFECTS-NEXT:  )
  ;; NORMAL_EFFECTS-NEXT: )
  ;; GLOBAL_EFFECTS:      (func $past-set
  ;; GLOBAL_EFFECTS-NEXT:  (local $x i32)
  ;; GLOBAL_EFFECTS-NEXT:  (local.set $x
  ;; GLOBAL_EFFECTS-NEXT:   (global.get $global)
  ;; GLOBAL_EFFECTS-NEXT:  )
  ;; GLOBAL_EFFECTS-NEXT:  (call $set-global)
  ;; GLOBAL_EFFECTS-NEXT:  (drop
  ;; GLOBAL_EFFECTS-NEXT:   (local.get $x)
  ;; GLOBAL_EFFECTS-NEXT:  )
  ;; GLOBAL_EFFECTS-NEXT: )
  (func $past-set
    (local $x i32)
    ;; We cannot move this set past the call, since the call writes the global.
    (local.set $x
      (global.get $global)
    )
    (call $set-global)
    (drop
      (local.get $x)
    )
  )

  ;; NORMAL_EFFECTS:      (func $set-global
  ;; NORMAL_EFFECTS-NEXT:  (global.set $global
  ;; NORMAL_EFFECTS-NEXT:   (i32.const 1)
  ;; NORMAL_EFFECTS-NEXT:  )
  ;; NORMAL_EFFECTS-NEXT: )
  ;; GLOBAL_EFFECTS:      (func $set-global
  ;; GLOBAL_EFFECTS-NEXT:  (global.set $global
  ;; GLOBAL_EFFECTS-NEXT:   (i32.const 1)
  ;; GLOBAL_EFFECTS-NEXT:  )
  ;; GLOBAL_EFFECTS-NEXT: )
  (func $set-global
    ;; Helper function.
    (global.set $global
      (i32.const 1)
    )
  )

  ;; NORMAL_EFFECTS:      (func $get-global
  ;; NORMAL_EFFECTS-NEXT:  (drop
  ;; NORMAL_EFFECTS-NEXT:   (global.get $global)
  ;; NORMAL_EFFECTS-NEXT:  )
  ;; NORMAL_EFFECTS-NEXT: )
  ;; GLOBAL_EFFECTS:      (func $get-global
  ;; GLOBAL_EFFECTS-NEXT:  (drop
  ;; GLOBAL_EFFECTS-NEXT:   (global.get $global)
  ;; GLOBAL_EFFECTS-NEXT:  )
  ;; GLOBAL_EFFECTS-NEXT: )
  (func $get-global
    ;; Helper function.
    (drop
      (global.get $global)
    )
  )
)