diff options
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 6 | ||||
-rw-r--r-- | test/lit/passes/optimize-instructions-gc-heap.wast | 54 |
2 files changed, 60 insertions, 0 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 059ef28fb..3de7b6519 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -2040,6 +2040,12 @@ struct OptimizeInstructions return; } + if (curr->op == ExternExternalize || curr->op == ExternInternalize) { + // We can't optimize these. Even removing a non-null cast is not valid as + // they allow nulls to filter through, unlike other RefAs* + return; + } + skipNonNullCast(curr->value); // Check if the type is the kind we are checking for. diff --git a/test/lit/passes/optimize-instructions-gc-heap.wast b/test/lit/passes/optimize-instructions-gc-heap.wast index e448e57fd..b77678760 100644 --- a/test/lit/passes/optimize-instructions-gc-heap.wast +++ b/test/lit/passes/optimize-instructions-gc-heap.wast @@ -766,4 +766,58 @@ (func $helper-i32 (param $x i32) (result i32) (i32.const 42) ) + + ;; CHECK: (func $extern.externalize (param $x anyref) (param $y externref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (extern.internalize + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (extern.internalize + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $extern.externalize (export "ext") (param $x (ref null any)) (param $y (ref null extern)) + ;; We should not change anything here, and also not hit an internal error. + (drop + (extern.externalize + (local.get $x) + ) + ) + (drop + (extern.externalize + (ref.as_non_null + (local.get $x) + ) + ) + ) + (drop + (extern.internalize + (local.get $y) + ) + ) + (drop + (extern.internalize + (ref.as_non_null + (local.get $y) + ) + ) + ) + ) ) |