Skip to content

Commit c4c1c50

Browse files
committed
SimplifyCFG: insert compensating end_lifetime when replacing a switch_enum
This is a follow-up of #84905, which handles non-copyable enums with a deinit correctly. Also, for copyable enums it's more efficient to use `end_lifetime` than `destroy_value`, because we already know that the enum contains a trivial case. Therefore no destroy operation is needed.
1 parent ffc71e9 commit c4c1c50

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1793,7 +1793,8 @@ bool SimplifyCFG::simplifySwitchEnumUnreachableBlocks(SwitchEnumInst *SEI) {
17931793
if (Dest->args_empty()) {
17941794
SILBuilderWithScope builder(SEI);
17951795
if (SEI->getOperand()->getOwnershipKind() == OwnershipKind::Owned) {
1796-
builder.createDestroyValue(SEI->getLoc(), SEI->getOperand());
1796+
// Note that a `destroy_value` would be wrong for non-copyable enums with deinits.
1797+
builder.createEndLifetime(SEI->getLoc(), SEI->getOperand());
17971798
}
17981799
builder.createBranch(SEI->getLoc(), Dest);
17991800

test/SILOptimizer/simplify_cfg_ossa.sil

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// RUN: %target-sil-opt -sil-print-types -enable-objc-interop -enable-sil-verify-all %s -simplify-cfg | %FileCheck %s
1+
// RUN: %target-sil-opt -sil-print-types -enable-objc-interop -enable-experimental-feature MoveOnlyEnumDeinits -enable-sil-verify-all %s -simplify-cfg | %FileCheck %s
2+
3+
// REQUIRES: swift_feature_MoveOnlyEnumDeinits
24

35
// OSSA form of tests from simplify_cfg.sil and simplify_cfg_simple.sil.
46
//
@@ -64,6 +66,12 @@ struct S {
6466
var b: NonTrivial
6567
}
6668

69+
enum NCE: ~Copyable {
70+
case a
71+
case b(AnyObject)
72+
deinit
73+
}
74+
6775
///////////
6876
// Tests //
6977
///////////
@@ -1944,12 +1952,12 @@ bb3:
19441952
return %t : $()
19451953
}
19461954

1947-
// CHECK-LABEL: sil [ossa] @insert_compensating_destroy_in_switch_enum_destination_block :
1955+
// CHECK-LABEL: sil [ossa] @insert_compensating_endlifetime_in_switch_enum_destination_block :
19481956
// CHECK: bb0(%0 : @owned $Optional<AnyObject>):
1949-
// CHECK-NEXT: destroy_value %0
1957+
// CHECK-NEXT: end_lifetime %0
19501958
// CHECK-NEXT: tuple
1951-
// CHECK: } // end sil function 'insert_compensating_destroy_in_switch_enum_destination_block'
1952-
sil [ossa] @insert_compensating_destroy_in_switch_enum_destination_block : $@convention(thin) (@owned Optional<AnyObject>) -> () {
1959+
// CHECK: } // end sil function 'insert_compensating_endlifetime_in_switch_enum_destination_block'
1960+
sil [ossa] @insert_compensating_endlifetime_in_switch_enum_destination_block : $@convention(thin) (@owned Optional<AnyObject>) -> () {
19531961
bb0(%0 : @owned $Optional<AnyObject>):
19541962
switch_enum %0, case #Optional.none!enumelt: bb1, case #Optional.some!enumelt: bb2
19551963

@@ -1962,6 +1970,26 @@ bb2(%4 : @owned $AnyObject):
19621970
unreachable
19631971
}
19641972

1973+
// CHECK-LABEL: sil [ossa] @insert_compensating_endlifetime_in_switch_enum_destination_block2 :
1974+
// CHECK: bb0(%0 : @owned $NCE):
1975+
// CHECK-NEXT: %1 = drop_deinit %0
1976+
// CHECK-NEXT: end_lifetime %1
1977+
// CHECK-NEXT: tuple
1978+
// CHECK: } // end sil function 'insert_compensating_endlifetime_in_switch_enum_destination_block2'
1979+
sil [ossa] @insert_compensating_endlifetime_in_switch_enum_destination_block2 : $@convention(thin) (@owned NCE) -> () {
1980+
bb0(%0 : @owned $NCE):
1981+
%1 = drop_deinit %0
1982+
switch_enum %1, case #NCE.a!enumelt: bb1, case #NCE.b!enumelt: bb2
1983+
1984+
bb1:
1985+
%15 = tuple ()
1986+
return %15
1987+
1988+
bb2(%4 : @owned $AnyObject):
1989+
destroy_value %4
1990+
unreachable
1991+
}
1992+
19651993
// CHECK-LABEL: sil [ossa] @replace_phi_arg_with_borrowed_from_use :
19661994
// CHECK: bb3([[R:%.*]] : @reborrow $B):
19671995
// CHECK: bb6([[G:%.*]] : @guaranteed $E):

0 commit comments

Comments
 (0)