Skip to content

Commit c5b14c2

Browse files
committed
BorrowUtils: make unchecked_ownership_conversion to guaranteed ownership a BeginBorrowValue
BeginBorrowValue needs to handle all cases where a guaranteed value is produced. Fixes a compiler crash.
1 parent 43b6fd4 commit c5b14c2

File tree

4 files changed

+36
-10
lines changed

4 files changed

+36
-10
lines changed

SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ private enum ImmutableScope {
648648
self = .borrow(singleBorrowIntroducer)
649649
case .functionArgument:
650650
self = .wholeFunction
651-
case .beginApply:
651+
case .beginApply, .uncheckOwnershipConversion:
652652
return nil
653653
}
654654
}

SwiftCompilerSources/Sources/Optimizer/Utilities/BorrowUtils.swift

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
270270
}
271271

272272
/// A value that introduces a borrow scope:
273-
/// begin_borrow, load_borrow, reborrow, guaranteed function argument.
273+
/// begin_borrow, load_borrow, reborrow, guaranteed function argument, begin_apply, unchecked_ownership_conversion.
274274
///
275275
/// If the value introduces a local scope, then that scope is
276276
/// terminated by scope ending operands. Function arguments do not
@@ -280,19 +280,22 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
280280
/// one of the yielded values. In any case, the scope ending operands
281281
/// are on the end_apply or abort_apply instructions that use the
282282
/// token.
283-
///
284-
/// Note: equivalent to C++ BorrowedValue, but also handles begin_apply.
285283
enum BeginBorrowValue {
286284
case beginBorrow(BeginBorrowInst)
287285
case loadBorrow(LoadBorrowInst)
288286
case beginApply(Value)
287+
case uncheckOwnershipConversion(UncheckedOwnershipConversionInst)
289288
case functionArgument(FunctionArgument)
290289
case reborrow(Phi)
291290

292291
init?(_ value: Value) {
293292
switch value {
294-
case let bbi as BeginBorrowInst: self = .beginBorrow(bbi)
295-
case let lbi as LoadBorrowInst: self = .loadBorrow(lbi)
293+
case let bbi as BeginBorrowInst:
294+
self = .beginBorrow(bbi)
295+
case let lbi as LoadBorrowInst:
296+
self = .loadBorrow(lbi)
297+
case let uoci as UncheckedOwnershipConversionInst where uoci.ownership == .guaranteed:
298+
self = .uncheckOwnershipConversion(uoci)
296299
case let arg as FunctionArgument where arg.ownership == .guaranteed:
297300
self = .functionArgument(arg)
298301
case let arg as Argument where arg.isReborrow:
@@ -311,6 +314,7 @@ enum BeginBorrowValue {
311314
case .beginBorrow(let bbi): return bbi
312315
case .loadBorrow(let lbi): return lbi
313316
case .beginApply(let v): return v
317+
case .uncheckOwnershipConversion(let uoci): return uoci
314318
case .functionArgument(let arg): return arg
315319
case .reborrow(let phi): return phi.value
316320
}
@@ -347,7 +351,7 @@ enum BeginBorrowValue {
347351

348352
var hasLocalScope: Bool {
349353
switch self {
350-
case .beginBorrow, .loadBorrow, .beginApply, .reborrow:
354+
case .beginBorrow, .loadBorrow, .beginApply, .reborrow, .uncheckOwnershipConversion:
351355
return true
352356
case .functionArgument:
353357
return false
@@ -364,7 +368,7 @@ enum BeginBorrowValue {
364368
return beginBorrow.operand
365369
case let .loadBorrow(loadBorrow):
366370
return loadBorrow.operand
367-
case .beginApply, .functionArgument, .reborrow:
371+
case .beginApply, .functionArgument, .reborrow, .uncheckOwnershipConversion:
368372
return nil
369373
}
370374
}
@@ -452,7 +456,7 @@ final class EnclosingValueIterator : IteratorProtocol {
452456
case let .beginBorrow(bbi):
453457
// Gather the outer enclosing borrow scope.
454458
worklist.pushIfNotVisited(bbi.borrowedValue)
455-
case .loadBorrow, .beginApply, .functionArgument:
459+
case .loadBorrow, .beginApply, .functionArgument, .uncheckOwnershipConversion:
456460
// There is no enclosing value on this path.
457461
break
458462
case .reborrow(let phi):

SwiftCompilerSources/Sources/Optimizer/Utilities/LifetimeDependenceUtils.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,9 @@ extension LifetimeDependence.Scope {
373373
self = .yield(value)
374374
case let .functionArgument(arg):
375375
self = .caller(arg)
376+
case .uncheckOwnershipConversion:
377+
// TODO: is this correct?
378+
self = Self(variable: base, context)
376379
case .reborrow:
377380
fatalError("reborrows are not supported in diagnostics")
378381
}

test/SILOptimizer/borrow_introducer_unit.sil

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
//
33
// REQUIRES: swift_in_compiler
44

5-
sil_stage raw
5+
sil_stage canonical
66

77
import Builtin
8+
import Swift
89

910
struct Trivial {
1011
var value: Builtin.Int32
@@ -430,3 +431,21 @@ bb4(%outer0 : @owned $C, %outer1 : @owned $C, %inner : @guaranteed $C):
430431
%99 = tuple()
431432
return %99 : $()
432433
}
434+
435+
// CHECK-LABEL: Borrow introducers for: %3 = unchecked_ownership_conversion %2
436+
// CHECK-NEXT: %3 = unchecked_ownership_conversion %2
437+
// CHECK-NEXT: end running test 1 of 2 on testUncheckedOwnershipConversion: borrow_introducers with: %3
438+
// CHECK-LABEL: Enclosing values for: %3 = unchecked_ownership_conversion %2
439+
// CHECK-NEXT: end running test 2 of 2 on testUncheckedOwnershipConversion: enclosing_values with: %3
440+
sil [ossa] @testUncheckedOwnershipConversion : $@convention(thin) (Unmanaged<C>) -> () {
441+
bb0(%0 : $Unmanaged<C>):
442+
%1 = struct_extract %0, #Unmanaged._value
443+
%2 = unmanaged_to_ref %1 to $C
444+
%3 = unchecked_ownership_conversion %2, @unowned to @guaranteed
445+
specify_test "borrow_introducers %3"
446+
specify_test "enclosing_values %3"
447+
end_borrow %3
448+
%8 = tuple ()
449+
return %8
450+
}
451+

0 commit comments

Comments
 (0)