Skip to content

Commit f7a4ed8

Browse files
committed
Cleanup dead blocks after noreturn folding
Follow-up passes might not handle blocks with undef instruction operands well. rdar://41139395
1 parent 73d3b37 commit f7a4ed8

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

lib/SILOptimizer/Mandatory/DiagnoseUnreachable.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/SIL/SILBuilder.h"
2121
#include "swift/SIL/SILUndef.h"
2222
#include "swift/SILOptimizer/Utils/Local.h"
23+
#include "swift/SILOptimizer/Utils/CFG.h"
2324
#include "swift/SILOptimizer/PassManager/Transforms.h"
2425
#include "llvm/ADT/STLExtras.h"
2526
#include "llvm/ADT/Statistic.h"
@@ -750,13 +751,16 @@ static void performNoReturnFunctionProcessing(SILFunction &Fn,
750751
SILFunctionTransform *T) {
751752
DEBUG(llvm::errs() << "*** No return function processing: " << Fn.getName()
752753
<< "\n");
753-
754+
bool Changed = false;
754755
for (auto &BB : Fn) {
755756
// Remove instructions from the basic block after a call to a noreturn
756757
// function.
757-
simplifyBlocksWithCallsToNoReturn(BB, nullptr);
758+
Changed |= simplifyBlocksWithCallsToNoReturn(BB, nullptr);
759+
}
760+
if (Changed) {
761+
removeUnreachableBlocks(Fn);
762+
T->invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
758763
}
759-
T->invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
760764
}
761765

762766
static void diagnoseUnreachable(SILFunction &Fn) {

test/SILOptimizer/mandatory_inlining.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,16 @@ public class A {
175175
}
176176
}
177177
}
178+
179+
// This used to crash during mandatory inlining because noreturn folding would
180+
// create sil instructions with undef in unreachable code.
181+
func dontCrash() {
182+
fatalError() // expected-note {{a call to a never-returning function}}
183+
let k = "foo" // expected-warning {{will never be executed}}
184+
switch k {
185+
case "bar":
186+
return
187+
default:
188+
fatalError("baz \(k)")
189+
}
190+
}

0 commit comments

Comments
 (0)