Skip to content

Commit 9a6ae6e

Browse files
authored
Merge pull request swiftlang#30943 from atrick/fix-assert-termoper
2 parents afaff48 + 18c4cdf commit 9a6ae6e

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,8 @@ swift::getSingleOwnedValueIntroducer(SILValue inputValue) {
691691
auto *arg = cast<SILPhiArgument>(currentValue);
692692
auto *termInst = arg->getSingleTerminator();
693693
assert(termInst && termInst->isTransformationTerminator());
694-
assert(termInst->getNumOperands() == 1 &&
694+
assert(termInst->getNumOperands()
695+
- termInst->getNumTypeDependentOperands() == 1 &&
695696
"Transformation terminators should only have single operands");
696697
currentValue = termInst->getAllOperands()[0].get();
697698
continue;

test/SILOptimizer/semantic-arc-opts-canonical.sil

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,3 +485,60 @@ bb3:
485485
%9999 = tuple()
486486
return %9999 : $()
487487
}
488+
489+
// ============================================================================
490+
// Test SemanticARC phi optimization. canEliminatePhi must recognize
491+
// terminators with multiple operands.
492+
493+
// CHECK-LABEL: sil [ossa] @testTypeDependentCheckCast : $@convention(thin) (@guaranteed Klass, @thick @dynamic_self Klass.Type) -> () {
494+
// CHECK: bb0(%0 : @guaranteed $Klass, %1 : $@thick @dynamic_self Klass.Type):
495+
// CHECK: checked_cast_br %0 : $Klass to @dynamic_self Klass, bb1, bb2 // type-defs: %1; id: %2
496+
//
497+
// CHECK: bb1([[CAST:%.*]] : @guaranteed $Klass):
498+
// CHECK: [[SOME:%.*]] = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, [[CAST]] : $Klass
499+
// CHECK: [[BORROW:%.*]] = begin_borrow [[SOME]] : $FakeOptional<Klass>
500+
// CHECK: br bb3([[BORROW]] : $FakeOptional<Klass>)
501+
//
502+
// CHECK: bb2([[FAIL:%.*]] : @guaranteed $Klass):
503+
// CHECK-NEXT: [[NONE:%.*]] = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
504+
// CHECK-NEXT: br bb3([[NONE]] : $FakeOptional<Klass>)
505+
//
506+
// CHECK: bb3([[PHI:%.*]] : @guaranteed $FakeOptional<Klass>):
507+
// CHECK: switch_enum [[PHI]] : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb5, case #FakeOptional.none!enumelt: bb4
508+
//
509+
// CHECK: bb4:
510+
// CHECK-NEXT: end_borrow [[PHI]] : $FakeOptional<Klass>
511+
// CHECK-NEXT: br bb6
512+
//
513+
// CHECK: bb5(%{{.*}} : @guaranteed $Klass):
514+
// CHECK-NEXT: end_borrow [[PHI]] : $FakeOptional<Klass>
515+
// CHECK-NEXT: br bb6
516+
// CHECK-LABEL: } // end sil function 'testTypeDependentCheckCast'
517+
sil [ossa] @testTypeDependentCheckCast : $@convention(thin) (@guaranteed Klass, @thick @dynamic_self Klass.Type) -> () {
518+
bb0(%0 : @guaranteed $Klass, %1 : $@thick @dynamic_self Klass.Type):
519+
%2 = copy_value %0 : $Klass
520+
checked_cast_br %2 : $Klass to @dynamic_self Klass, bb1, bb2
521+
522+
bb1(%4 : @owned $Klass):
523+
%5 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %4 : $Klass
524+
br bb3(%5 : $FakeOptional<Klass>)
525+
526+
bb2(%7 : @owned $Klass):
527+
destroy_value %7 : $Klass
528+
%9 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
529+
br bb3(%9 : $FakeOptional<Klass>)
530+
531+
bb3(%11 : @owned $FakeOptional<Klass>):
532+
switch_enum %11 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb5, case #FakeOptional.none!enumelt: bb4
533+
534+
bb4:
535+
br bb6
536+
537+
bb5(%14 : @owned $Klass):
538+
destroy_value %14 : $Klass
539+
br bb6
540+
541+
bb6:
542+
%17 = tuple ()
543+
return %17 : $()
544+
}

0 commit comments

Comments
 (0)