From c9c06865e5f7ed593bcd90d96dc09d3051b351b7 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 20 Nov 2025 20:20:48 -0800 Subject: [PATCH 1/7] start --- src/passes/Inlining.cpp | 1 + test/lit/passes/inlining_splitting.wast | 181 ++++++++++++++++++++++++ 2 files changed, 182 insertions(+) diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index 31e5fb1179d..4338f5e9d63 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -960,6 +960,7 @@ struct FunctionSplitter { // Find the number of ifs. Index numIfs = 0; while (getIf(body, numIfs) && numIfs <= MaxIfs) { + // but what if if has effects that the later things notice, either other ifs or the final B? acuallyy effects are cool. but locals r not! numIfs++; } if (numIfs == 0 || numIfs > MaxIfs) { diff --git a/test/lit/passes/inlining_splitting.wast b/test/lit/passes/inlining_splitting.wast index f3d7f44a4d2..ed2bdec9d4c 100644 --- a/test/lit/passes/inlining_splitting.wast +++ b/test/lit/passes/inlining_splitting.wast @@ -2271,3 +2271,184 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) +(module + ;; Pattern B situations with local value dependencies. + + ;; An import, whose calls are work that we want to split out. + ;; CHECK: (type $0 (func)) + + ;; CHECK: (type $1 (func (param i32 i32))) + + ;; CHECK: (import "out" "func" (func $import (type $0))) + (import "out" "func" (func $import)) + + (func $bad (param $x i32) (param $y i32) (result i32) + ;; Check $x, and possibly set $y. $y is read below, so we cannot split out + ;; the set. + (if + (local.get $x) + (then + (block + (local.set $y + (i32.const 42) + ) + (call $import) + ) + ) + ) + (local.get $y) + ) + + (func $good (param $x i32) (param $y i32) (result i32) + ;; As above, but set $x in the if body. No problem occurs after the if, so + ;; we can split here. + (if + (local.get $x) + (then + (block + (local.set $x + (i32.const 1337) + ) + (call $import) + ) + ) + ) + (local.get $y) + ) + + ;; CHECK: (func $calls-bad (type $0) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad (result i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad$1 (result i32) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $calls-bad + ;; These should not be inlined/split. + ;; Call twice to avoid single-call inlining. + (drop + (call $bad (i32.const 1) (i32.const 2)) + ) + (drop + (call $bad (i32.const 1) (i32.const 2)) + ) + ) + + ;; CHECK: (func $calls-good (type $0) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good$2 (result i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$good + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good$3 (result i32) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$good + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $calls-good + ;; These should be inlined/split. + (drop + (call $good (i32.const 2) (i32.const 3)) + ) + (drop + (call $good (i32.const 2) (i32.const 3)) + ) + ) +) + +;; TODO: two ifs etc. +;; CHECK: (func $byn-split-outlined-B$bad (type $1) (param $x i32) (param $y i32) +;; CHECK-NEXT: (local.set $y +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (call $import) +;; CHECK-NEXT: ) + +;; CHECK: (func $byn-split-outlined-B$good (type $1) (param $x i32) (param $y i32) +;; CHECK-NEXT: (local.set $x +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (call $import) +;; CHECK-NEXT: ) From b518d06b09dfd4f8025f423837e6c2b200836a36 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 21 Nov 2025 07:41:30 -0800 Subject: [PATCH 2/7] work --- test/lit/passes/inlining_splitting.wast | 37 ++++++++++++------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/test/lit/passes/inlining_splitting.wast b/test/lit/passes/inlining_splitting.wast index ed2bdec9d4c..5e6787d1d90 100644 --- a/test/lit/passes/inlining_splitting.wast +++ b/test/lit/passes/inlining_splitting.wast @@ -2299,23 +2299,6 @@ (local.get $y) ) - (func $good (param $x i32) (param $y i32) (result i32) - ;; As above, but set $x in the if body. No problem occurs after the if, so - ;; we can split here. - (if - (local.get $x) - (then - (block - (local.set $x - (i32.const 1337) - ) - (call $import) - ) - ) - ) - (local.get $y) - ) - ;; CHECK: (func $calls-bad (type $0) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i32) @@ -2377,6 +2360,23 @@ ) ) + (func $good (param $x i32) (param $y i32) (result i32) + ;; As above, but set $x in the if body. No problem occurs after the if, so + ;; we can split here. + (if + (local.get $x) + (then + (block + (local.set $x + (i32.const 1337) + ) + (call $import) + ) + ) + ) + (local.get $y) + ) + ;; CHECK: (func $calls-good (type $0) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i32) @@ -2438,7 +2438,6 @@ ) ) -;; TODO: two ifs etc. ;; CHECK: (func $byn-split-outlined-B$bad (type $1) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $y ;; CHECK-NEXT: (i32.const 42) @@ -2448,7 +2447,7 @@ ;; CHECK: (func $byn-split-outlined-B$good (type $1) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $x -;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) From c0c21f630e99079cf6aeff000dafe023b370eb0d Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 21 Nov 2025 07:44:47 -0800 Subject: [PATCH 3/7] work --- test/lit/passes/inlining_splitting.wast | 252 +++++++++++++++++++++++- 1 file changed, 245 insertions(+), 7 deletions(-) diff --git a/test/lit/passes/inlining_splitting.wast b/test/lit/passes/inlining_splitting.wast index 5e6787d1d90..d7da290aa6e 100644 --- a/test/lit/passes/inlining_splitting.wast +++ b/test/lit/passes/inlining_splitting.wast @@ -2275,11 +2275,11 @@ ;; Pattern B situations with local value dependencies. ;; An import, whose calls are work that we want to split out. - ;; CHECK: (type $0 (func)) + ;; CHECK: (type $0 (func (param i32 i32))) - ;; CHECK: (type $1 (func (param i32 i32))) + ;; CHECK: (type $1 (func)) - ;; CHECK: (import "out" "func" (func $import (type $0))) + ;; CHECK: (import "out" "func" (func $import (type $1))) (import "out" "func" (func $import)) (func $bad (param $x i32) (param $y i32) (result i32) @@ -2299,7 +2299,7 @@ (local.get $y) ) - ;; CHECK: (func $calls-bad (type $0) + ;; CHECK: (func $calls-bad (type $1) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) @@ -2377,7 +2377,7 @@ (local.get $y) ) - ;; CHECK: (func $calls-good (type $0) + ;; CHECK: (func $calls-good (type $1) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) @@ -2436,18 +2436,256 @@ (call $good (i32.const 2) (i32.const 3)) ) ) + + (func $bad-2 (param $x i32) (param $y i32) (result i32) + ;; Two ifs, with the problem in the first. + (if + (local.get $x) + (then + (block + (local.set $y ;; this is bad + (i32.const 42) + ) + (call $import) + ) + ) + ) + (if + (local.get $y) + (then + (block + (local.set $x + (i32.const 42) + ) + (call $import) + ) + ) + ) + (local.get $y) + ) + + ;; CHECK: (func $calls-bad-2 (type $1) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-2$4 (result i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_15 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-2$5 (result i32) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_15 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $calls-bad-2 + ;; These should not be inlined/split. + (drop + (call $bad-2 (i32.const 1) (i32.const 2)) + ) + (drop + (call $bad-2 (i32.const 1) (i32.const 2)) + ) + ) + + (func $bad-3 (param $x i32) (param $y i32) (result i32) + ;; Two ifs, with the problem in the second. + (if + (local.get $x) + (then + (block + (local.set $x ;; this changed + (i32.const 42) + ) + (call $import) + ) + ) + ) + (if + (local.get $y) + (then + (block + (local.set $y ;; this changed + (i32.const 42) + ) + (call $import) + ) + ) + ) + (local.get $y) + ) + + ;; CHECK: (func $calls-bad-3 (type $1) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-3$6 (result i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_18 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-3$7 (result i32) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_18 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $calls-bad-3 + ;; These should not be inlined/split. + (drop + (call $bad-3 (i32.const 1) (i32.const 2)) + ) + (drop + (call $bad-3 (i32.const 1) (i32.const 2)) + ) + ) ) -;; CHECK: (func $byn-split-outlined-B$bad (type $1) (param $x i32) (param $y i32) +;; CHECK: (func $byn-split-outlined-B$bad (type $0) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $y ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) -;; CHECK: (func $byn-split-outlined-B$good (type $1) (param $x i32) (param $y i32) +;; CHECK: (func $byn-split-outlined-B$good (type $0) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) + +;; CHECK: (func $byn-split-outlined-B$bad-2 (type $0) (param $x i32) (param $y i32) +;; CHECK-NEXT: (local.set $y +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (call $import) +;; CHECK-NEXT: ) + +;; CHECK: (func $byn-split-outlined-B$bad-2_15 (type $0) (param $x i32) (param $y i32) +;; CHECK-NEXT: (local.set $x +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (call $import) +;; CHECK-NEXT: ) + +;; CHECK: (func $byn-split-outlined-B$bad-3 (type $0) (param $x i32) (param $y i32) +;; CHECK-NEXT: (local.set $x +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (call $import) +;; CHECK-NEXT: ) + +;; CHECK: (func $byn-split-outlined-B$bad-3_18 (type $0) (param $x i32) (param $y i32) +;; CHECK-NEXT: (local.set $y +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (call $import) +;; CHECK-NEXT: ) From 01af821cafd2ca987b990bba1894cf9f5b0bf680 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 21 Nov 2025 07:45:53 -0800 Subject: [PATCH 4/7] work --- test/lit/passes/inlining_splitting.wast | 131 ++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 6 deletions(-) diff --git a/test/lit/passes/inlining_splitting.wast b/test/lit/passes/inlining_splitting.wast index d7da290aa6e..674bc7d9cc0 100644 --- a/test/lit/passes/inlining_splitting.wast +++ b/test/lit/passes/inlining_splitting.wast @@ -2490,7 +2490,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_15 + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_17 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -2521,7 +2521,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_15 + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_17 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) @@ -2595,7 +2595,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_18 + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_20 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -2626,7 +2626,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_18 + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_20 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) @@ -2646,6 +2646,111 @@ (call $bad-3 (i32.const 1) (i32.const 2)) ) ) + + (func $bad-4 (param $x i32) (param $y i32) (result i32) + ;; Two ifs, with a problem in both. + (if + (local.get $x) + (then + (block + (local.set $y ;; this changed + (i32.const 42) + ) + (call $import) + ) + ) + ) + (if + (local.get $y) + (then + (block + (local.set $y + (i32.const 42) + ) + (call $import) + ) + ) + ) + (local.get $y) + ) + + ;; CHECK: (func $calls-bad-4 (type $1) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-4$8 (result i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4_23 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-4$9 (result i32) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4_23 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $calls-bad-4 + ;; These should not be inlined/split. + (drop + (call $bad-4 (i32.const 1) (i32.const 2)) + ) + (drop + (call $bad-4 (i32.const 1) (i32.const 2)) + ) + ) ) ;; CHECK: (func $byn-split-outlined-B$bad (type $0) (param $x i32) (param $y i32) @@ -2669,7 +2774,7 @@ ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) -;; CHECK: (func $byn-split-outlined-B$bad-2_15 (type $0) (param $x i32) (param $y i32) +;; CHECK: (func $byn-split-outlined-B$bad-2_17 (type $0) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) @@ -2683,7 +2788,21 @@ ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) -;; CHECK: (func $byn-split-outlined-B$bad-3_18 (type $0) (param $x i32) (param $y i32) +;; CHECK: (func $byn-split-outlined-B$bad-3_20 (type $0) (param $x i32) (param $y i32) +;; CHECK-NEXT: (local.set $y +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (call $import) +;; CHECK-NEXT: ) + +;; CHECK: (func $byn-split-outlined-B$bad-4 (type $0) (param $x i32) (param $y i32) +;; CHECK-NEXT: (local.set $y +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (call $import) +;; CHECK-NEXT: ) + +;; CHECK: (func $byn-split-outlined-B$bad-4_23 (type $0) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $y ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) From 195cd68280a457fea178a11b9e4ab94239ea242b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 21 Nov 2025 07:47:02 -0800 Subject: [PATCH 5/7] work --- test/lit/passes/inlining_splitting.wast | 137 ++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 9 deletions(-) diff --git a/test/lit/passes/inlining_splitting.wast b/test/lit/passes/inlining_splitting.wast index 674bc7d9cc0..4b54208272d 100644 --- a/test/lit/passes/inlining_splitting.wast +++ b/test/lit/passes/inlining_splitting.wast @@ -2490,7 +2490,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_17 + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_19 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -2521,7 +2521,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_17 + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_19 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) @@ -2595,7 +2595,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_20 + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_22 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -2626,7 +2626,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_20 + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_22 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) @@ -2700,7 +2700,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4_23 + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4_25 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -2731,7 +2731,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4_23 + ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4_25 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) @@ -2751,6 +2751,111 @@ (call $bad-4 (i32.const 1) (i32.const 2)) ) ) + + (func $good-5 (param $x i32) (param $y i32) (result i32) + ;; Two ifs, with no problem in either. + (if + (local.get $x) + (then + (block + (local.set $x ;; this changed + (i32.const 42) + ) + (call $import) + ) + ) + ) + (if + (local.get $y) + (then + (block + (local.set $x ;; this changed + (i32.const 42) + ) + (call $import) + ) + ) + ) + (local.get $y) + ) + + ;; CHECK: (func $calls-good-5 (type $1) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good-5$10 (result i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$good-5 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$good-5_28 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good-5$11 (result i32) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$good-5 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$good-5_28 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $calls-good-5 + ;; These should be inlined/split. + (drop + (call $good-5 (i32.const 1) (i32.const 2)) + ) + (drop + (call $good-5 (i32.const 1) (i32.const 2)) + ) + ) ) ;; CHECK: (func $byn-split-outlined-B$bad (type $0) (param $x i32) (param $y i32) @@ -2774,7 +2879,7 @@ ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) -;; CHECK: (func $byn-split-outlined-B$bad-2_17 (type $0) (param $x i32) (param $y i32) +;; CHECK: (func $byn-split-outlined-B$bad-2_19 (type $0) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) @@ -2788,7 +2893,7 @@ ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) -;; CHECK: (func $byn-split-outlined-B$bad-3_20 (type $0) (param $x i32) (param $y i32) +;; CHECK: (func $byn-split-outlined-B$bad-3_22 (type $0) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $y ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) @@ -2802,9 +2907,23 @@ ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) -;; CHECK: (func $byn-split-outlined-B$bad-4_23 (type $0) (param $x i32) (param $y i32) +;; CHECK: (func $byn-split-outlined-B$bad-4_25 (type $0) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $y ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) + +;; CHECK: (func $byn-split-outlined-B$good-5 (type $0) (param $x i32) (param $y i32) +;; CHECK-NEXT: (local.set $x +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (call $import) +;; CHECK-NEXT: ) + +;; CHECK: (func $byn-split-outlined-B$good-5_28 (type $0) (param $x i32) (param $y i32) +;; CHECK-NEXT: (local.set $x +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (call $import) +;; CHECK-NEXT: ) From ee1ed0416d7739f9739ffaeb2fb5bcae7b99d7ca Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 21 Nov 2025 08:18:47 -0800 Subject: [PATCH 6/7] work --- src/passes/Inlining.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index 4338f5e9d63..335a7a87917 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -960,7 +960,6 @@ struct FunctionSplitter { // Find the number of ifs. Index numIfs = 0; while (getIf(body, numIfs) && numIfs <= MaxIfs) { - // but what if if has effects that the later things notice, either other ifs or the final B? acuallyy effects are cool. but locals r not! numIfs++; } if (numIfs == 0 || numIfs > MaxIfs) { @@ -979,7 +978,19 @@ struct FunctionSplitter { if (finalItem && getItem(body, numIfs + 1)) { return InliningMode::Uninlineable; } - // This has the general shape we seek. Check each if. + // This has the general shape we seek. Check each if: it must be in the + // form mentioned above (simple condition, no returns in body). We must also + // have no sets of locals that the final item notices, as then we could + // have this: + // + // if (A) { + // x = 10; + // } + // return x; + // + // We cannot split out the if in such a case because of the local + // dependency. + std::unordered_set writtenLocals; for (Index i = 0; i < numIfs; i++) { auto* iff = getIf(body, i); // The if must have a simple condition and no else arm. @@ -996,7 +1007,21 @@ struct FunctionSplitter { // unreachable, and we ruled out none before. assert(iff->ifTrue->type == Type::unreachable); } + if (finalItem) { + for (auto* set : FindAll(iff).list) { + writtenLocals.insert(set->index); + } + } } + // Finish the locals check mentioned above. + if (finalItem) { + for (auto* get : FindAll(finalItem).list) { + if (writtenLocals.count(get->index)) { + return InliningMode::Uninlineable; + } + } + } + // Success, this matches the pattern. // If the outlined function will be worth inlining normally, skip the From 99741b52376651299bd03a26b1494428b752a36e Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 21 Nov 2025 08:27:18 -0800 Subject: [PATCH 7/7] work --- src/passes/Inlining.cpp | 2 +- test/lit/passes/inlining_splitting.wast | 410 +++++++----------------- 2 files changed, 121 insertions(+), 291 deletions(-) diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index 335a7a87917..412c53e40a7 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -1015,7 +1015,7 @@ struct FunctionSplitter { } // Finish the locals check mentioned above. if (finalItem) { - for (auto* get : FindAll(finalItem).list) { + for (auto* get : FindAll(finalItem).list) { if (writtenLocals.count(get->index)) { return InliningMode::Uninlineable; } diff --git a/test/lit/passes/inlining_splitting.wast b/test/lit/passes/inlining_splitting.wast index 4b54208272d..e583e2e4021 100644 --- a/test/lit/passes/inlining_splitting.wast +++ b/test/lit/passes/inlining_splitting.wast @@ -2275,13 +2275,27 @@ ;; Pattern B situations with local value dependencies. ;; An import, whose calls are work that we want to split out. - ;; CHECK: (type $0 (func (param i32 i32))) + ;; CHECK: (type $0 (func)) + + ;; CHECK: (type $1 (func (param i32 i32) (result i32))) - ;; CHECK: (type $1 (func)) + ;; CHECK: (type $2 (func (param i32 i32))) - ;; CHECK: (import "out" "func" (func $import (type $1))) + ;; CHECK: (import "out" "func" (func $import (type $0))) (import "out" "func" (func $import)) + ;; CHECK: (func $bad (type $1) (param $x i32) (param $y i32) (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) (func $bad (param $x i32) (param $y i32) (result i32) ;; Check $x, and possibly set $y. $y is read below, so we cannot split out ;; the set. @@ -2299,53 +2313,17 @@ (local.get $y) ) - ;; CHECK: (func $calls-bad (type $1) - ;; CHECK-NEXT: (local $0 i32) - ;; CHECK-NEXT: (local $1 i32) - ;; CHECK-NEXT: (local $2 i32) - ;; CHECK-NEXT: (local $3 i32) + ;; CHECK: (func $calls-bad (type $0) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad (result i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $bad + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad$1 (result i32) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $bad + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2367,7 +2345,7 @@ (local.get $x) (then (block - (local.set $x + (local.set $x ;; this changed (i32.const 1337) ) (call $import) @@ -2377,13 +2355,13 @@ (local.get $y) ) - ;; CHECK: (func $calls-good (type $1) + ;; CHECK: (func $calls-good (type $0) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good$2 (result i32) + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good (result i32) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) @@ -2405,7 +2383,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good$3 (result i32) + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good$1 (result i32) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) @@ -2437,6 +2415,27 @@ ) ) + ;; CHECK: (func $bad-2 (type $1) (param $x i32) (param $y i32) (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) (func $bad-2 (param $x i32) (param $y i32) (result i32) ;; Two ifs, with the problem in the first. (if @@ -2464,71 +2463,17 @@ (local.get $y) ) - ;; CHECK: (func $calls-bad-2 (type $1) - ;; CHECK-NEXT: (local $0 i32) - ;; CHECK-NEXT: (local $1 i32) - ;; CHECK-NEXT: (local $2 i32) - ;; CHECK-NEXT: (local $3 i32) + ;; CHECK: (func $calls-bad-2 (type $0) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-2$4 (result i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_19 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $bad-2 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-2$5 (result i32) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-2_19 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $bad-2 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2542,6 +2487,27 @@ ) ) + ;; CHECK: (func $bad-3 (type $1) (param $x i32) (param $y i32) (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) (func $bad-3 (param $x i32) (param $y i32) (result i32) ;; Two ifs, with the problem in the second. (if @@ -2569,71 +2535,17 @@ (local.get $y) ) - ;; CHECK: (func $calls-bad-3 (type $1) - ;; CHECK-NEXT: (local $0 i32) - ;; CHECK-NEXT: (local $1 i32) - ;; CHECK-NEXT: (local $2 i32) - ;; CHECK-NEXT: (local $3 i32) + ;; CHECK: (func $calls-bad-3 (type $0) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-3$6 (result i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_22 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $bad-3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-3$7 (result i32) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-3_22 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $bad-3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2647,6 +2559,27 @@ ) ) + ;; CHECK: (func $bad-4 (type $1) (param $x i32) (param $y i32) (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) (func $bad-4 (param $x i32) (param $y i32) (result i32) ;; Two ifs, with a problem in both. (if @@ -2674,71 +2607,17 @@ (local.get $y) ) - ;; CHECK: (func $calls-bad-4 (type $1) - ;; CHECK-NEXT: (local $0 i32) - ;; CHECK-NEXT: (local $1 i32) - ;; CHECK-NEXT: (local $2 i32) - ;; CHECK-NEXT: (local $3 i32) + ;; CHECK: (func $calls-bad-4 (type $0) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-4$8 (result i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4_25 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $bad-4 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$bad-4$9 (result i32) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$bad-4_25 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $bad-4 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2779,13 +2658,13 @@ (local.get $y) ) - ;; CHECK: (func $calls-good-5 (type $1) + ;; CHECK: (func $calls-good-5 (type $0) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good-5$10 (result i32) + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good-5$2 (result i32) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -2805,7 +2684,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$good-5_28 + ;; CHECK-NEXT: (call $byn-split-outlined-B$good-5_17 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -2816,7 +2695,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good-5$11 (result i32) + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-B$good-5$3 (result i32) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -2836,7 +2715,7 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (call $byn-split-outlined-B$good-5_28 + ;; CHECK-NEXT: (call $byn-split-outlined-B$good-5_17 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) @@ -2858,70 +2737,21 @@ ) ) -;; CHECK: (func $byn-split-outlined-B$bad (type $0) (param $x i32) (param $y i32) -;; CHECK-NEXT: (local.set $y -;; CHECK-NEXT: (i32.const 42) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $import) -;; CHECK-NEXT: ) - -;; CHECK: (func $byn-split-outlined-B$good (type $0) (param $x i32) (param $y i32) +;; CHECK: (func $byn-split-outlined-B$good (type $2) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) -;; CHECK: (func $byn-split-outlined-B$bad-2 (type $0) (param $x i32) (param $y i32) -;; CHECK-NEXT: (local.set $y -;; CHECK-NEXT: (i32.const 42) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $import) -;; CHECK-NEXT: ) - -;; CHECK: (func $byn-split-outlined-B$bad-2_19 (type $0) (param $x i32) (param $y i32) -;; CHECK-NEXT: (local.set $x -;; CHECK-NEXT: (i32.const 42) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $import) -;; CHECK-NEXT: ) - -;; CHECK: (func $byn-split-outlined-B$bad-3 (type $0) (param $x i32) (param $y i32) -;; CHECK-NEXT: (local.set $x -;; CHECK-NEXT: (i32.const 42) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $import) -;; CHECK-NEXT: ) - -;; CHECK: (func $byn-split-outlined-B$bad-3_22 (type $0) (param $x i32) (param $y i32) -;; CHECK-NEXT: (local.set $y -;; CHECK-NEXT: (i32.const 42) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $import) -;; CHECK-NEXT: ) - -;; CHECK: (func $byn-split-outlined-B$bad-4 (type $0) (param $x i32) (param $y i32) -;; CHECK-NEXT: (local.set $y -;; CHECK-NEXT: (i32.const 42) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $import) -;; CHECK-NEXT: ) - -;; CHECK: (func $byn-split-outlined-B$bad-4_25 (type $0) (param $x i32) (param $y i32) -;; CHECK-NEXT: (local.set $y -;; CHECK-NEXT: (i32.const 42) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $import) -;; CHECK-NEXT: ) - -;; CHECK: (func $byn-split-outlined-B$good-5 (type $0) (param $x i32) (param $y i32) +;; CHECK: (func $byn-split-outlined-B$good-5 (type $2) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) -;; CHECK: (func $byn-split-outlined-B$good-5_28 (type $0) (param $x i32) (param $y i32) +;; CHECK: (func $byn-split-outlined-B$good-5_17 (type $2) (param $x i32) (param $y i32) ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )