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

;; RUN: foreach %s %t wasm-opt --memory64-lowering --enable-simd --enable-memory64 --enable-threads --enable-bulk-memory --enable-reference-types -S -o - | filecheck %s

;; Check the --table64-lowering alias
;; RUN: foreach %s %t wasm-opt --table64-lowering --enable-simd --enable-memory64 --enable-threads --enable-bulk-memory --enable-reference-types -S -o - | filecheck %s

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

 ;; CHECK:      (type $1 (func (param i64 v128)))

 ;; CHECK:      (import "env" "__memory_base" (global $__memory_base i64))
 (import "env" "__memory_base" (global $__memory_base i64))
 ;; CHECK:      (import "env" "__memory_base32" (global $__memory_base32 i32))

 ;; CHECK:      (memory $0 1 1)
 (memory $0 i64 1 1)
 (data (i64.const 0) "\00\00\00\00\00\00\00\00\00\00")
 (data (global.get $__memory_base) "foo")
 ;; CHECK:      (data $0 (i32.const 0) "\00\00\00\00\00\00\00\00\00\00")

 ;; CHECK:      (data $1 (global.get $__memory_base32) "foo")

 ;; CHECK:      (func $load
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.load
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 4)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.load align=1
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 4)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.load align=2
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 4)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.load
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 4)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.load offset=100
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 4)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.load offset=100 align=1
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 4)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.load offset=100 align=2
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 4)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.load offset=100
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 4)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.load offset=100 align=1
 ;; CHECK-NEXT:    (unreachable)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT: )
 (func $load
  (drop (i32.load (i64.const 4)))
  (drop (i32.load align=1 (i64.const 4)))
  (drop (i32.load align=2 (i64.const 4)))
  (drop (i32.load align=4 (i64.const 4)))
  (drop (i32.load offset=100 (i64.const 4)))
  (drop (i32.load offset=100 align=1 (i64.const 4)))
  (drop (i32.load offset=100 align=2 (i64.const 4)))
  (drop (i32.load offset=100 align=4 (i64.const 4)))
  (drop (i32.load offset=100 align=1 (unreachable)))
 )

 ;; CHECK:      (func $store
 ;; CHECK-NEXT:  (i32.store
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 4)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.const 8)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (i32.store align=1
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 4)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.const 8)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (i32.store align=2
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 4)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.const 8)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (i32.store
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 4)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.const 8)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (i32.store offset=100
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 4)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.const 8)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (i32.store offset=100 align=1
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 4)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.const 8)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (i32.store offset=100 align=2
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 4)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.const 8)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (i32.store offset=100
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 4)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.const 8)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (i32.store offset=100 align=1
 ;; CHECK-NEXT:   (unreachable)
 ;; CHECK-NEXT:   (i32.const 8)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (i32.store offset=100 align=1
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 4)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (unreachable)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT: )
 (func $store
  (i32.store (i64.const 4) (i32.const 8))
  (i32.store align=1 (i64.const 4) (i32.const 8))
  (i32.store align=2 (i64.const 4) (i32.const 8))
  (i32.store align=4 (i64.const 4) (i32.const 8))
  (i32.store offset=100 (i64.const 4) (i32.const 8))
  (i32.store offset=100 align=1 (i64.const 4) (i32.const 8))
  (i32.store offset=100 align=2 (i64.const 4) (i32.const 8))
  (i32.store offset=100 align=4 (i64.const 4) (i32.const 8))
  (i32.store offset=100 align=1 (unreachable) (i32.const 8))
  (i32.store offset=100 align=1 (i64.const 4) (unreachable))
 )

 ;; CHECK:      (func $atomics
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.atomic.load
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 4)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (i32.atomic.store
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 4)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.const 8)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.atomic.rmw8.add_u
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 1)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:    (i32.const 2)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (i32.atomic.rmw8.cmpxchg_u
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 1)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:    (i32.const 2)
 ;; CHECK-NEXT:    (i32.const 3)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (memory.atomic.wait32
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 1)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:    (i32.const 2)
 ;; CHECK-NEXT:    (i64.const 3)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (drop
 ;; CHECK-NEXT:   (memory.atomic.notify
 ;; CHECK-NEXT:    (i32.wrap_i64
 ;; CHECK-NEXT:     (i64.const 1)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:    (i32.const 2)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT: )
 (func $atomics
  (drop (i32.atomic.load (i64.const 4)))
  (i32.atomic.store (i64.const 4) (i32.const 8))
  (drop (i32.atomic.rmw8.add_u (i64.const 1) (i32.const 2)))
  (drop (i32.atomic.rmw8.cmpxchg_u (i64.const 1) (i32.const 2) (i32.const 3)))
  (drop (memory.atomic.wait32 (i64.const 1) (i32.const 2) (i64.const 3)))
  (drop (memory.atomic.notify (i64.const 1) (i32.const 2)))
 )

 ;; CHECK:      (func $other
 ;; CHECK-NEXT:  (local $0 i64)
 ;; CHECK-NEXT:  (local $1 i32)
 ;; CHECK-NEXT:  (local.set $0
 ;; CHECK-NEXT:   (i64.extend_i32_u
 ;; CHECK-NEXT:    (memory.size)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (local.set $0
 ;; CHECK-NEXT:   (if (result i64)
 ;; CHECK-NEXT:    (i32.eq
 ;; CHECK-NEXT:     (i32.const -1)
 ;; CHECK-NEXT:     (local.tee $1
 ;; CHECK-NEXT:      (memory.grow
 ;; CHECK-NEXT:       (i32.wrap_i64
 ;; CHECK-NEXT:        (i64.const 1)
 ;; CHECK-NEXT:       )
 ;; CHECK-NEXT:      )
 ;; CHECK-NEXT:     )
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:    (then
 ;; CHECK-NEXT:     (i64.const -1)
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:    (else
 ;; CHECK-NEXT:     (i64.extend_i32_u
 ;; CHECK-NEXT:      (local.get $1)
 ;; CHECK-NEXT:     )
 ;; CHECK-NEXT:    )
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (memory.init $0
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 1)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.const 2)
 ;; CHECK-NEXT:   (i32.const 3)
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (memory.fill
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 1)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.const 2)
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 3)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT:  (memory.copy
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 1)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 2)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:   (i32.wrap_i64
 ;; CHECK-NEXT:    (i64.const 3)
 ;; CHECK-NEXT:   )
 ;; CHECK-NEXT:  )
 ;; CHECK-NEXT: )
 (func $other
  (local i64)
  (local.set 0 (memory.size))
  (local.set 0 (memory.grow (i64.const 1)))
  (memory.init 0 (i64.const 1) (i32.const 2) (i32.const 3))
  (memory.fill (i64.const 1) (i32.const 2) (i64.const 3))
  (memory.copy (i64.const 1) (i64.const 2) (i64.const 3))
 )

  ;; CHECK:      (func $simd (param $ptr i64) (param $val v128)
  ;; CHECK-NEXT:  (v128.store
  ;; CHECK-NEXT:   (i32.wrap_i64
  ;; CHECK-NEXT:    (local.get $ptr)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (local.get $val)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (v128.store8_lane 0
  ;; CHECK-NEXT:   (i32.wrap_i64
  ;; CHECK-NEXT:    (local.get $ptr)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (local.get $val)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (v128.load
  ;; CHECK-NEXT:    (i32.wrap_i64
  ;; CHECK-NEXT:     (local.get $ptr)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (v128.load8_lane 0
  ;; CHECK-NEXT:    (i32.wrap_i64
  ;; CHECK-NEXT:     (local.get $ptr)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (local.get $val)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (v128.load8_splat
  ;; CHECK-NEXT:    (i32.wrap_i64
  ;; CHECK-NEXT:     (local.get $ptr)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (v128.load8x8_s
  ;; CHECK-NEXT:    (i32.wrap_i64
  ;; CHECK-NEXT:     (local.get $ptr)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (v128.load32_zero
  ;; CHECK-NEXT:    (i32.wrap_i64
  ;; CHECK-NEXT:     (local.get $ptr)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $simd (param $ptr i64) (param $val v128)
   (v128.store (local.get $ptr) (local.get $val))
   (v128.store8_lane 0 (local.get $ptr) (local.get $val))
   (drop (v128.load (local.get $ptr)))
   (drop (v128.load8_lane 0 (local.get $ptr) (local.get $val)))
   (drop (v128.load8_splat (local.get $ptr)))
   (drop (v128.load8x8_s (local.get $ptr)))
   (drop (v128.load32_zero (local.get $ptr)))
  )
 )

(module
  ;; CHECK:      (memory $0 1 65536)
  (memory $0 i64 1 65537)
)

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

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

  ;; CHECK:      (table $t64 10 100 funcref)
  (table $t64 i64 10 100 funcref)

  ;; CHECK:      (table $t32 10 100 funcref)

  ;; CHECK:      (elem $elem64 (table $t64) (i32.const 0) funcref (item (ref.null nofunc)))
  (elem $elem64 (table $t64) (i64.const 0) funcref (ref.null func))

  (table $t32 10 100 funcref)
  ;; CHECK:      (elem $elem32 (table $t32) (i32.const 0) funcref (item (ref.null nofunc)))
  (elem $elem32 (table $t32) (i32.const 0) funcref (ref.null func))

  ;; CHECK:      (func $test_call_indirect
  ;; CHECK-NEXT:  (call_indirect $t64 (type $0)
  ;; CHECK-NEXT:   (i32.wrap_i64
  ;; CHECK-NEXT:    (i64.const 0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test_call_indirect
    (call_indirect 0 (i64.const 0))
  )

  ;; CHECK:      (func $test_table_size (result i64)
  ;; CHECK-NEXT:  (i64.extend_i32_u
  ;; CHECK-NEXT:   (table.size $t64)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test_table_size (result i64)
    (table.size $t64)
  )

  ;; CHECK:      (func $test_table_grow (result i64)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (if (result i64)
  ;; CHECK-NEXT:   (i32.eq
  ;; CHECK-NEXT:    (i32.const -1)
  ;; CHECK-NEXT:    (local.tee $0
  ;; CHECK-NEXT:     (table.grow $t64
  ;; CHECK-NEXT:      (ref.null nofunc)
  ;; CHECK-NEXT:      (i32.wrap_i64
  ;; CHECK-NEXT:       (i64.const 10)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (i64.const -1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (else
  ;; CHECK-NEXT:    (i64.extend_i32_u
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test_table_grow (result i64)
    ;; table.grow returns -1 on failure. The lowering must check for -1 and
    ;; return i64(-1) instead of i64.extend_i32_u(i32(-1)) which would be
    ;; 4294967295.
    (table.grow $t64 (ref.null func) (i64.const 10))
  )

  ;; CHECK:      (func $test_table_fill
  ;; CHECK-NEXT:  (table.fill $t64
  ;; CHECK-NEXT:   (i32.wrap_i64
  ;; CHECK-NEXT:    (i64.const 0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (ref.null nofunc)
  ;; CHECK-NEXT:   (i32.wrap_i64
  ;; CHECK-NEXT:    (i64.const 10)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test_table_fill
    (table.fill $t64 (i64.const 0) (ref.null func) (i64.const 10))
  )

  ;; CHECK:      (func $test_table_init
  ;; CHECK-NEXT:  (table.init $t64 $elem64
  ;; CHECK-NEXT:   (i32.wrap_i64
  ;; CHECK-NEXT:    (i64.const 0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (i32.const 5)
  ;; CHECK-NEXT:   (i32.const 10)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test_table_init
    (table.init $t64 $elem64 (i64.const 0) (i32.const 5) (i32.const 10))
  )
)

(module
  (memory i64 1 1)

  ;; CHECK:      (type $0 (func (param i64 v128)))

  ;; CHECK:      (type $1 (func (param i64) (result i32)))

  ;; CHECK:      (type $2 (func (param i64 i32)))

  ;; CHECK:      (type $3 (func (param i64)))

  ;; CHECK:      (memory $0 1 1)

  ;; CHECK:      (func $test_large_offsets (param $ptr i64) (result i32)
  ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  (func $test_large_offsets (param $ptr i64) (result i32)
    (i32.load offset=4294967297 (local.get $ptr))
  )

  ;; CHECK:      (func $test_store_large_offset (param $ptr i64) (param $val i32)
  ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  (func $test_store_large_offset (param $ptr i64) (param $val i32)
    (i32.store offset=4294967296 (local.get $ptr) (local.get $val))
  )

  ;; CHECK:      (func $test_simd_load_large_offset (param $ptr i64)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test_simd_load_large_offset (param $ptr i64)
    (drop (v128.load offset=4294967296 (local.get $ptr)))
  )

  ;; CHECK:      (func $test_simd_load_lane_large_offset (param $ptr i64) (param $val v128)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test_simd_load_lane_large_offset (param $ptr i64) (param $val v128)
    (drop (v128.load8_lane offset=4294967296 0 (local.get $ptr) (local.get $val)))
  )

  ;; CHECK:      (func $test_simd_store_lane_large_offset (param $ptr i64) (param $val v128)
  ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  (func $test_simd_store_lane_large_offset (param $ptr i64) (param $val v128)
    (v128.store8_lane offset=4294967296 0 (local.get $ptr) (local.get $val))
  )
)

(module
  ;; CHECK:      (type $0 (func (param i64 i32)))

  ;; CHECK:      (type $1 (func (param i64 i32 i32)))

  ;; CHECK:      (type $2 (func (param i64 i32 i64)))

  ;; CHECK:      (type $3 (func (param i64) (result i32)))

  ;; CHECK:      (memory $0 1 1)
  (memory $0 i64 1 1)

  ;; CHECK:      (func $test_atomic_rmw_large_offset (param $ptr i64) (param $val i32)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test_atomic_rmw_large_offset (param $ptr i64) (param $val i32)
    (drop (i32.atomic.rmw.add offset=4294967296 (local.get $ptr) (local.get $val)))
  )

  ;; CHECK:      (func $test_atomic_cmpxchg_large_offset (param $ptr i64) (param $exp i32) (param $new i32)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test_atomic_cmpxchg_large_offset (param $ptr i64) (param $exp i32) (param $new i32)
    (drop (i32.atomic.rmw.cmpxchg offset=4294967296 (local.get $ptr) (local.get $exp) (local.get $new)))
  )

  ;; CHECK:      (func $test_atomic_wait_large_offset (param $ptr i64) (param $exp i32) (param $timeout i64)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test_atomic_wait_large_offset (param $ptr i64) (param $exp i32) (param $timeout i64)
    (drop (memory.atomic.wait32 offset=4294967296 (local.get $ptr) (local.get $exp) (local.get $timeout)))
  )

  ;; CHECK:      (func $test_atomic_notify_large_offset (param $ptr i64) (param $count i32)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test_atomic_notify_large_offset (param $ptr i64) (param $count i32)
    (drop (memory.atomic.notify offset=4294967296 (local.get $ptr) (local.get $count)))
  )

  ;; CHECK:      (func $test_large_offsets_effect (param $ptr i64) (result i32)
  ;; CHECK-NEXT:  (local $1 i64)
  ;; CHECK-NEXT:  (local.set $1
  ;; CHECK-NEXT:   (i64.div_s
  ;; CHECK-NEXT:    (i64.const 1337)
  ;; CHECK-NEXT:    (local.get $ptr)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  (func $test_large_offsets_effect (param $ptr i64) (result i32)
    (i32.load offset=4294967297
      ;; This might trap, and must be kept around.
      (i64.div_s
        (i64.const 1337)
        (local.get $ptr)
      )
    )
  )
)
