Change tests
diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index 19052a4..033e1ec 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt
@@ -17,6 +17,7 @@ disjoint_sets.cpp dwarf-ranges.cpp effects.cpp + gc-type-utils.cpp glbs.cpp graph.cpp inplace_vector.cpp
diff --git a/test/gtest/cast-check.cpp b/test/gtest/cast-check.cpp index 377ec2e..6164f4f 100644 --- a/test/gtest/cast-check.cpp +++ b/test/gtest/cast-check.cpp
@@ -212,14 +212,12 @@ TEST_F(CastCheckTest, CastFromWaitqueue) { // Casting from unshared waitqueue or nowaitqueue is always unreachable. for (auto nullability : {Nullable, NonNullable}) { - EXPECT_EQ( - evaluateCastCheck(Type(HeapType::waitqueue, nullability), - Type(HeapType::waitqueue, Nullable)), - GCTypeUtils::Unreachable); - EXPECT_EQ( - evaluateCastCheck(Type(HeapType::nowaitqueue, nullability), - Type(HeapType::waitqueue, Nullable)), - GCTypeUtils::Unreachable); + EXPECT_EQ(evaluateCastCheck(Type(HeapType::waitqueue, nullability), + Type(HeapType::waitqueue, Nullable)), + GCTypeUtils::Unreachable); + EXPECT_EQ(evaluateCastCheck(Type(HeapType::nowaitqueue, nullability), + Type(HeapType::waitqueue, Nullable)), + GCTypeUtils::Unreachable); } // Casting between shared waitqueue types behaves normally. @@ -255,59 +253,4 @@ Failure); } -TEST(GCTypeUtilsTest, IsTriviallyUninhabitable) { - // Non-nullable bottom types are trivially uninhabitable. - EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::none, NonNullable))); - EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::nofunc, NonNullable))); - EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::noext, NonNullable))); - EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::nocont, NonNullable))); - EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::noexn, NonNullable))); - EXPECT_TRUE( - isTriviallyUninhabitable(Type(HeapTypes::sharedNowaitqueue, NonNullable))); - - // Nullable bottom types are inhabitable (via null). - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::none, Nullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::nofunc, Nullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::noext, Nullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::nocont, Nullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::noexn, Nullable))); - EXPECT_FALSE( - isTriviallyUninhabitable(Type(HeapTypes::sharedNowaitqueue, Nullable))); - - // Unshared waitqueue and nowaitqueue are uninhabitable regardless of nullability. - EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::waitqueue, Nullable))); - EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::waitqueue, NonNullable))); - EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::nowaitqueue, Nullable))); - EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::nowaitqueue, NonNullable))); - - // Shared waitqueue is inhabitable. - EXPECT_FALSE( - isTriviallyUninhabitable(Type(HeapTypes::sharedWaitqueue, Nullable))); - EXPECT_FALSE( - isTriviallyUninhabitable(Type(HeapTypes::sharedWaitqueue, NonNullable))); - - // Common types are inhabitable. - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::any, Nullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::any, NonNullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::func, Nullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::func, NonNullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::eq, Nullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::eq, NonNullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::i31, Nullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::i31, NonNullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::struct_, Nullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::struct_, NonNullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::array, Nullable))); - EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::array, NonNullable))); - - // Non-reference types and non-values. - EXPECT_FALSE(isTriviallyUninhabitable(Type::i32)); - EXPECT_FALSE(isTriviallyUninhabitable(Type::i64)); - EXPECT_FALSE(isTriviallyUninhabitable(Type::f32)); - EXPECT_FALSE(isTriviallyUninhabitable(Type::f64)); - EXPECT_FALSE(isTriviallyUninhabitable(Type::v128)); - EXPECT_FALSE(isTriviallyUninhabitable(Type::none)); - EXPECT_TRUE(isTriviallyUninhabitable(Type::unreachable)); -} - } // namespace wasm
diff --git a/test/gtest/gc-type-utils.cpp b/test/gtest/gc-type-utils.cpp new file mode 100644 index 0000000..021c582 --- /dev/null +++ b/test/gtest/gc-type-utils.cpp
@@ -0,0 +1,82 @@ +/* + * Copyright 2026 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ir/gc-type-utils.h" +#include "wasm-type.h" +#include "gtest/gtest.h" + +namespace wasm { + +using namespace GCTypeUtils; + +TEST(GCTypeUtilsTest, IsTriviallyUninhabitable) { + // Non-nullable bottom types are trivially uninhabitable. + EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::none, NonNullable))); + EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::nofunc, NonNullable))); + EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::noext, NonNullable))); + EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::nocont, NonNullable))); + EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::noexn, NonNullable))); + EXPECT_TRUE( + isTriviallyUninhabitable(Type(HeapTypes::sharedNowaitqueue, NonNullable))); + + // Nullable bottom types are inhabitable (via null). + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::none, Nullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::nofunc, Nullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::noext, Nullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::nocont, Nullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::noexn, Nullable))); + EXPECT_FALSE( + isTriviallyUninhabitable(Type(HeapTypes::sharedNowaitqueue, Nullable))); + + // Unshared waitqueue and nowaitqueue are uninhabitable regardless of + // nullability. + EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::waitqueue, Nullable))); + EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::waitqueue, NonNullable))); + EXPECT_TRUE(isTriviallyUninhabitable(Type(HeapType::nowaitqueue, Nullable))); + EXPECT_TRUE( + isTriviallyUninhabitable(Type(HeapType::nowaitqueue, NonNullable))); + + // Shared waitqueue is inhabitable. + EXPECT_FALSE( + isTriviallyUninhabitable(Type(HeapTypes::sharedWaitqueue, Nullable))); + EXPECT_FALSE( + isTriviallyUninhabitable(Type(HeapTypes::sharedWaitqueue, NonNullable))); + + // Common types are inhabitable. + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::any, Nullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::any, NonNullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::func, Nullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::func, NonNullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::eq, Nullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::eq, NonNullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::i31, Nullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::i31, NonNullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::struct_, Nullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::struct_, NonNullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::array, Nullable))); + EXPECT_FALSE(isTriviallyUninhabitable(Type(HeapType::array, NonNullable))); + + // Non-reference types and non-values. + EXPECT_FALSE(isTriviallyUninhabitable(Type::i32)); + EXPECT_FALSE(isTriviallyUninhabitable(Type::i64)); + EXPECT_FALSE(isTriviallyUninhabitable(Type::f32)); + EXPECT_FALSE(isTriviallyUninhabitable(Type::f64)); + EXPECT_FALSE(isTriviallyUninhabitable(Type::v128)); + EXPECT_FALSE(isTriviallyUninhabitable(Type::none)); + EXPECT_TRUE(isTriviallyUninhabitable(Type::unreachable)); +} + +} // namespace wasm
diff --git a/test/lit/passes/dae-optimizing.wast b/test/lit/passes/dae-optimizing.wast index 8635032..5ec9ade 100644 --- a/test/lit/passes/dae-optimizing.wast +++ b/test/lit/passes/dae-optimizing.wast
@@ -171,7 +171,7 @@ ) ;; Test that unshared waitqueue results are treated as uninhabitable (callers -;; become unreachable), while shared waitqueue results are inhabitable. +;; become unreachable). (module (func $import (import "" "") (result i32)) (func $impossible (import "" "") (result (ref waitqueue))) @@ -220,53 +220,3 @@ (call $impossible) ) ) - -(module - (func $import (import "" "") (result i32)) - (func $possible (import "" "") (result (ref (shared waitqueue)))) - - ;; CHECK: (type $0 (func (result i32))) - - ;; CHECK: (type $1 (func (result (ref (shared waitqueue))))) - - ;; CHECK: (type $2 (func)) - - ;; CHECK: (import "" "" (func $import (type $0) (result i32))) - - ;; CHECK: (import "" "" (func $possible (type $1) (result (ref (shared waitqueue))))) - - ;; CHECK: (export "export" (func $export)) - - ;; CHECK: (func $export (type $0) (result i32) - ;; CHECK-NEXT: (call $internal) - ;; CHECK-NEXT: (call $internal) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - (func $export (export "export") (result i32) - (drop - (call $internal - (i32.const 0) - ) - ) - (drop - (call $internal - (i32.const 1) - ) - ) - (i32.const 0) - ) - ;; CHECK: (func $internal (type $2) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $import) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $possible) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $internal (param i32) (result (ref (shared waitqueue))) - (drop - (call $import) - ) - (call $possible) - ) -)
diff --git a/test/lit/passes/optimize-instructions-waitqueue.wast b/test/lit/passes/optimize-instructions-waitqueue.wast index 78518c4..4b385a1 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 $2) (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 $1) (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) @@ -84,21 +84,4 @@ (func $test-unshared (param $wq (ref waitqueue)) (result i32) (ref.test (ref nowaitqueue) (local.get $wq)) ) - - ;; CHECK: (func $cast-shared (type $5) (param $wq (ref (shared waitqueue))) (result (ref (shared waitqueue))) - ;; CHECK-NEXT: (local.get $wq) - ;; CHECK-NEXT: ) - (func $cast-shared (param $wq (ref (shared waitqueue))) (result (ref (shared waitqueue))) - (ref.cast (ref (shared waitqueue)) (local.get $wq)) - ) - - ;; CHECK: (func $test-shared (type $1) (param $wq (ref (shared waitqueue))) (result i32) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $wq) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - (func $test-shared (param $wq (ref (shared waitqueue))) (result i32) - (ref.test (ref (shared waitqueue)) (local.get $wq)) - ) )