@@ -960,7 +960,6 @@ struct FunctionSplitter {
960960 // Find the number of ifs.
961961 Index numIfs = 0 ;
962962 while (getIf (body, numIfs) && numIfs <= MaxIfs) {
963- // 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!
964963 numIfs++;
965964 }
966965 if (numIfs == 0 || numIfs > MaxIfs) {
@@ -979,7 +978,19 @@ struct FunctionSplitter {
979978 if (finalItem && getItem (body, numIfs + 1 )) {
980979 return InliningMode::Uninlineable;
981980 }
982- // This has the general shape we seek. Check each if.
981+ // This has the general shape we seek. Check each if: it must be in the
982+ // form mentioned above (simple condition, no returns in body). We must also
983+ // have no sets of locals that the final item notices, as then we could
984+ // have this:
985+ //
986+ // if (A) {
987+ // x = 10;
988+ // }
989+ // return x;
990+ //
991+ // We cannot split out the if in such a case because of the local
992+ // dependency.
993+ std::unordered_set<Index> writtenLocals;
983994 for (Index i = 0 ; i < numIfs; i++) {
984995 auto * iff = getIf (body, i);
985996 // The if must have a simple condition and no else arm.
@@ -996,7 +1007,21 @@ struct FunctionSplitter {
9961007 // unreachable, and we ruled out none before.
9971008 assert (iff->ifTrue ->type == Type::unreachable);
9981009 }
1010+ if (finalItem) {
1011+ for (auto * set : FindAll<LocalSet>(iff).list ) {
1012+ writtenLocals.insert (set->index );
1013+ }
1014+ }
9991015 }
1016+ // Finish the locals check mentioned above.
1017+ if (finalItem) {
1018+ for (auto * get : FindAll<LocalSet>(finalItem).list ) {
1019+ if (writtenLocals.count (get->index )) {
1020+ return InliningMode::Uninlineable;
1021+ }
1022+ }
1023+ }
1024+
10001025 // Success, this matches the pattern.
10011026
10021027 // If the outlined function will be worth inlining normally, skip the
0 commit comments