Skip to content

Commit e215ae9

Browse files
committed
CopyToBorrowOptimization: correctly handle unchecked_enum_data
A `unchecked_enum_data` which extracts a trivial payload out of a non-trivial enum ends the lifetime of its owned operand. Fixes an ownership verification error rdar://142644731
1 parent a4c675e commit e215ae9

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CopyToBorrowOptimization.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ private struct Uses {
185185
for succ in termInst.successors where !succ.arguments.contains(where: {$0.ownership == .owned}) {
186186
nonDestroyingLiverangeExits.append(succ.instructions.first!)
187187
}
188+
} else if !forwardingInst.forwardedResults.contains(where: { $0.ownership == .owned }) {
189+
// The forwarding instruction has no owned result, which means it ends the lifetime of its owned operand.
190+
// This can happen with an `unchecked_enum_data` which extracts a trivial payload out of a
191+
// non-trivial enum.
192+
nonDestroyingLiverangeExits.append(forwardingInst.next!)
188193
}
189194
}
190195

test/SILOptimizer/copy-to-borrow-optimization.sil

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,3 +2146,16 @@ bb3:
21462146
%r = tuple ()
21472147
return %r
21482148
}
2149+
2150+
// CHECK-LABEL: sil [ossa] @lifetime_ending_enum_data :
2151+
// CHECK: %1 = load_borrow %0
2152+
// CHECK-NEXT: %2 = unchecked_enum_data %1
2153+
// CHECK-NEXT: end_borrow %1
2154+
// CHECK: } // end sil function 'lifetime_ending_enum_data'
2155+
sil [ossa] @lifetime_ending_enum_data : $@convention(method) (@in_guaranteed MultiPayload) -> MyInt {
2156+
bb0(%0 : $*MultiPayload):
2157+
%1 = load [copy] %0
2158+
%2 = unchecked_enum_data %1, #MultiPayload.b!enumelt
2159+
return %2
2160+
}
2161+

0 commit comments

Comments
 (0)