;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: foreach %s %t wasm-opt --memory-packing -all --zero-filled-memory      -S -o - | filecheck %s
;; RUN: foreach %s %t wasm-opt --memory-packing -all --zero-filled-memory -tnh -S -o - | filecheck %s --check-prefix=TNH__

;; Test that memory-packing correctly handles memory64 data segment offsets
;; with the high bit set (>= 0x80000000). These must be treated as unsigned
;; values, not sign-extended to 64 bits.

(module
  ;; An active data segment at offset 0x80000000 on a memory64 with only 2
  ;; pages. The offset far exceeds the memory size, so this should trap and the
  ;; segment must be preserved.
  ;; CHECK:      (memory $memory i64 2 2)
  ;; TNH__:      (memory $memory i64 2 2)
  (memory $memory i64 2 2)
  ;; CHECK:      (data $data (i64.const 2147483648) "\00")
  (data $data (i64.const 0x80000000) "\00")
)

(module
  ;; Similar to above but with a multi-byte segment that should be shortened to
  ;; a single byte at the highest address to preserve the trap.
  ;; CHECK:      (memory $memory i64 2 2)
  ;; TNH__:      (memory $memory i64 2 2)
  (memory $memory i64 2 2)
  ;; CHECK:      (data $data (i64.const 2147483650) "\00")
  (data $data (i64.const 0x80000000) "\00\00\00")
)

(module
  ;; Offset 0xFFFFFFFF (4GB - 1) on memory64. This is a valid i64 offset that
  ;; must not be confused with -1 in i32. The segment should trap.
  ;; CHECK:      (memory $memory i64 2 2)
  ;; TNH__:      (memory $memory i64 2 2)
  (memory $memory i64 2 2)
  ;; CHECK:      (data $data (i64.const 4294967295) "\00")
  (data $data (i64.const 0xFFFFFFFF) "\00")
)

(module
  ;; A memory64 with enough pages that offset 0x80000000 is in bounds (0x80000000
  ;; = 2GB, which is 32768 pages). The segment should be removable since it's all
  ;; zeroes and in bounds.
  ;; CHECK:      (memory $memory i64 32769 32769)
  ;; TNH__:      (memory $memory i64 32769 32769)
  (memory $memory i64 32769 32769)
  (data $data (i64.const 0x80000000) "\00")
)

(module
  ;; A passive segment used with memory.init. The memory.init offset into the
  ;; segment is 0x80000000 (as i32), which exceeds the segment data size and
  ;; should cause a trap. Ensure the i32 offset is treated as unsigned (2147483648)
  ;; not sign-extended to a negative value.
  ;; CHECK:      (type $0 (func))

  ;; CHECK:      (memory $memory i64 2 2)
  ;; TNH__:      (type $0 (func))

  ;; TNH__:      (memory $memory i64 2 2)
  (memory $memory i64 2 2)
  (data $data "hello")
  ;; CHECK:      (func $test (type $0)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i64.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const -2147483648)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const 1)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  ;; TNH__:      (func $test (type $0)
  ;; TNH__-NEXT:  (drop
  ;; TNH__-NEXT:   (i64.const 0)
  ;; TNH__-NEXT:  )
  ;; TNH__-NEXT:  (drop
  ;; TNH__-NEXT:   (i32.const -2147483648)
  ;; TNH__-NEXT:  )
  ;; TNH__-NEXT:  (drop
  ;; TNH__-NEXT:   (i32.const 1)
  ;; TNH__-NEXT:  )
  ;; TNH__-NEXT:  (unreachable)
  ;; TNH__-NEXT: )
  (func $test
    (memory.init $data
      (i64.const 0)
      (i32.const 0x80000000)
      (i32.const 1)
    )
  )
)

(module
  ;; A passive segment where memory.init size has the high bit set.
  ;; Size 0x80000000 (2147483648) exceeds the segment data size (5) and should
  ;; trap. Ensure the i32 size is treated as unsigned.
  ;; CHECK:      (type $0 (func))

  ;; CHECK:      (memory $memory i64 2 2)
  ;; TNH__:      (type $0 (func))

  ;; TNH__:      (memory $memory i64 2 2)
  (memory $memory i64 2 2)
  (data $data "hello")
  ;; CHECK:      (func $test (type $0)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i64.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const -2147483648)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  ;; TNH__:      (func $test (type $0)
  ;; TNH__-NEXT:  (drop
  ;; TNH__-NEXT:   (i64.const 0)
  ;; TNH__-NEXT:  )
  ;; TNH__-NEXT:  (drop
  ;; TNH__-NEXT:   (i32.const 0)
  ;; TNH__-NEXT:  )
  ;; TNH__-NEXT:  (drop
  ;; TNH__-NEXT:   (i32.const -2147483648)
  ;; TNH__-NEXT:  )
  ;; TNH__-NEXT:  (unreachable)
  ;; TNH__-NEXT: )
  (func $test
    (memory.init $data
      (i64.const 0)
      (i32.const 0)
      (i32.const 0x80000000)
    )
  )
)
