summaryrefslogtreecommitdiff
path: root/test/lit
diff options
context:
space:
mode:
Diffstat (limited to 'test/lit')
-rw-r--r--test/lit/exec/memory-copy.wat267
-rw-r--r--test/lit/exec/memory-fill.wat184
-rw-r--r--test/lit/help/wasm-metadce.test4
-rw-r--r--test/lit/help/wasm-opt.test4
-rw-r--r--test/lit/help/wasm2js.test4
-rw-r--r--test/lit/passes/memory-copy-fill-lowering.wast168
6 files changed, 631 insertions, 0 deletions
diff --git a/test/lit/exec/memory-copy.wat b/test/lit/exec/memory-copy.wat
new file mode 100644
index 000000000..793f94656
--- /dev/null
+++ b/test/lit/exec/memory-copy.wat
@@ -0,0 +1,267 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited.
+
+;; RUN: wasm-opt %s --enable-bulk-memory --memory-copy-fill-lowering --fuzz-exec -q -o /dev/null 2>&1 | filecheck %s
+
+;; Tests derived from bulk-memory.wast spec tests
+
+;; memory.copy
+(module
+ (import "fuzzing-support" "log-i32" (func $log-i32 (param i32)))
+ (memory 1 1)
+ (data (i32.const 0) "\aa\bb\cc\dd")
+
+ (func $assert_load (param i32 i32)
+ (if (i32.ne (local.get 1) (i32.load8_u (local.get 0)))
+ (then (unreachable)))
+ )
+
+ (func $print_memory
+ (local $i i32)
+ (local.set 0 (i32.const 9))
+ (loop $loop
+ (call $log-i32 (local.get 0))
+ (call $log-i32 (i32.load8_u (local.get 0)))
+ (local.set 0 (i32.add (local.get 0) (i32.const 1)))
+ (br_if $loop (i32.ne (local.get 0) (i32.const 17)))
+ )
+ )
+
+ ;; non-overlapping copy
+ ;; CHECK: [fuzz-exec] calling test1
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 9]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 10]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 11]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 12]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 13]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 14]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 15]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 16]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 9]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 10]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 170]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 11]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 187]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 12]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 204]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 13]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 221]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 14]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 15]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 16]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ (func $test1 (export "test1")
+ (call $print_memory)
+ (memory.copy (i32.const 10) (i32.const 0) (i32.const 4))
+ (call $print_memory)
+ (call $assert_load (i32.const 9) (i32.const 0))
+ (call $assert_load (i32.const 10) (i32.const 0xaa))
+ (call $assert_load (i32.const 11) (i32.const 0xbb))
+ (call $assert_load (i32.const 12) (i32.const 0xcc))
+ (call $assert_load (i32.const 13) (i32.const 0xdd))
+ (call $assert_load (i32.const 14) (i32.const 0))
+ )
+ ;; Overlap, src > dst
+ ;; CHECK: [fuzz-exec] calling test2
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 9]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 187]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 10]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 204]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 11]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 221]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 12]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 204]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 13]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 221]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 14]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 15]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 16]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ (func $test2 (export "test2")
+ (memory.copy (i32.const 8) (i32.const 10) (i32.const 4))
+ (call $print_memory)
+ (call $assert_load (i32.const 8) (i32.const 0xaa))
+ (call $assert_load (i32.const 9) (i32.const 0xbb))
+ (call $assert_load (i32.const 10) (i32.const 0xcc))
+ (call $assert_load (i32.const 11) (i32.const 0xdd))
+ (call $assert_load (i32.const 12) (i32.const 0xcc))
+ (call $assert_load (i32.const 13) (i32.const 0xdd))
+ )
+ ;; Overlap, src < dst
+ ;; CHECK: [fuzz-exec] calling test3
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 9]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 187]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 10]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 11]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 170]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 12]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 187]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 13]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 204]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 14]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 221]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 15]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 204]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 16]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ (func $test3 (export "test3")
+ (memory.copy (i32.const 10) (i32.const 7) (i32.const 6))
+ (call $print_memory)
+ (call $assert_load (i32.const 10) (i32.const 0x0))
+ (call $assert_load (i32.const 11) (i32.const 0xaa))
+ (call $assert_load (i32.const 12) (i32.const 0xbb))
+ (call $assert_load (i32.const 13) (i32.const 0xcc))
+ (call $assert_load (i32.const 14) (i32.const 0xdd))
+ (call $assert_load (i32.const 15) (i32.const 0xcc))
+ (call $assert_load (i32.const 16) (i32.const 0))
+ )
+ ;; Overlap src < dst but size is OOB (but the address does not overflow)
+ ;; CHECK: [fuzz-exec] calling test4a
+ ;; CHECK-NEXT: [trap out of bounds segment access in memory.copy]
+ (func $test4a (export "test4a")
+ (memory.copy (i32.const 13) (i32.const 11) (i32.const 0x10000))
+ (call $print_memory) ;; not reached.
+ )
+ ;; CHECK: [fuzz-exec] calling test4b
+ (func $test4b (export "test4b")
+ (call $assert_load (i32.const 10) (i32.const 0x0))
+ (call $assert_load (i32.const 11) (i32.const 0xaa))
+ (call $assert_load (i32.const 12) (i32.const 0xbb))
+ (call $assert_load (i32.const 13) (i32.const 0xcc))
+ (call $assert_load (i32.const 14) (i32.const 0xdd))
+ (call $assert_load (i32.const 15) (i32.const 0xcc))
+ (call $assert_load (i32.const 16) (i32.const 0))
+ )
+ ;; Copy ending at memory limit is ok
+ ;; CHECK: [fuzz-exec] calling test5
+ (func $test5 (export "test5")
+ (memory.copy (i32.const 0xff00) (i32.const 0) (i32.const 0x100))
+ (memory.copy (i32.const 0xfe00) (i32.const 0xff00) (i32.const 0x100))
+ )
+ ;; Succeed when copying 0 bytes at the end of the region
+ ;; CHECK: [fuzz-exec] calling test6
+ (func $test6 (export "test6")
+ (memory.copy (i32.const 0x10000) (i32.const 0) (i32.const 0))
+ (memory.copy (i32.const 0x0) (i32.const 0x10000) (i32.const 0))
+ )
+ ;; copying 0 bytes outside of the limit is not allowed.
+ ;; CHECK: [fuzz-exec] calling test7
+ ;; CHECK-NEXT: [trap out of bounds segment access in memory.copy]
+ (func $test7 (export "test7")
+ (memory.copy (i32.const 0x10001) (i32.const 0) (i32.const 0x0))
+ )
+ ;; CHECK: [fuzz-exec] calling test8
+ ;; CHECK-NEXT: [trap out of bounds segment access in memory.copy]
+ (func $test8 (export "test8")
+ (memory.copy (i32.const 0x0) (i32.const 0x10001) (i32.const 0))
+ )
+)
+
+
+
+;; CHECK: [fuzz-exec] calling test1
+;; CHECK-NEXT: [LoggingExternalInterface logging 9]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 10]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 11]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 12]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 13]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 14]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 15]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 16]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 9]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 10]
+;; CHECK-NEXT: [LoggingExternalInterface logging 170]
+;; CHECK-NEXT: [LoggingExternalInterface logging 11]
+;; CHECK-NEXT: [LoggingExternalInterface logging 187]
+;; CHECK-NEXT: [LoggingExternalInterface logging 12]
+;; CHECK-NEXT: [LoggingExternalInterface logging 204]
+;; CHECK-NEXT: [LoggingExternalInterface logging 13]
+;; CHECK-NEXT: [LoggingExternalInterface logging 221]
+;; CHECK-NEXT: [LoggingExternalInterface logging 14]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 15]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 16]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+
+;; CHECK: [fuzz-exec] calling test2
+;; CHECK-NEXT: [LoggingExternalInterface logging 9]
+;; CHECK-NEXT: [LoggingExternalInterface logging 187]
+;; CHECK-NEXT: [LoggingExternalInterface logging 10]
+;; CHECK-NEXT: [LoggingExternalInterface logging 204]
+;; CHECK-NEXT: [LoggingExternalInterface logging 11]
+;; CHECK-NEXT: [LoggingExternalInterface logging 221]
+;; CHECK-NEXT: [LoggingExternalInterface logging 12]
+;; CHECK-NEXT: [LoggingExternalInterface logging 204]
+;; CHECK-NEXT: [LoggingExternalInterface logging 13]
+;; CHECK-NEXT: [LoggingExternalInterface logging 221]
+;; CHECK-NEXT: [LoggingExternalInterface logging 14]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 15]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 16]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+
+;; CHECK: [fuzz-exec] calling test3
+;; CHECK-NEXT: [LoggingExternalInterface logging 9]
+;; CHECK-NEXT: [LoggingExternalInterface logging 187]
+;; CHECK-NEXT: [LoggingExternalInterface logging 10]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 11]
+;; CHECK-NEXT: [LoggingExternalInterface logging 170]
+;; CHECK-NEXT: [LoggingExternalInterface logging 12]
+;; CHECK-NEXT: [LoggingExternalInterface logging 187]
+;; CHECK-NEXT: [LoggingExternalInterface logging 13]
+;; CHECK-NEXT: [LoggingExternalInterface logging 204]
+;; CHECK-NEXT: [LoggingExternalInterface logging 14]
+;; CHECK-NEXT: [LoggingExternalInterface logging 221]
+;; CHECK-NEXT: [LoggingExternalInterface logging 15]
+;; CHECK-NEXT: [LoggingExternalInterface logging 204]
+;; CHECK-NEXT: [LoggingExternalInterface logging 16]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+
+;; CHECK: [fuzz-exec] calling test4a
+;; CHECK-NEXT: [trap unreachable]
+
+;; CHECK: [fuzz-exec] calling test4b
+
+;; CHECK: [fuzz-exec] calling test5
+
+;; CHECK: [fuzz-exec] calling test6
+
+;; CHECK: [fuzz-exec] calling test7
+;; CHECK-NEXT: [trap unreachable]
+
+;; CHECK: [fuzz-exec] calling test8
+;; CHECK-NEXT: [trap unreachable]
+;; CHECK-NEXT: [fuzz-exec] comparing test1
+;; CHECK-NEXT: [fuzz-exec] comparing test2
+;; CHECK-NEXT: [fuzz-exec] comparing test3
+;; CHECK-NEXT: [fuzz-exec] comparing test4a
+;; CHECK-NEXT: [fuzz-exec] comparing test4b
+;; CHECK-NEXT: [fuzz-exec] comparing test5
+;; CHECK-NEXT: [fuzz-exec] comparing test6
+;; CHECK-NEXT: [fuzz-exec] comparing test7
+;; CHECK-NEXT: [fuzz-exec] comparing test8
diff --git a/test/lit/exec/memory-fill.wat b/test/lit/exec/memory-fill.wat
new file mode 100644
index 000000000..dc9aead6d
--- /dev/null
+++ b/test/lit/exec/memory-fill.wat
@@ -0,0 +1,184 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited.
+
+;; RUN: wasm-opt %s --enable-bulk-memory --memory-copy-fill-lowering --fuzz-exec -q -o /dev/null 2>&1 | filecheck %s
+
+;; Tests derived from bulk-memory.wast spec tests
+
+;; memory.fill
+(module
+ (import "fuzzing-support" "log-i32" (func $log-i32 (param i32)))
+ (memory 1)
+
+
+ (func $assert_load (param i32 i32)
+ (if (i32.ne (local.get 1) (i32.load8_u (local.get 0)))
+ (then (unreachable)))
+ )
+
+ (func $print_memory (param i32 i32)
+ (loop $loop
+ (call $log-i32 (local.get 0))
+ (call $log-i32 (i32.load8_u (local.get 0)))
+ (local.set 0 (i32.add (local.get 0) (i32.const 1)))
+ (br_if $loop (i32.ne (local.get 0) (local.get 1)))
+ )
+ )
+ ;; basic fill test
+ ;; CHECK: [fuzz-exec] calling test1
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 2]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 3]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 4]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 255]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 2]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 255]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 3]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 255]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 4]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ (func $test1 (export "test1")
+ (call $print_memory (i32.const 0) (i32.const 5))
+ (memory.fill (i32.const 1) (i32.const 0xff) (i32.const 3))
+ (call $print_memory (i32.const 0) (i32.const 5))
+ (call $assert_load (i32.const 0) (i32.const 0))
+ (call $assert_load (i32.const 1) (i32.const 0xff))
+ (call $assert_load (i32.const 2) (i32.const 0xff))
+ (call $assert_load (i32.const 3) (i32.const 0xff))
+ (call $assert_load (i32.const 4) (i32.const 0x0))
+ )
+ ;; Fill value is stored as a byte
+ ;; CHECK: [fuzz-exec] calling test2
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 170]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 170]
+ (func $test2 (export "test2")
+ (memory.fill (i32.const 0) (i32.const 0xbbaa) (i32.const 2))
+ (call $print_memory (i32.const 0) (i32.const 2))
+ (call $assert_load (i32.const 0) (i32.const 0xaa))
+ (call $assert_load (i32.const 1) (i32.const 0xaa))
+ )
+ ;; Fill all of memory
+ ;; CHECK: [fuzz-exec] calling test3
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 2]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 3]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 4]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 5]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ (func $test3 (export "test3")
+ (memory.fill (i32.const 0) (i32.const 0) (i32.const 0x10000))
+ ;; let's not print all of memory; just beyond what we filled before
+ (call $print_memory (i32.const 0) (i32.const 6))
+ )
+ ;; Succeed when writing 0 bytes at the end of the region
+ ;; CHECK: [fuzz-exec] calling test4
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 2]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 3]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 4]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 5]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 6]
+ ;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+ (func $test4 (export "test4")
+ (memory.fill (i32.const 0x10000) (i32.const 0) (i32.const 0))
+ ;; let's not print all of memory; just beyond what we filled before
+ (call $print_memory (i32.const 0) (i32.const 7))
+ )
+ ;; Writing 0 bytes outside of memory is not allowed
+ ;; CHECK: [fuzz-exec] calling test5
+ ;; CHECK-NEXT: [trap out of bounds memory access in memory.fill]
+ (func $test5 (export "test5")
+ (memory.fill (i32.const 0x10001) (i32.const 0) (i32.const 0))
+ ;; should not be reached
+ (call $print_memory (i32.const 0) (i32.const 6))
+ )
+ ;; again we do not test negative/overflowing addresses as the spec test does.
+)
+;; CHECK: [fuzz-exec] calling test1
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 1]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 2]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 3]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 4]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 1]
+;; CHECK-NEXT: [LoggingExternalInterface logging 255]
+;; CHECK-NEXT: [LoggingExternalInterface logging 2]
+;; CHECK-NEXT: [LoggingExternalInterface logging 255]
+;; CHECK-NEXT: [LoggingExternalInterface logging 3]
+;; CHECK-NEXT: [LoggingExternalInterface logging 255]
+;; CHECK-NEXT: [LoggingExternalInterface logging 4]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+
+;; CHECK: [fuzz-exec] calling test2
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 170]
+;; CHECK-NEXT: [LoggingExternalInterface logging 1]
+;; CHECK-NEXT: [LoggingExternalInterface logging 170]
+
+;; CHECK: [fuzz-exec] calling test3
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 1]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 2]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 3]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 4]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 5]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+
+;; CHECK: [fuzz-exec] calling test4
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 1]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 2]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 3]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 4]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 5]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+;; CHECK-NEXT: [LoggingExternalInterface logging 6]
+;; CHECK-NEXT: [LoggingExternalInterface logging 0]
+
+;; CHECK: [fuzz-exec] calling test5
+;; CHECK-NEXT: [trap unreachable]
+;; CHECK-NEXT: [fuzz-exec] comparing test1
+;; CHECK-NEXT: [fuzz-exec] comparing test2
+;; CHECK-NEXT: [fuzz-exec] comparing test3
+;; CHECK-NEXT: [fuzz-exec] comparing test4
+;; CHECK-NEXT: [fuzz-exec] comparing test5
diff --git a/test/lit/help/wasm-metadce.test b/test/lit/help/wasm-metadce.test
index 50295b1f0..908b381e8 100644
--- a/test/lit/help/wasm-metadce.test
+++ b/test/lit/help/wasm-metadce.test
@@ -239,6 +239,10 @@
;; CHECK-NEXT: --log-execution instrument the build with
;; CHECK-NEXT: logging of where execution goes
;; CHECK-NEXT:
+;; CHECK-NEXT: --memory-copy-fill-lowering Lower memory.copy and
+;; CHECK-NEXT: memory.fill to wasm mvp and
+;; CHECK-NEXT: disable the bulk-memory feature.
+;; CHECK-NEXT:
;; CHECK-NEXT: --memory-packing packs memory into separate
;; CHECK-NEXT: segments, skipping zeros
;; CHECK-NEXT:
diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test
index 0691d1c18..7d173b084 100644
--- a/test/lit/help/wasm-opt.test
+++ b/test/lit/help/wasm-opt.test
@@ -248,6 +248,10 @@
;; CHECK-NEXT: --log-execution instrument the build with
;; CHECK-NEXT: logging of where execution goes
;; CHECK-NEXT:
+;; CHECK-NEXT: --memory-copy-fill-lowering Lower memory.copy and
+;; CHECK-NEXT: memory.fill to wasm mvp and
+;; CHECK-NEXT: disable the bulk-memory feature.
+;; CHECK-NEXT:
;; CHECK-NEXT: --memory-packing packs memory into separate
;; CHECK-NEXT: segments, skipping zeros
;; CHECK-NEXT:
diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test
index 89dcaa028..514f638d9 100644
--- a/test/lit/help/wasm2js.test
+++ b/test/lit/help/wasm2js.test
@@ -202,6 +202,10 @@
;; CHECK-NEXT: --log-execution instrument the build with
;; CHECK-NEXT: logging of where execution goes
;; CHECK-NEXT:
+;; CHECK-NEXT: --memory-copy-fill-lowering Lower memory.copy and
+;; CHECK-NEXT: memory.fill to wasm mvp and
+;; CHECK-NEXT: disable the bulk-memory feature.
+;; CHECK-NEXT:
;; CHECK-NEXT: --memory-packing packs memory into separate
;; CHECK-NEXT: segments, skipping zeros
;; CHECK-NEXT:
diff --git a/test/lit/passes/memory-copy-fill-lowering.wast b/test/lit/passes/memory-copy-fill-lowering.wast
new file mode 100644
index 000000000..540237ff7
--- /dev/null
+++ b/test/lit/passes/memory-copy-fill-lowering.wast
@@ -0,0 +1,168 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+
+;; RUN: wasm-opt --enable-bulk-memory %s --memory-copy-fill-lowering -S -o - | filecheck %s
+
+(module
+ (memory 0)
+ ;; CHECK: (type $0 (func (param i32 i32 i32)))
+
+ ;; CHECK: (memory $0 0)
+
+ ;; CHECK: (func $memcpy (param $dst i32) (param $src i32) (param $size i32)
+ ;; CHECK-NEXT: (call $__memory_copy
+ ;; CHECK-NEXT: (local.get $dst)
+ ;; CHECK-NEXT: (local.get $src)
+ ;; CHECK-NEXT: (local.get $size)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $memcpy (param $dst i32) (param $src i32) (param $size i32)
+ (memory.copy (local.get $dst) (local.get $src) (local.get $size))
+ )
+ ;; CHECK: (func $memfill (param $dst i32) (param $val i32) (param $size i32)
+ ;; CHECK-NEXT: (call $__memory_fill
+ ;; CHECK-NEXT: (local.get $dst)
+ ;; CHECK-NEXT: (local.get $val)
+ ;; CHECK-NEXT: (local.get $size)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $memfill (param $dst i32) (param $val i32) (param $size i32)
+ (memory.fill (local.get $dst) (local.get $val) (local.get $size))
+ )
+)
+;; CHECK: (func $__memory_copy (param $dst i32) (param $src i32) (param $size i32)
+;; CHECK-NEXT: (local $start i32)
+;; CHECK-NEXT: (local $end i32)
+;; CHECK-NEXT: (local $step i32)
+;; CHECK-NEXT: (local $i i32)
+;; CHECK-NEXT: (local.set $end
+;; CHECK-NEXT: (i32.mul
+;; CHECK-NEXT: (memory.size)
+;; CHECK-NEXT: (i32.const 65536)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.or
+;; CHECK-NEXT: (i32.gt_u
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (local.get $dst)
+;; CHECK-NEXT: (local.get $size)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $end)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.gt_u
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (local.get $src)
+;; CHECK-NEXT: (local.get $size)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $end)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (then
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.lt_u
+;; CHECK-NEXT: (local.get $src)
+;; CHECK-NEXT: (local.get $dst)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (then
+;; CHECK-NEXT: (local.set $start
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (local.get $size)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $end
+;; CHECK-NEXT: (i32.const -1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $step
+;; CHECK-NEXT: (i32.const -1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (else
+;; CHECK-NEXT: (local.set $start
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $end
+;; CHECK-NEXT: (local.get $size)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $step
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $i
+;; CHECK-NEXT: (local.get $start)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $out
+;; CHECK-NEXT: (loop $copy
+;; CHECK-NEXT: (br_if $out
+;; CHECK-NEXT: (i32.eq
+;; CHECK-NEXT: (local.get $i)
+;; CHECK-NEXT: (local.get $end)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store8
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (local.get $dst)
+;; CHECK-NEXT: (local.get $i)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (local.get $src)
+;; CHECK-NEXT: (local.get $i)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $i
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (local.get $i)
+;; CHECK-NEXT: (local.get $step)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br $copy)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+
+;; CHECK: (func $__memory_fill (param $dst i32) (param $val i32) (param $size i32)
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.gt_u
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (local.get $dst)
+;; CHECK-NEXT: (local.get $size)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.mul
+;; CHECK-NEXT: (memory.size)
+;; CHECK-NEXT: (i32.const 65536)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (then
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $out
+;; CHECK-NEXT: (loop $copy
+;; CHECK-NEXT: (br_if $out
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (local.get $size)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $size
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (local.get $size)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store8
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (local.get $dst)
+;; CHECK-NEXT: (local.get $size)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $val)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br $copy)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )