Skip to content

Commit 4b7297a

Browse files
committed
Update SILGen for unsafe mutate accessors
1 parent f8d9b89 commit 4b7297a

File tree

3 files changed

+196
-4
lines changed

3 files changed

+196
-4
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,11 @@ namespace {
12551255
if (!base.getType().isLoadable(SGF.F)) {
12561256
return base;
12571257
}
1258+
1259+
if (base.getValue()->getType().isTrivial(SGF.F)) {
1260+
return SGF.B.createLoadTrivial(loc, base);
1261+
}
1262+
12581263
auto result = SGF.B.createLoadBorrow(loc, base.getValue());
12591264
// Mark the load_borrow as unchecked. We can't stop the source code from
12601265
// trying to mutate or consume the same lvalue during this borrow, so

lib/SILGen/SILGenStmt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ bool SILGenFunction::emitGuaranteedReturn(
805805
// }
806806
if (afd->getAttrs().hasAttribute<UnsafeSelfDependentResultAttr>()) {
807807
auto regularLoc = RegularLocation::getAutoGeneratedLocation();
808-
auto resultMV = emitBorrowedLValue(regularLoc, std::move(lvalue));
808+
auto resultMV = emitRawProjectedLValue(regularLoc, std::move(lvalue));
809809
SILValue result = resultMV.getValue();
810810
if (resultMV.getType().isAddress() &&
811811
F.getConventions().hasGuaranteedResult()) {

test/SILGen/borrow_accessor_container.swift

Lines changed: 190 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN:%target-swift-frontend -emit-silgen %s -verify -enable-experimental-feature BorrowAndMutateAccessors | %FileCheck %s
1+
// RUN:%target-swift-frontend -emit-silgen %s -verify -enable-experimental-feature BorrowAndMutateAccessors -disable-experimental-parser-round-trip | %FileCheck %s
22

33
// REQUIRES: swift_feature_BorrowAndMutateAccessors
44

@@ -11,6 +11,10 @@ public struct Container<Element: ~Copyable >: ~Copyable {
1111
borrow {
1212
return _storage.baseAddress.unsafelyUnwrapped.pointee
1313
}
14+
@_unsafeSelfDependentResult
15+
mutate {
16+
return &_storage.baseAddress.unsafelyUnwrapped.pointee
17+
}
1418
}
1519

1620
public subscript(index: Int) -> Element {
@@ -19,11 +23,72 @@ public struct Container<Element: ~Copyable >: ~Copyable {
1923
precondition(index >= 0 && index < _count, "Index out of bounds")
2024
return _storage.baseAddress.unsafelyUnwrapped.advanced(by: index).pointee
2125
}
26+
@_unsafeSelfDependentResult
27+
mutate {
28+
precondition(index >= 0 && index < _count, "Index out of bounds")
29+
return &_storage.baseAddress.unsafelyUnwrapped.advanced(by: index).pointee
30+
}
2231
}
2332
}
2433

2534
extension Container: Copyable where Element: Copyable {}
2635

36+
// CHECK: sil hidden [ossa] @$s25borrow_accessor_container9ContainerVAARi_zrlE5firstxvb : $@convention(method) <Element where Element : ~Copyable> (@guaranteed Container<Element>) -> @guaranteed_addr Element {
37+
// CHECK: bb0([[REG0:%.*]] : @guaranteed $Container<Element>):
38+
// CHECK: [[REG1:%.*]] = copy_value [[REG0]]
39+
// CHECK: [[REG2:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[REG1]]
40+
// CHECK: debug_value [[REG2]], let, name "self", argno 1
41+
// CHECK: [[REG4:%.*]] = begin_borrow [[REG2]]
42+
// CHECK: [[REG5:%.*]] = struct_extract [[REG0]], #Container._storage
43+
// CHECK: [[REG6:%.*]] = alloc_stack $Optional<UnsafeMutablePointer<Element>>
44+
// CHECK: [[REG7:%.*]] = function_ref @$sSr11baseAddressSpyxGSgvg : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutableBufferPointer<τ_0_0>) -> Optional<UnsafeMutablePointer<τ_0_0>>
45+
// CHECK: [[REG8:%.*]] = apply [[REG7]]<Element>([[REG5]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutableBufferPointer<τ_0_0>) -> Optional<UnsafeMutablePointer<τ_0_0>>
46+
// CHECK: store [[REG8]] to [trivial] [[REG6]]
47+
// CHECK: [[REG10:%.*]] = alloc_stack $UnsafeMutablePointer<Element>
48+
// CHECK: [[REG11:%.*]] = function_ref @$sSq17unsafelyUnwrappedxvg : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed Optional<τ_0_0>) -> @lifetime(copy 0) @out τ_0_0
49+
// CHECK: [[REG12:%.*]] = apply [[REG11]]<UnsafeMutablePointer<Element>>([[REG10]], [[REG6]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed Optional<τ_0_0>) -> @lifetime(copy 0) @out τ_0_0
50+
// CHECK: [[REG13:%.*]] = load [trivial] [[REG10]]
51+
// CHECK: [[REG14:%.*]] = function_ref @$sSpsRi_zrlE7pointeexvlu : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutablePointer<τ_0_0>) -> UnsafePointer<τ_0_0>
52+
// CHECK: [[REG15:%.*]] = apply [[REG14]]<Element>([[REG13]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutablePointer<τ_0_0>) -> UnsafePointer<τ_0_0>
53+
// CHECK: [[REG16:%.*]] = struct_extract [[REG15]], #UnsafePointer._rawValue
54+
// CHECK: [[REG17:%.*]] = pointer_to_address [[REG16]] to [strict] $*Element
55+
// CHECK: [[REG18:%.*]] = mark_dependence [unresolved] [[REG17]] on [[REG13]]
56+
// CHECK: [[REG19:%.*]] = begin_access [read] [unsafe] [[REG18]]
57+
// CHECK: [[REG20:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[REG19]]
58+
// CHECK: end_access [[REG19]]
59+
// CHECK: dealloc_stack [[REG10]]
60+
// CHECK: dealloc_stack [[REG6]]
61+
// CHECK: end_borrow [[REG4]]
62+
// CHECK: destroy_value [[REG2]]
63+
// CHECK: return [[REG20]]
64+
// CHECK: }
65+
66+
// CHECK: sil hidden [ossa] @$s25borrow_accessor_container9ContainerVAARi_zrlE5firstxvz : $@convention(method) <Element where Element : ~Copyable> (@inout Container<Element>) -> @guaranteed_addr Element {
67+
// CHECK: bb0([[REG0:%.*]] : $*Container<Element>):
68+
// CHECK: debug_value [[REG0]], var, name "self", argno 1, expr op_deref
69+
// CHECK: [[REG2:%.*]] = mark_unresolved_non_copyable_value [consumable_and_assignable] [[REG0]]
70+
// CHECK: [[REG3:%.*]] = struct_element_addr [[REG2]], #Container._storage
71+
// CHECK: [[REG4:%.*]] = load [trivial] [[REG3]]
72+
// CHECK: [[REG5:%.*]] = alloc_stack $Optional<UnsafeMutablePointer<Element>>
73+
// CHECK: [[REG6:%.*]] = function_ref @$sSr11baseAddressSpyxGSgvg : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutableBufferPointer<τ_0_0>) -> Optional<UnsafeMutablePointer<τ_0_0>>
74+
// CHECK: [[REG7:%.*]] = apply [[REG6]]<Element>([[REG4]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutableBufferPointer<τ_0_0>) -> Optional<UnsafeMutablePointer<τ_0_0>>
75+
// CHECK: store [[REG7]] to [trivial] [[REG5]]
76+
// CHECK: [[REG9:%.*]] = alloc_stack $UnsafeMutablePointer<Element>
77+
// CHECK: [[REG10:%.*]] = function_ref @$sSq17unsafelyUnwrappedxvg : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed Optional<τ_0_0>) -> @lifetime(copy 0) @out τ_0_0
78+
// CHECK: [[REG11:%.*]] = apply [[REG10]]<UnsafeMutablePointer<Element>>([[REG9]], [[REG5]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed Optional<τ_0_0>) -> @lifetime(copy 0) @out τ_0_0
79+
// CHECK: [[REG12:%.*]] = load [trivial] [[REG9]]
80+
// CHECK: [[REG13:%.*]] = function_ref @$sSpsRi_zrlE7pointeexvau : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutablePointer<τ_0_0>) -> UnsafeMutablePointer<τ_0_0>
81+
// CHECK: [[REG14:%.*]] = apply [[REG13]]<Element>([[REG12]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutablePointer<τ_0_0>) -> UnsafeMutablePointer<τ_0_0>
82+
// CHECK: [[REG15:%.*]] = struct_extract [[REG14]], #UnsafeMutablePointer._rawValue
83+
// CHECK: [[REG16:%.*]] = pointer_to_address [[REG15]] to [strict] $*Element
84+
// CHECK: [[REG17:%.*]] = mark_dependence [unresolved] [[REG16]] on [[REG12]]
85+
// CHECK: [[REG18:%.*]] = begin_access [modify] [unsafe] [[REG17]]
86+
// CHECK: [[REG19:%.*]] = mark_unresolved_non_copyable_value [consumable_and_assignable] [[REG18]]
87+
// CHECK: end_access [[REG18]]
88+
// CHECK: dealloc_stack [[REG9]]
89+
// CHECK: dealloc_stack [[REG5]]
90+
// CHECK: return [[REG19]]
91+
// CHECK: }
2792

2893
// CHECK: sil [ossa] @$s25borrow_accessor_container9ContainerVAARi_zrlEyxSicib : $@convention(method) <Element where Element : ~Copyable> (Int, @guaranteed Container<Element>) -> @guaranteed_addr Element {
2994
// CHECK: bb0([[REG0:%.*]] : $Int, [[REG1:%.*]] : @guaranteed $Container<Element>):
@@ -61,7 +126,45 @@ extension Container: Copyable where Element: Copyable {}
61126
// CHECK: destroy_value [[REG4]]
62127
// CHECK: return [[REG32]]
63128
// CHECK: }
64-
129+
130+
// CHECK: sil [ossa] @$s25borrow_accessor_container9ContainerVAARi_zrlEyxSiciz : $@convention(method) <Element where Element : ~Copyable> (Int, @inout Container<Element>) -> @guaranteed_addr Element {
131+
// CHECK: bb0([[REG0:%.*]] : $Int, [[REG1:%.*]] : $*Container<Element>):
132+
// CHECK: debug_value [[REG0]], let, name "index", argno 1
133+
// CHECK: debug_value [[REG1]], var, name "self", argno 2, expr op_deref
134+
// CHECK: [[REG4:%.*]] = mark_unresolved_non_copyable_value [consumable_and_assignable] [[REG1]]
135+
// CHECK: [[REG5:%.*]] = alloc_stack $UnsafeMutablePointer<Element>
136+
// CHECK: [[REG6:%.*]] = begin_access [read] [unknown] [[REG4]]
137+
// CHECK: [[REG7:%.*]] = struct_element_addr [[REG6]], #Container._storage
138+
// CHECK: [[REG8:%.*]] = load [trivial] [[REG7]]
139+
// CHECK: end_access [[REG6]]
140+
// CHECK: [[REG10:%.*]] = function_ref @$sSr11baseAddressSpyxGSgvg : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutableBufferPointer<τ_0_0>) -> Optional<UnsafeMutablePointer<τ_0_0>>
141+
// CHECK: [[REG11:%.*]] = apply [[REG10]]<Element>([[REG8]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutableBufferPointer<τ_0_0>) -> Optional<UnsafeMutablePointer<τ_0_0>>
142+
// CHECK: [[REG12:%.*]] = alloc_stack $Optional<UnsafeMutablePointer<Element>>
143+
// CHECK: store [[REG11]] to [trivial] [[REG12]]
144+
// CHECK: [[REG14:%.*]] = alloc_stack $UnsafeMutablePointer<Element>
145+
// CHECK: [[REG15:%.*]] = function_ref @$sSq17unsafelyUnwrappedxvg : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed Optional<τ_0_0>) -> @lifetime(copy 0) @out τ_0_0
146+
// CHECK: [[REG16:%.*]] = apply [[REG15]]<UnsafeMutablePointer<Element>>([[REG14]], [[REG12]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed Optional<τ_0_0>) -> @lifetime(copy 0) @out τ_0_0
147+
// CHECK: [[REG17:%.*]] = load [trivial] [[REG14]]
148+
// CHECK: [[REG18:%.*]] = alloc_stack $UnsafeMutablePointer<Element>
149+
// CHECK: store [[REG17]] to [trivial] [[REG18]]
150+
// CHECK: [[REG20:%.*]] = function_ref @$ss8_PointerPsE8advanced2byxSi_tF : $@convention(method) <τ_0_0 where τ_0_0 : _Pointer> (Int, @in_guaranteed τ_0_0) -> @out τ_0_0
151+
// CHECK: [[REG21:%.*]] = apply [[REG20]]<UnsafeMutablePointer<Element>>([[REG5]], [[REG0]], [[REG18]]) : $@convention(method) <τ_0_0 where τ_0_0 : _Pointer> (Int, @in_guaranteed τ_0_0) -> @out τ_0_0
152+
// CHECK: dealloc_stack [[REG18]]
153+
// CHECK: dealloc_stack [[REG14]]
154+
// CHECK: dealloc_stack [[REG12]]
155+
// CHECK: [[REG25:%.*]] = load [trivial] [[REG5]]
156+
// CHECK: [[REG26:%.*]] = function_ref @$sSpsRi_zrlE7pointeexvau : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutablePointer<τ_0_0>) -> UnsafeMutablePointer<τ_0_0>
157+
// CHECK: [[REG27:%.*]] = apply [[REG26]]<Element>([[REG25]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutablePointer<τ_0_0>) -> UnsafeMutablePointer<τ_0_0>
158+
// CHECK: [[REG28:%.*]] = struct_extract [[REG27]], #UnsafeMutablePointer._rawValue
159+
// CHECK: [[REG29:%.*]] = pointer_to_address [[REG28]] to [strict] $*Element
160+
// CHECK: [[REG30:%.*]] = mark_dependence [unresolved] [[REG29]] on [[REG25]]
161+
// CHECK: [[REG31:%.*]] = begin_access [modify] [unsafe] [[REG30]]
162+
// CHECK: [[REG32:%.*]] = mark_unresolved_non_copyable_value [consumable_and_assignable] [[REG31]]
163+
// CHECK: end_access [[REG31]]
164+
// CHECK: dealloc_stack [[REG5]]
165+
// CHECK: return [[REG32]]
166+
// CHECK: }
167+
65168
public class Klass {}
66169

67170
public struct S {
@@ -85,6 +188,11 @@ public struct CopyableContainer {
85188
precondition(index >= 0 && index < _count, "Index out of bounds")
86189
return _storage.baseAddress.unsafelyUnwrapped.advanced(by: index).pointee._k
87190
}
191+
@_unsafeSelfDependentResult
192+
mutate {
193+
precondition(index >= 0 && index < _count, "Index out of bounds")
194+
return &_storage.baseAddress.unsafelyUnwrapped.advanced(by: index).pointee._k
195+
}
88196
}
89197
}
90198

@@ -124,6 +232,43 @@ public struct CopyableContainer {
124232
// CHECK: return [[REG32]]
125233
// CHECK: }
126234

235+
// CHECK: sil [ossa] @$s25borrow_accessor_container17CopyableContainerVyAA5KlassCSiciz : $@convention(method) (Int, @inout CopyableContainer) -> @guaranteed_addr Klass {
236+
// CHECK: bb0([[REG0:%.*]] : $Int, [[REG1:%.*]] : $*CopyableContainer):
237+
// CHECK: debug_value [[REG0]], let, name "index", argno 1
238+
// CHECK: debug_value [[REG1]], var, name "self", argno 2, expr op_deref
239+
// CHECK: [[REG4:%.*]] = alloc_stack $UnsafeMutablePointer<S>
240+
// CHECK: [[REG5:%.*]] = begin_access [read] [unknown] [[REG1]]
241+
// CHECK: [[REG6:%.*]] = struct_element_addr [[REG5]], #CopyableContainer._storage
242+
// CHECK: [[REG7:%.*]] = load [trivial] [[REG6]]
243+
// CHECK: end_access [[REG5]]
244+
// CHECK: [[REG9:%.*]] = function_ref @$sSr11baseAddressSpyxGSgvg : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutableBufferPointer<τ_0_0>) -> Optional<UnsafeMutablePointer<τ_0_0>>
245+
// CHECK: [[REG10:%.*]] = apply [[REG9]]<S>([[REG7]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutableBufferPointer<τ_0_0>) -> Optional<UnsafeMutablePointer<τ_0_0>>
246+
// CHECK: [[REG11:%.*]] = alloc_stack $Optional<UnsafeMutablePointer<S>>
247+
// CHECK: store [[REG10]] to [trivial] [[REG11]]
248+
// CHECK: [[REG13:%.*]] = alloc_stack $UnsafeMutablePointer<S>
249+
// CHECK: [[REG14:%.*]] = function_ref @$sSq17unsafelyUnwrappedxvg : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed Optional<τ_0_0>) -> @lifetime(copy 0) @out τ_0_0
250+
// CHECK: [[REG15:%.*]] = apply [[REG14]]<UnsafeMutablePointer<S>>([[REG13]], [[REG11]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed Optional<τ_0_0>) -> @lifetime(copy 0) @out τ_0_0
251+
// CHECK: [[REG16:%.*]] = load [trivial] [[REG13]]
252+
// CHECK: [[REG17:%.*]] = alloc_stack $UnsafeMutablePointer<S>
253+
// CHECK: store [[REG16]] to [trivial] [[REG17]]
254+
// CHECK: [[REG19:%.*]] = function_ref @$ss8_PointerPsE8advanced2byxSi_tF : $@convention(method) <τ_0_0 where τ_0_0 : _Pointer> (Int, @in_guaranteed τ_0_0) -> @out τ_0_0
255+
// CHECK: [[REG20:%.*]] = apply [[REG19]]<UnsafeMutablePointer<S>>([[REG4]], [[REG0]], [[REG17]]) : $@convention(method) <τ_0_0 where τ_0_0 : _Pointer> (Int, @in_guaranteed τ_0_0) -> @out τ_0_0
256+
// CHECK: dealloc_stack [[REG17]]
257+
// CHECK: dealloc_stack [[REG13]]
258+
// CHECK: dealloc_stack [[REG11]]
259+
// CHECK: [[REG24:%.*]] = load [trivial] [[REG4]]
260+
// CHECK: [[REG25:%.*]] = function_ref @$sSpsRi_zrlE7pointeexvau : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutablePointer<τ_0_0>) -> UnsafeMutablePointer<τ_0_0>
261+
// CHECK: [[REG26:%.*]] = apply [[REG25]]<S>([[REG24]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutablePointer<τ_0_0>) -> UnsafeMutablePointer<τ_0_0>
262+
// CHECK: [[REG27:%.*]] = struct_extract [[REG26]], #UnsafeMutablePointer._rawValue
263+
// CHECK: [[REG28:%.*]] = pointer_to_address [[REG27]] to [strict] $*S
264+
// CHECK: [[REG29:%.*]] = mark_dependence [unresolved] [[REG28]] on [[REG24]]
265+
// CHECK: [[REG30:%.*]] = begin_access [modify] [unsafe] [[REG29]]
266+
// CHECK: [[REG31:%.*]] = struct_element_addr [[REG30]], #S._k
267+
// CHECK: end_access [[REG30]]
268+
// CHECK: dealloc_stack [[REG4]]
269+
// CHECK: return [[REG31]]
270+
// CHECK: }
271+
127272
public struct NC : ~Copyable {}
128273

129274
public struct NonCopyableContainer : ~Copyable {
@@ -143,6 +288,11 @@ public struct NonCopyableContainer : ~Copyable {
143288
precondition(index >= 0 && index < _count, "Index out of bounds")
144289
return _storage.baseAddress.unsafelyUnwrapped.advanced(by: index).pointee
145290
}
291+
@_unsafeSelfDependentResult
292+
mutate {
293+
precondition(index >= 0 && index < _count, "Index out of bounds")
294+
return &_storage.baseAddress.unsafelyUnwrapped.advanced(by: index).pointee
295+
}
146296
}
147297
}
148298

@@ -187,4 +337,41 @@ public struct NonCopyableContainer : ~Copyable {
187337
// CHECK: destroy_value [[REG4]]
188338
// CHECK: return [[REG36]]
189339
// CHECK: }
190-
340+
341+
// CHECK: sil [ossa] @$s25borrow_accessor_container20NonCopyableContainerVyAA2NCVSiciz : $@convention(method) (Int, @inout NonCopyableContainer) -> @guaranteed_addr NC {
342+
// CHECK: bb0([[REG0:%.*]] : $Int, [[REG1:%.*]] : $*NonCopyableContainer):
343+
// CHECK: debug_value [[REG0]], let, name "index", argno 1
344+
// CHECK: debug_value [[REG1]], var, name "self", argno 2, expr op_deref
345+
// CHECK: [[REG4:%.*]] = mark_unresolved_non_copyable_value [consumable_and_assignable] [[REG1]]
346+
// CHECK: [[REG5:%.*]] = alloc_stack $UnsafeMutablePointer<NC>
347+
// CHECK: [[REG6:%.*]] = begin_access [read] [unknown] [[REG4]]
348+
// CHECK: [[REG7:%.*]] = struct_element_addr [[REG6]], #NonCopyableContainer._storage
349+
// CHECK: [[REG8:%.*]] = load [trivial] [[REG7]]
350+
// CHECK: end_access [[REG6]]
351+
// CHECK: [[REG10:%.*]] = function_ref @$sSr11baseAddressSpyxGSgvg : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutableBufferPointer<τ_0_0>) -> Optional<UnsafeMutablePointer<τ_0_0>>
352+
// CHECK: [[REG11:%.*]] = apply [[REG10]]<NC>([[REG8]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutableBufferPointer<τ_0_0>) -> Optional<UnsafeMutablePointer<τ_0_0>>
353+
// CHECK: [[REG12:%.*]] = alloc_stack $Optional<UnsafeMutablePointer<NC>>
354+
// CHECK: store [[REG11]] to [trivial] [[REG12]]
355+
// CHECK: [[REG14:%.*]] = alloc_stack $UnsafeMutablePointer<NC>
356+
// CHECK: [[REG15:%.*]] = function_ref @$sSq17unsafelyUnwrappedxvg : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed Optional<τ_0_0>) -> @lifetime(copy 0) @out τ_0_0
357+
// CHECK: [[REG16:%.*]] = apply [[REG15]]<UnsafeMutablePointer<NC>>([[REG14]], [[REG12]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed Optional<τ_0_0>) -> @lifetime(copy 0) @out τ_0_0
358+
// CHECK: [[REG17:%.*]] = load [trivial] [[REG14]]
359+
// CHECK: [[REG18:%.*]] = alloc_stack $UnsafeMutablePointer<NC>
360+
// CHECK: store [[REG17]] to [trivial] [[REG18]]
361+
// CHECK: [[REG20:%.*]] = function_ref @$ss8_PointerPsE8advanced2byxSi_tF : $@convention(method) <τ_0_0 where τ_0_0 : _Pointer> (Int, @in_guaranteed τ_0_0) -> @out τ_0_0
362+
// CHECK: [[REG21:%.*]] = apply [[REG20]]<UnsafeMutablePointer<NC>>([[REG5]], [[REG0]], [[REG18]]) : $@convention(method) <τ_0_0 where τ_0_0 : _Pointer> (Int, @in_guaranteed τ_0_0) -> @out τ_0_0
363+
// CHECK: dealloc_stack [[REG18]]
364+
// CHECK: dealloc_stack [[REG14]]
365+
// CHECK: dealloc_stack [[REG12]]
366+
// CHECK: [[REG25:%.*]] = load [trivial] [[REG5]]
367+
// CHECK: [[REG26:%.*]] = function_ref @$sSpsRi_zrlE7pointeexvau : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutablePointer<τ_0_0>) -> UnsafeMutablePointer<τ_0_0>
368+
// CHECK: [[REG27:%.*]] = apply [[REG26]]<NC>([[REG25]]) : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafeMutablePointer<τ_0_0>) -> UnsafeMutablePointer<τ_0_0>
369+
// CHECK: [[REG28:%.*]] = struct_extract [[REG27]], #UnsafeMutablePointer._rawValue
370+
// CHECK: [[REG29:%.*]] = pointer_to_address [[REG28]] to [strict] $*NC
371+
// CHECK: [[REG30:%.*]] = mark_dependence [unresolved] [[REG29]] on [[REG25]]
372+
// CHECK: [[REG31:%.*]] = begin_access [modify] [unsafe] [[REG30]]
373+
// CHECK: [[REG32:%.*]] = mark_unresolved_non_copyable_value [consumable_and_assignable] [[REG31]]
374+
// CHECK: end_access [[REG31]]
375+
// CHECK: dealloc_stack [[REG5]]
376+
// CHECK: return [[REG32]]
377+
// CHECK: }

0 commit comments

Comments
 (0)