From ebaa4d26efdfda6d03627f910c250b5e581b4c09 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 21 May 2026 10:29:36 -0700 Subject: [PATCH] fix --- src/passes/RemoveUnusedModuleElements.cpp | 3 ++ .../remove-unused-module-elements_tnh.wast | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp index fd026490cb1..679e3224029 100644 --- a/src/passes/RemoveUnusedModuleElements.cpp +++ b/src/passes/RemoveUnusedModuleElements.cpp @@ -764,6 +764,9 @@ struct Analyzer { } else if (kind == ModuleElementKind::ElementSegment) { // TODO: We could empty out parts of the segment we don't need. auto* segment = module->getElementSegment(value); + if (segment->offset) { + addReferences(segment->offset); + } for (auto* item : segment->data) { addReferences(item); } diff --git a/test/lit/passes/remove-unused-module-elements_tnh.wast b/test/lit/passes/remove-unused-module-elements_tnh.wast index 76275742c63..a4d06d53154 100644 --- a/test/lit/passes/remove-unused-module-elements_tnh.wast +++ b/test/lit/passes/remove-unused-module-elements_tnh.wast @@ -236,3 +236,45 @@ ;; T_N_H: (export "mem" (memory $mem)) (export "mem" (memory $mem)) ) + +;; The exported function has a call_indirect, which refers to the table and +;; elem. The elem refers to the global, so it must not be removed (in either TNH +;; or not). +(module + ;; CHECK: (type $nop (func)) + ;; T_N_H: (type $nop (func)) + (type $nop (func)) + + ;; CHECK: (global $g i32 (i32.const 0)) + ;; T_N_H: (global $g i32 (i32.const 0)) + (global $g i32 (i32.const 0)) + + ;; CHECK: (table $table 50 50 funcref) + ;; T_N_H: (table $table 50 50 funcref) + (table $table 50 50 funcref) + + ;; CHECK: (elem $elem (global.get $g) $func) + ;; T_N_H: (elem $elem (global.get $g) $func) + (elem $elem (global.get $g) $func) + + ;; CHECK: (export "func" (func $func)) + + ;; CHECK: (func $func (type $nop) + ;; CHECK-NEXT: (call_indirect $table (type $nop) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; T_N_H: (export "func" (func $func)) + + ;; T_N_H: (func $func (type $nop) + ;; T_N_H-NEXT: (call_indirect $table (type $nop) + ;; T_N_H-NEXT: (i32.const 0) + ;; T_N_H-NEXT: ) + ;; T_N_H-NEXT: ) + (func $func (export "func") (type $nop) + (call_indirect (type $nop) + (i32.const 0) + ) + ) +) +