Skip to content

Commit b70447f

Browse files
authored
Merge pull request #22557 from gottesmm/pr-022460b087105257b6bd2d0c926210bc16db17be
[ownership] Fix default block folding in diagnose_unreachable.
2 parents bf842b0 + f64a0f3 commit b70447f

File tree

2 files changed

+70
-5
lines changed

2 files changed

+70
-5
lines changed

lib/SILOptimizer/Mandatory/DiagnoseUnreachable.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,16 @@ static bool constantFoldTerminator(SILBasicBlock &BB,
265265
}
266266
}
267267

268-
if (!TheSuccessorBlock)
268+
SILBasicBlock *DB = nullptr;
269+
if (!TheSuccessorBlock) {
269270
if (SUI->hasDefault()) {
270-
SILBasicBlock *DB= SUI->getDefaultBB();
271+
DB = SUI->getDefaultBB();
271272
if (!isa<UnreachableInst>(DB->getTerminator())) {
272273
TheSuccessorBlock = DB;
273274
ReachableBlockIdx = SUI->getNumCases();
274275
}
275276
}
277+
}
276278

277279
// Not fully covered switches will be diagnosed later. SILGen represents
278280
// them with a Default basic block with an unreachable instruction.
@@ -285,8 +287,17 @@ static bool constantFoldTerminator(SILBasicBlock &BB,
285287
SILBuilderWithScope B(&BB, TI);
286288
SILLocation Loc = TI->getLoc();
287289
if (!TheSuccessorBlock->args_empty()) {
288-
assert(TheEnum->hasOperand());
289-
B.createBranch(Loc, TheSuccessorBlock, TheEnum->getOperand());
290+
// If the successor block that we are looking at is the default block,
291+
// we create an argument not for the enum case, but for the original
292+
// value.
293+
SILValue branchOperand;
294+
if (TheSuccessorBlock != DB) {
295+
assert(TheEnum->hasOperand());
296+
branchOperand = TheEnum->getOperand();
297+
} else {
298+
branchOperand = TheEnum;
299+
}
300+
B.createBranch(Loc, TheSuccessorBlock, branchOperand);
290301
} else
291302
B.createBranch(Loc, TheSuccessorBlock);
292303

test/SILOptimizer/diagnose_unreachable.sil

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-sil-opt -enable-sil-verify-all %s -diagnose-unreachable -sil-print-debuginfo | %FileCheck %s
1+
// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -diagnose-unreachable -sil-print-debuginfo | %FileCheck %s
22

33
import Builtin
44
import Swift
@@ -281,6 +281,7 @@ bb3:
281281
enum Singleton {
282282
case x(Int, UnicodeScalar)
283283
};
284+
284285
sil @constant_fold_switch_enum_with_payload : $@convention(thin) (Int, UnicodeScalar) -> (Int, UnicodeScalar) {
285286
bb0(%6 : $Int, %10 : $UnicodeScalar):
286287
%11 = tuple (%6 : $Int, %10 : $UnicodeScalar)
@@ -448,3 +449,56 @@ bb2(%3 : $Never):
448449
bb3(%4 : $Error):
449450
throw %4 : $Error
450451
}
452+
453+
enum Either<L, R> {
454+
case left(L)
455+
case right(R)
456+
}
457+
458+
class Klass1 {}
459+
class Klass2 {}
460+
461+
// CHECK-LABEL: sil [ossa] @constant_fold_diagnose_unreachable_succ_match : $@convention(thin) (@owned Klass1) -> () {
462+
// CHECK: bb0([[ARG:%.*]] :
463+
// CHECK: destroy_value [[ARG]]
464+
// CHECK: } // end sil function 'constant_fold_diagnose_unreachable_succ_match'
465+
sil [ossa] @constant_fold_diagnose_unreachable_succ_match : $@convention(thin) (@owned Klass1) -> () {
466+
bb0(%0 : @owned $Klass1):
467+
%1 = enum $Either<Klass1, Klass2>, #Either.left!enumelt.1, %0 : $Klass1
468+
switch_enum %1 : $Either<Klass1, Klass2>, case #Either.left!enumelt.1: bb1, default bb2
469+
470+
bb1(%2 : @owned $Klass1):
471+
destroy_value %2 : $Klass1
472+
br bb3
473+
474+
bb2(%3 : @owned $Either<Klass1, Klass2>):
475+
destroy_value %3 : $Either<Klass1, Klass2>
476+
br bb3
477+
478+
bb3:
479+
%9999 = tuple()
480+
return %9999 : $()
481+
}
482+
483+
// CHECK-LABEL: sil [ossa] @constant_fold_diagnose_unreachable_default : $@convention(thin) (@owned Klass2) -> () {
484+
// CHECK: bb0([[ARG:%.*]] :
485+
// CHECK: [[ENUM:%.*]] = enum $Either<Klass1, Klass2>, #Either.right!enumelt.1, [[ARG]]
486+
// CHECK: destroy_value [[ENUM]]
487+
// CHECK: } // end sil function 'constant_fold_diagnose_unreachable_default'
488+
sil [ossa] @constant_fold_diagnose_unreachable_default : $@convention(thin) (@owned Klass2) -> () {
489+
bb0(%0 : @owned $Klass2):
490+
%1 = enum $Either<Klass1, Klass2>, #Either.right!enumelt.1, %0 : $Klass2
491+
switch_enum %1 : $Either<Klass1, Klass2>, case #Either.left!enumelt.1: bb1, default bb2
492+
493+
bb1(%2 : @owned $Klass1):
494+
destroy_value %2 : $Klass1
495+
br bb3
496+
497+
bb2(%3 : @owned $Either<Klass1, Klass2>):
498+
destroy_value %3 : $Either<Klass1, Klass2>
499+
br bb3
500+
501+
bb3:
502+
%9999 = tuple()
503+
return %9999 : $()
504+
}

0 commit comments

Comments
 (0)