From 36180d355d2ad4a6bf7a2089e8445f06f2c9414f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 2 Oct 2025 11:59:02 -0700 Subject: [PATCH 1/3] fix --- src/passes/DeadArgumentElimination.cpp | 22 +++++++++++++++++++++ test/lit/passes/dae-gc-no-cd.wast | 27 ++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/passes/DeadArgumentElimination.cpp b/src/passes/DeadArgumentElimination.cpp index b31588e2e80..f82c7f4ef7f 100644 --- a/src/passes/DeadArgumentElimination.cpp +++ b/src/passes/DeadArgumentElimination.cpp @@ -609,6 +609,25 @@ struct DAE : public Pass { } } + // We also must not make private types public. That could be a problem + // without custom descriptors (private exact types are ok - they are lowered + // away - but not publicones), and also in general, making more things + // public has downsides to later opts, that this one doesn't justify. + if (isExported) { + if (!privateTypes) { + privateTypes.emplace(); + for (auto type : ModuleUtils::getPrivateHeapTypes(*module)) { + privateTypes->insert(type); + } + } + + for (auto t : newType) { + if (t.isRef() && privateTypes->count(t.getHeapType())) { + return false; + } + } + } + if (!isExported) { func->setResults(newType); } else { @@ -632,6 +651,9 @@ struct DAE : public Pass { return true; } + + // Created on first use. + std::optional> privateTypes; }; Pass* createDAEPass() { return new DAE(); } diff --git a/test/lit/passes/dae-gc-no-cd.wast b/test/lit/passes/dae-gc-no-cd.wast index f5c4064f0f2..12e71fa8315 100644 --- a/test/lit/passes/dae-gc-no-cd.wast +++ b/test/lit/passes/dae-gc-no-cd.wast @@ -13,7 +13,7 @@ (type $A (struct)) - ;; CHECK: (func $export (type $3) (result (ref $A)) + ;; CHECK: (func $export (type $func) (result anyref) ;; CHECK-NEXT: (struct.new_default $A) ;; CHECK-NEXT: ) (func $export (export "export") (type $func) (result anyref) @@ -21,7 +21,7 @@ (struct.new $A) ) - ;; CHECK: (func $export-tuple (type $4) (result (ref $A) i32) + ;; CHECK: (func $export-tuple (type $func2) (result anyref i32) ;; CHECK-NEXT: (tuple.make 2 ;; CHECK-NEXT: (struct.new_default $A) ;; CHECK-NEXT: (i32.const 42) @@ -36,3 +36,26 @@ ) ) +;; We can refine the array result to $array. However, doing so brings in the +;; entire rec group of $array, which includes an exact type, which is not +;; allowed when custom descriptors are disabled. +(module + ;; CHECK: (type $func (sub (func (result (ref array))))) + (type $func (sub (func (result (ref array))))) + + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $array (array i8)) + (type $array (array i8)) + ;; CHECK: (type $unused (func (result (ref (exact $array))))) + (type $unused (func (result (ref (exact $array))))) + ) + + ;; CHECK: (func $test (type $func) (result (ref array)) + ;; CHECK-NEXT: (array.new_fixed $array 0) + ;; CHECK-NEXT: ) + (func $test (export "test") (type $func) (result (ref array)) + (array.new_fixed $array 0) + ) +) + From 3ee8dbe591cc78b3252c06aa679e1fbe3f8e4fdf Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 2 Oct 2025 12:00:08 -0700 Subject: [PATCH 2/3] fix --- src/passes/DeadArgumentElimination.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/passes/DeadArgumentElimination.cpp b/src/passes/DeadArgumentElimination.cpp index f82c7f4ef7f..c77fdd18ce9 100644 --- a/src/passes/DeadArgumentElimination.cpp +++ b/src/passes/DeadArgumentElimination.cpp @@ -611,7 +611,7 @@ struct DAE : public Pass { // We also must not make private types public. That could be a problem // without custom descriptors (private exact types are ok - they are lowered - // away - but not publicones), and also in general, making more things + // away - but not public ones). And also in general, making more things // public has downsides to later opts, that this one doesn't justify. if (isExported) { if (!privateTypes) { From bc118c73bbe6500a838f5c55807580cdc5e6b6fa Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 2 Oct 2025 12:03:19 -0700 Subject: [PATCH 3/3] test --- test/lit/passes/dae-gc.wast | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/test/lit/passes/dae-gc.wast b/test/lit/passes/dae-gc.wast index 9381968cfe0..4f7c3947078 100644 --- a/test/lit/passes/dae-gc.wast +++ b/test/lit/passes/dae-gc.wast @@ -312,25 +312,70 @@ ;; CHECK: (type $2 (sub $func (func (result (ref (exact $A)))))) + ;; CHECK: (type $3 (func (result (ref $A)))) + ;; CHECK: (export "export" (func $export)) + ;; CHECK: (export "export2" (func $export2)) + ;; CHECK: (func $export (type $2) (result (ref (exact $A))) ;; CHECK-NEXT: (struct.new_default $A) ;; CHECK-NEXT: ) (func $export (export "export") (type $func) (result anyref) (struct.new $A) ) + + ;; CHECK: (func $export2 (type $3) (result (ref $A)) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $export2 (export "export2") (result (ref $A)) + ;; Make $A public, so we are ok to refine $export. + (unreachable) + ) ) ;; We do not refine the result if the type is final/closed, as we can't ;; subtype it. (module + ;; CHECK: (type $A (struct)) + ;; CHECK: (type $func (func (result anyref))) (type $func (func (result anyref))) + (type $A (struct)) + + ;; CHECK: (type $2 (func (result (ref $A)))) + + ;; CHECK: (export "export" (func $export)) + + ;; CHECK: (export "export2" (func $export2)) + + ;; CHECK: (func $export (type $func) (result anyref) + ;; CHECK-NEXT: (struct.new_default $A) + ;; CHECK-NEXT: ) + (func $export (export "export") (type $func) (result anyref) + (struct.new $A) + ) + + ;; CHECK: (func $export2 (type $2) (result (ref $A)) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $export2 (export "export2") (result (ref $A)) + ;; Make $A public, so we are ok to refine $export. + (unreachable) + ) +) + +;; We do not refine the result if the type is private, as that would make it +;; public. +(module + ;; CHECK: (type $func (sub (func (result anyref)))) + ;; CHECK: (type $A (struct)) (type $A (struct)) + (type $func (sub (func (result anyref)))) + ;; CHECK: (export "export" (func $export)) ;; CHECK: (func $export (type $func) (result anyref) @@ -340,3 +385,4 @@ (struct.new $A) ) ) +