From 7a5b0cac145fe6480542188061caf3247fc6a638 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 17 Sep 2026 09:53:47 -0700 Subject: [PATCH 1/7] Add missing isGenerative data, and one test --- src/ir/properties.cpp | 18 +++++++++-- .../passes/optimize-instructions-atomics.wast | 30 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/ir/properties.cpp b/src/ir/properties.cpp index 535f50dace4..a3dc9c45dc9 100644 --- a/src/ir/properties.cpp +++ b/src/ir/properties.cpp @@ -47,9 +47,23 @@ struct GenerativityScanner : public PostWalker { void visitArrayNewElem(ArrayNewElem* curr) { generative = true; } void visitArrayNewFixed(ArrayNewFixed* curr) { generative = true; } void visitContNew(ContNew* curr) { generative = true; } + + // Notifications/waits depend on events on other threads. + void visitAtomicNotify(AtomicNotify* curr) { generative = true; } + void visitWaitqueueNotify(WaitqueueNotify* curr) { generative = true; } + void visitAtomicWait(AtomicWait* curr) { generative = true; } + void visitStructWait(StructWait* curr) { generative = true; } void visitWaitqueueNew(WaitqueueNew* curr) { generative = true; } - // TODO: waitqueue.notify, struct.wait, atomic.notify, and atomic.wait should - // also be generative. + + // Instructions that both read and write memory are generative (as they + // themselves can lead to a different value being returned from identical- + // looking instructions; no other instruction in the middle is needed). + void visitAtomicRMW(AtomicRMW* curr) { generative = true; } + void visitAtomicCmpxchg(AtomicCmpxchg* curr) { generative = true; } + void visitStructRMW(StructRMW* curr) { generative = true; } + void visitStructCmpxchg(StructCmpxchg* curr) { generative = true; } + void visitArrayRMW(ArrayRMW* curr) { generative = true; } + void visitArrayCmpxchg(ArrayCmpxchg* curr) { generative = true; } }; } // anonymous namespace diff --git a/test/lit/passes/optimize-instructions-atomics.wast b/test/lit/passes/optimize-instructions-atomics.wast index e59c6a4e79b..07662a5e73b 100644 --- a/test/lit/passes/optimize-instructions-atomics.wast +++ b/test/lit/passes/optimize-instructions-atomics.wast @@ -91,4 +91,34 @@ ;; skips (drop (i64.extend_i32_s (i32.atomic.load (local.get $x)))) ) + + ;; CHECK: (func $select-atomic-rmw (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.atomic.rmw16.xchg_u + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.atomic.rmw16.xchg_u + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-atomic-rmw (result i32) + ;; The first rmw here influences the second, and we need to return the result + ;; of the first, which means we need a temp local. We avoid adding one and do + ;; not optimize here. + (select + (i32.atomic.rmw16.xchg_u + (i32.const 0) + (i32.const 1) + ) + (i32.atomic.rmw16.xchg_u + (i32.const 0) + (i32.const 1) + ) + (i32.const 1) + ) + ) ) From 804e297f2b9a62972508c011dbd1649f45994c69 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 17 Sep 2026 11:21:42 -0700 Subject: [PATCH 2/7] tests --- .../passes/optimize-instructions-atomics.wast | 89 ++++++++ .../optimize-instructions-gc-atomics.wast | 191 +++++++++++++++++- 2 files changed, 278 insertions(+), 2 deletions(-) diff --git a/test/lit/passes/optimize-instructions-atomics.wast b/test/lit/passes/optimize-instructions-atomics.wast index 07662a5e73b..679d6c5793f 100644 --- a/test/lit/passes/optimize-instructions-atomics.wast +++ b/test/lit/passes/optimize-instructions-atomics.wast @@ -121,4 +121,93 @@ (i32.const 1) ) ) + + ;; CHECK: (func $select-atomic-cmpxchg (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.atomic.rmw.cmpxchg + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.atomic.rmw.cmpxchg + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-atomic-cmpxchg (result i32) + (select + (i32.atomic.rmw.cmpxchg + (i32.const 0) + (i32.const 1) + (i32.const 2) + ) + (i32.atomic.rmw.cmpxchg + (i32.const 0) + (i32.const 1) + (i32.const 2) + ) + (i32.const 1) + ) + ) + + ;; CHECK: (func $select-atomic-wait (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (memory.atomic.wait32 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.atomic.wait32 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-atomic-wait (result i32) + (select + (memory.atomic.wait32 + (i32.const 0) + (i32.const 1) + (i64.const 2) + ) + (memory.atomic.wait32 + (i32.const 0) + (i32.const 1) + (i64.const 2) + ) + (i32.const 1) + ) + ) + + ;; CHECK: (func $select-atomic-notify (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (memory.atomic.notify + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.atomic.notify + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-atomic-notify (result i32) + (select + (memory.atomic.notify + (i32.const 0) + (i32.const 1) + ) + (memory.atomic.notify + (i32.const 0) + (i32.const 1) + ) + (i32.const 1) + ) + ) ) diff --git a/test/lit/passes/optimize-instructions-gc-atomics.wast b/test/lit/passes/optimize-instructions-gc-atomics.wast index a0283390c9a..526e5bad4f3 100644 --- a/test/lit/passes/optimize-instructions-gc-atomics.wast +++ b/test/lit/passes/optimize-instructions-gc-atomics.wast @@ -3,11 +3,12 @@ ;; RUN: wasm-opt %s -all --optimize-instructions -S -o - | filecheck %s (module - ;; CHECK: (type $unshared (struct (field (mut i32)))) - ;; CHECK: (type $shared (shared (struct (field (mut i32))))) (type $shared (shared (struct (field (mut i32))))) + ;; CHECK: (type $unshared (struct (field (mut i32)))) (type $unshared (struct (field (mut i32)))) + ;; CHECK: (type $array (shared (array (mut i32)))) + (type $array (shared (array (mut i32)))) ;; CHECK: (func $get-unordered-unshared (type $2) (result i32) ;; CHECK-NEXT: (struct.get $unshared 0 @@ -154,4 +155,190 @@ (i32.const 0) ) ) + + ;; CHECK: (func $select-struct-rmw (type $4) (param $x (ref $shared)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (struct.atomic.rmw.add $shared 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (struct.atomic.rmw.add $shared 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-struct-rmw (param $x (ref $shared)) (result i32) + (select + (struct.atomic.rmw.add $shared 0 + (local.get $x) + (i32.const 1) + ) + (struct.atomic.rmw.add $shared 0 + (local.get $x) + (i32.const 1) + ) + (i32.const 1) + ) + ) + + ;; CHECK: (func $select-struct-cmpxchg (type $4) (param $x (ref $shared)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (struct.atomic.rmw.cmpxchg $shared 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (struct.atomic.rmw.cmpxchg $shared 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-struct-cmpxchg (param $x (ref $shared)) (result i32) + (select + (struct.atomic.rmw.cmpxchg $shared 0 + (local.get $x) + (i32.const 1) + (i32.const 2) + ) + (struct.atomic.rmw.cmpxchg $shared 0 + (local.get $x) + (i32.const 1) + (i32.const 2) + ) + (i32.const 1) + ) + ) + + ;; CHECK: (func $select-array-rmw (type $6) (param $x (ref $array)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (array.atomic.rmw.add $array + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (array.atomic.rmw.add $array + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-array-rmw (param $x (ref $array)) (result i32) + (select + (array.atomic.rmw.add $array + (local.get $x) + (i32.const 0) + (i32.const 1) + ) + (array.atomic.rmw.add $array + (local.get $x) + (i32.const 0) + (i32.const 1) + ) + (i32.const 1) + ) + ) + + ;; CHECK: (func $select-array-cmpxchg (type $6) (param $x (ref $array)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (array.atomic.rmw.cmpxchg $array + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (array.atomic.rmw.cmpxchg $array + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-array-cmpxchg (param $x (ref $array)) (result i32) + (select + (array.atomic.rmw.cmpxchg $array + (local.get $x) + (i32.const 0) + (i32.const 1) + (i32.const 2) + ) + (array.atomic.rmw.cmpxchg $array + (local.get $x) + (i32.const 0) + (i32.const 1) + (i32.const 2) + ) + (i32.const 1) + ) + ) + + ;; CHECK: (func $select-struct-wait (type $7) (param $x (ref $shared)) (param $wq (ref (shared waitqueue))) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (struct.wait $shared 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $wq) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (struct.wait $shared 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $wq) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-struct-wait (param $x (ref $shared)) (param $wq (ref (shared waitqueue))) (result i32) + (select + (struct.wait $shared 0 + (local.get $x) + (local.get $wq) + (i32.const 0) + (i64.const -1) + ) + (struct.wait $shared 0 + (local.get $x) + (local.get $wq) + (i32.const 0) + (i64.const -1) + ) + (i32.const 1) + ) + ) + + ;; CHECK: (func $select-waitqueue-notify (type $8) (param $wq (ref (shared waitqueue))) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (waitqueue.notify + ;; CHECK-NEXT: (local.get $wq) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (waitqueue.notify + ;; CHECK-NEXT: (local.get $wq) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-waitqueue-notify (param $wq (ref (shared waitqueue))) (result i32) + (select + (waitqueue.notify + (local.get $wq) + (i32.const 1) + ) + (waitqueue.notify + (local.get $wq) + (i32.const 1) + ) + (i32.const 1) + ) + ) ) From e330965f8e2a2f3eb713f9d0f340c82a2bd00258 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 17 Sep 2026 11:22:42 -0700 Subject: [PATCH 3/7] more --- .../passes/optimize-instructions-atomics.wast | 16 +++++++++++++++- .../passes/optimize-instructions-gc-atomics.wast | 3 +++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/test/lit/passes/optimize-instructions-atomics.wast b/test/lit/passes/optimize-instructions-atomics.wast index 679d6c5793f..41d631daa7f 100644 --- a/test/lit/passes/optimize-instructions-atomics.wast +++ b/test/lit/passes/optimize-instructions-atomics.wast @@ -108,7 +108,7 @@ (func $select-atomic-rmw (result i32) ;; The first rmw here influences the second, and we need to return the result ;; of the first, which means we need a temp local. We avoid adding one and do - ;; not optimize here. + ;; not optimize here. Other instructions are tested in the functions below. (select (i32.atomic.rmw16.xchg_u (i32.const 0) @@ -210,4 +210,18 @@ (i32.const 1) ) ) + + (func $select-atomic-notify (result i32) + ;; For comparison with above, when the instruction is not generative, we can + ;; optimize. + (select + (i32.load + (i32.const 0) + ) + (i32.load + (i32.const 0) + ) + (i32.const 1) + ) + ) ) diff --git a/test/lit/passes/optimize-instructions-gc-atomics.wast b/test/lit/passes/optimize-instructions-gc-atomics.wast index 526e5bad4f3..a84fffe61f3 100644 --- a/test/lit/passes/optimize-instructions-gc-atomics.wast +++ b/test/lit/passes/optimize-instructions-gc-atomics.wast @@ -170,6 +170,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $select-struct-rmw (param $x (ref $shared)) (result i32) + ;; The first rmw here influences the second, and we need to return the result + ;; of the first, which means we need a temp local. We avoid adding one and do + ;; not optimize here. Other instructions are tested in the functions below. (select (struct.atomic.rmw.add $shared 0 (local.get $x) From 971ee4b8a1c3bda84b51c7c18e1fc49019163a22 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 17 Sep 2026 11:25:36 -0700 Subject: [PATCH 4/7] more --- .../passes/optimize-instructions-atomics.wast | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/test/lit/passes/optimize-instructions-atomics.wast b/test/lit/passes/optimize-instructions-atomics.wast index 41d631daa7f..63dd8c1bee6 100644 --- a/test/lit/passes/optimize-instructions-atomics.wast +++ b/test/lit/passes/optimize-instructions-atomics.wast @@ -211,14 +211,29 @@ ) ) - (func $select-atomic-notify (result i32) + ;; CHECK: (func $select-atomic-load (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.atomic.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.atomic.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-atomic-load (result i32) ;; For comparison with above, when the instruction is not generative, we can - ;; optimize. + ;; optimize: the two atomic loads must return the same thing, so we drop the + ;; first and return the second (even though the first is what is actually + ;; returned. (select - (i32.load + (i32.atomic.load (i32.const 0) ) - (i32.load + (i32.atomic.load (i32.const 0) ) (i32.const 1) From bf2e4720199dfeb37860ec5d775b04cc21a2ed9b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 17 Sep 2026 11:27:13 -0700 Subject: [PATCH 5/7] more --- test/lit/passes/optimize-instructions-atomics.wast | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lit/passes/optimize-instructions-atomics.wast b/test/lit/passes/optimize-instructions-atomics.wast index 63dd8c1bee6..3086fe26896 100644 --- a/test/lit/passes/optimize-instructions-atomics.wast +++ b/test/lit/passes/optimize-instructions-atomics.wast @@ -227,8 +227,8 @@ (func $select-atomic-load (result i32) ;; For comparison with above, when the instruction is not generative, we can ;; optimize: the two atomic loads must return the same thing, so we drop the - ;; first and return the second (even though the first is what is actually - ;; returned. + ;; first and return the second (even though the first is what the select + ;; returns). (select (i32.atomic.load (i32.const 0) From 9a61e8e55ed72c020848e9b02fff76d12a3bafaa Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 17 Sep 2026 13:19:58 -0700 Subject: [PATCH 6/7] avoid fuzzing waitqueue --- scripts/test/fuzzing.py | 1 + .../optimize-instructions-gc-atomics.wast | 62 ---------------- .../optimize-instructions-waitqueue.wast | 70 +++++++++++++++++++ 3 files changed, 71 insertions(+), 62 deletions(-) create mode 100644 test/lit/passes/optimize-instructions-waitqueue.wast diff --git a/scripts/test/fuzzing.py b/scripts/test/fuzzing.py index 0a4fa6f7d76..a091689f7e2 100644 --- a/scripts/test/fuzzing.py +++ b/scripts/test/fuzzing.py @@ -117,6 +117,7 @@ # Not fully implemented. 'waitqueue.wast', 'gufa-waitqueue.wast', + 'optimize-instructions-waitqueue.wast', 'publish.wast', 'optimize-instructions-publish.wast', # TODO: fix handling of the non-utf8 names here diff --git a/test/lit/passes/optimize-instructions-gc-atomics.wast b/test/lit/passes/optimize-instructions-gc-atomics.wast index a84fffe61f3..c9d878010bd 100644 --- a/test/lit/passes/optimize-instructions-gc-atomics.wast +++ b/test/lit/passes/optimize-instructions-gc-atomics.wast @@ -282,66 +282,4 @@ (i32.const 1) ) ) - - ;; CHECK: (func $select-struct-wait (type $7) (param $x (ref $shared)) (param $wq (ref (shared waitqueue))) (result i32) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (struct.wait $shared 0 - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $wq) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i64.const -1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (struct.wait $shared 0 - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $wq) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i64.const -1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $select-struct-wait (param $x (ref $shared)) (param $wq (ref (shared waitqueue))) (result i32) - (select - (struct.wait $shared 0 - (local.get $x) - (local.get $wq) - (i32.const 0) - (i64.const -1) - ) - (struct.wait $shared 0 - (local.get $x) - (local.get $wq) - (i32.const 0) - (i64.const -1) - ) - (i32.const 1) - ) - ) - - ;; CHECK: (func $select-waitqueue-notify (type $8) (param $wq (ref (shared waitqueue))) (result i32) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (waitqueue.notify - ;; CHECK-NEXT: (local.get $wq) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (waitqueue.notify - ;; CHECK-NEXT: (local.get $wq) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $select-waitqueue-notify (param $wq (ref (shared waitqueue))) (result i32) - (select - (waitqueue.notify - (local.get $wq) - (i32.const 1) - ) - (waitqueue.notify - (local.get $wq) - (i32.const 1) - ) - (i32.const 1) - ) - ) ) diff --git a/test/lit/passes/optimize-instructions-waitqueue.wast b/test/lit/passes/optimize-instructions-waitqueue.wast new file mode 100644 index 00000000000..90031cdd624 --- /dev/null +++ b/test/lit/passes/optimize-instructions-waitqueue.wast @@ -0,0 +1,70 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + +;; RUN: wasm-opt %s -all --optimize-instructions -S -o - | filecheck %s + +(module + ;; CHECK: (type $shared (shared (struct (field (mut i32))))) + (type $shared (shared (struct (field (mut i32))))) + + ;; CHECK: (func $select-struct-wait (type $7) (param $x (ref $shared)) (param $wq (ref (shared waitqueue))) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (struct.wait $shared 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $wq) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (struct.wait $shared 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $wq) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-struct-wait (param $x (ref $shared)) (param $wq (ref (shared waitqueue))) (result i32) + (select + (struct.wait $shared 0 + (local.get $x) + (local.get $wq) + (i32.const 0) + (i64.const -1) + ) + (struct.wait $shared 0 + (local.get $x) + (local.get $wq) + (i32.const 0) + (i64.const -1) + ) + (i32.const 1) + ) + ) + + ;; CHECK: (func $select-waitqueue-notify (type $8) (param $wq (ref (shared waitqueue))) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (waitqueue.notify + ;; CHECK-NEXT: (local.get $wq) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (waitqueue.notify + ;; CHECK-NEXT: (local.get $wq) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-waitqueue-notify (param $wq (ref (shared waitqueue))) (result i32) + (select + (waitqueue.notify + (local.get $wq) + (i32.const 1) + ) + (waitqueue.notify + (local.get $wq) + (i32.const 1) + ) + (i32.const 1) + ) + ) +) From bb62520a4b7779e9959681187497592d9a999dc1 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 17 Sep 2026 13:21:43 -0700 Subject: [PATCH 7/7] fix --- test/lit/passes/optimize-instructions-waitqueue.wast | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lit/passes/optimize-instructions-waitqueue.wast b/test/lit/passes/optimize-instructions-waitqueue.wast index 90031cdd624..8abe1860daa 100644 --- a/test/lit/passes/optimize-instructions-waitqueue.wast +++ b/test/lit/passes/optimize-instructions-waitqueue.wast @@ -6,7 +6,7 @@ ;; CHECK: (type $shared (shared (struct (field (mut i32))))) (type $shared (shared (struct (field (mut i32))))) - ;; CHECK: (func $select-struct-wait (type $7) (param $x (ref $shared)) (param $wq (ref (shared waitqueue))) (result i32) + ;; CHECK: (func $select-struct-wait (type $1) (param $x (ref $shared)) (param $wq (ref (shared waitqueue))) (result i32) ;; CHECK-NEXT: (select ;; CHECK-NEXT: (struct.wait $shared 0 ;; CHECK-NEXT: (local.get $x) @@ -41,7 +41,7 @@ ) ) - ;; CHECK: (func $select-waitqueue-notify (type $8) (param $wq (ref (shared waitqueue))) (result i32) + ;; CHECK: (func $select-waitqueue-notify (type $2) (param $wq (ref (shared waitqueue))) (result i32) ;; CHECK-NEXT: (select ;; CHECK-NEXT: (waitqueue.notify ;; CHECK-NEXT: (local.get $wq)