diff --git a/src/ir/child-typer.h b/src/ir/child-typer.h index 089b21f86e0..5a374f89b8e 100644 --- a/src/ir/child-typer.h +++ b/src/ir/child-typer.h @@ -1249,8 +1249,11 @@ template struct ChildTyper : OverriddenVisitor { Type type = ht->getArray().element.type; note(&curr->ref, Type(*ht, Nullable)); note(&curr->index, Type::i32); - // TODO: (shared eq) as appropriate. - note(&curr->expected, type.isRef() ? Type(HeapType::eq, Nullable) : type); + note( + &curr->expected, + type.isRef() + ? Type(HeapTypes::eq.getBasic(type.getHeapType().getShared()), Nullable) + : type); note(&curr->replacement, type); } diff --git a/test/lit/basic/gc-atomics-shared.wast b/test/lit/basic/gc-atomics-shared.wast new file mode 100644 index 00000000000..818239c1569 --- /dev/null +++ b/test/lit/basic/gc-atomics-shared.wast @@ -0,0 +1,55 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + +;; RUN: wasm-opt -all %s -S -o - | filecheck %s + +;; Check that we properly parse array.atomic.rmw.cmpxchg of a shared array, +;; when the instruction is unreachable (when the the expected field does not +;; have the correct sharedness). + +(module + ;; CHECK: (type $array (shared (array (mut (ref null (shared eq)))))) + (type $array (shared (array (mut (ref null (shared eq)))))) + + ;; CHECK: (global $g (ref $array) (array.new_default $array + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: )) + (global $g (ref $array) (array.new_default $array (i32.const 0))) + + ;; CHECK: (func $test (type $1) (result (ref null (shared eq))) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $g) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block ;; (replaces unreachable ArrayCmpxchg we can't emit) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (result (ref null (shared eq))) + (array.atomic.rmw.cmpxchg acqrel acqrel $array + (global.get $g) + (i32.const 0) + (ref.as_non_null (ref.null none)) + (unreachable) + ) + ) +) +