[SILGen] Used move_value for lexical lets.

Instead of using begin_borrow [lexical] + copy_value.
This commit is contained in:
Nate Chandler
2023-03-30 17:16:05 -07:00
parent 673c03bba1
commit 10ce0c6b16
42 changed files with 335 additions and 240 deletions

View File

@@ -847,11 +847,18 @@ public:
}
// Otherwise, if we do not have a no implicit copy variable, just follow
// the "normal path": perform a lexical borrow if the lifetime is lexical.
return SGF.B.createBeginBorrow(
PrologueLoc, value,
/*isLexical=*/SGF.F.getLifetime(vd, value->getType()).isLexical(),
/*hasPointerEscape=*/false, /*fromVarDecl=*/true);
// the "normal path".
auto isLexical = SGF.F.getLifetime(vd, value->getType()).isLexical();
if (value->getOwnershipKind() == OwnershipKind::Owned)
return SGF.B.createMoveValue(PrologueLoc, value, /*isLexical*/ isLexical,
/*hasPointerEscape=*/false,
/*fromVarDecl=*/true);
return SGF.B.createBeginBorrow(PrologueLoc, value, /*isLexical*/ isLexical,
/*hasPointerEscape=*/false,
/*fromVarDecl=*/true);
}
void bindValue(SILValue value, SILGenFunction &SGF, bool wasPlusOne,
@@ -2177,6 +2184,11 @@ void SILGenFunction::destroyLocalVariable(SILLocation silLoc, VarDecl *vd) {
return;
}
if (auto *mvi = dyn_cast<MoveValueInst>(Val.getDefiningInstruction())) {
B.emitDestroyValueOperation(silLoc, mvi);
return;
}
if (auto *mvi = dyn_cast<MarkUnresolvedNonCopyableValueInst>(
Val.getDefiningInstruction())) {
if (mvi->hasMoveCheckerKind()) {

View File

@@ -508,6 +508,7 @@ public func reflect<T: Error>(error: T) {
let error: Error = error
let errorPointerValue = unsafeBitCast(error, to: UInt.self)
reflect(instanceAddress: errorPointerValue, kind: .ErrorExistential)
withExtendedLifetime(error) {}
}
// Like reflect<T: Error>(error: T), but calls projectExistentialAndUnwrapClass
@@ -523,6 +524,7 @@ public func reflectUnwrappingClassExistential<T: Error>(error: T) {
kind: .ErrorExistential,
shouldUnwrapClassExistential: true)
anyPointer.deallocate()
withExtendedLifetime(error) {}
}
// Reflect an `Enum`

View File

@@ -96,8 +96,10 @@ func test_context_builtins_with_type<T>(t: T) {
// CHECK-LABEL: sil{{.*}}@test_context_builtins_with_type : $@convention(thin) <T> (@in_guaranteed T) -> () {
// CHECK: bb0({{%.*}} : $*T):
// CHECK: [[CTX:%.*]] = builtin "autoDiffCreateLinearMapContextWithType"<T>({{%.*}} : $@thick T.Type) : $Builtin.NativeObject // users: {{.*}}
// CHECK: [[BORROWED_CTX:%.*]] = begin_borrow [lexical] [var_decl] [[CTX]] : $Builtin.NativeObject // users: {{.*}}
// CHECK: [[CTX:%.*]] = builtin "autoDiffCreateLinearMapContextWithType"<T>({{%.*}} : $@thick T.Type) : $Builtin.NativeObject
// CHECK: [[CTX_LIFETIME:%.*]] = move_value [lexical] [var_decl] [[CTX]]
// CHECK: [[BORROWED_CTX:%.*]] = begin_borrow [[CTX_LIFETIME]]
// CHECK: [[BUF:%.*]] = builtin "autoDiffProjectTopLevelSubcontext"([[BORROWED_CTX]] : $Builtin.NativeObject) : $Builtin.RawPointer // users: {{.*}}
// CHECK: [[BORROWED_CTX:%.*]] = begin_borrow [[CTX_LIFETIME]]
// CHECK: [[BUF:%.*]] = builtin "autoDiffAllocateSubcontextWithType"<T>([[BORROWED_CTX]] : $Builtin.NativeObject, {{.*}} : $@thick T.Type) : $Builtin.RawPointer // users: {{.*}}
// CHECK: destroy_value [[CTX]]
// CHECK: destroy_value [[CTX_LIFETIME]]

View File

@@ -15,7 +15,7 @@ public class S {
// CHECK: debug_value {{.*}} : $Optional<C>, let, name "x", {{.*}}, scope [[X1]]
// CHECK: debug_value {{.*}} : $C, let, name "x", {{.*}}, scope [[X2]]
// FIXME: This source location is a little wild.
// CHECK-NEXT: strong_retain{{.*}}:[[@LINE+4]]:12, scope [[X2]]
// CHECK-NEXT: release_value{{.*}}:[[@LINE+5]]:3, scope [[X2]]
throw MyError()
// CHECK: function_ref {{.*}}MyError{{.*}}:[[@LINE-1]]:13, scope [[GUARD]]
}

View File

@@ -68,7 +68,8 @@ public func foo(_ x: Double) {
// CHECK: [[ZVAL:%.*]] = load [trivial] [[READ]]
// CHECK: [[THUNK:%.*]] = function_ref @$s10cf_members3fooyySdFSo10IAMStruct1VSdcADcfu0_ : $@convention(thin) (Struct1) -> @owned @callee_guaranteed (Double) -> Struct1
// CHECK: [[C:%.*]] = apply [[THUNK]]([[ZVAL]])
// CHECK: [[BORROWED_C:%.*]] = begin_borrow [lexical] [var_decl] [[C]]
// CHECK: [[C_MOVE:%.*]] = move_value [lexical] [var_decl] [[C]]
// CHECK: [[BORROWED_C:%.*]] = begin_borrow [[C_MOVE]]
// CHECK: [[C_COPY:%.*]] = copy_value [[BORROWED_C]]
// CHECK: [[BORROWED_C2:%.*]] = begin_borrow [[C_COPY]]
let c: (Double) -> Struct1 = z.translate(radians:)
@@ -102,7 +103,8 @@ public func foo(_ x: Double) {
// CHECK: [[ZVAL:%.*]] = load [trivial] [[READ]]
// CHECK: [[THUNK:%.*]] = function_ref @$s10cf_members3fooyySdFSo10IAMStruct1VSdcADcfu4_ : $@convention(thin) (Struct1) -> @owned @callee_guaranteed (Double) -> Struct1
// CHECK: [[F:%.*]] = apply [[THUNK]]([[ZVAL]])
// CHECK: [[BORROWED_F:%.*]] = begin_borrow [lexical] [var_decl] [[F]]
// CHECK: [[MOVED_F:%.*]] = move_value [lexical] [var_decl] [[F]]
// CHECK: [[BORROWED_F:%.*]] = begin_borrow [[MOVED_F]]
// CHECK: [[F_COPY:%.*]] = copy_value [[BORROWED_F]]
// CHECK: [[BORROWED_F2:%.*]] = begin_borrow [[F_COPY]]
let f = z.scale

View File

@@ -494,14 +494,15 @@ class SuperSub : SuperBase {
// CHECK: [[INNER:%.*]] = function_ref @[[INNER_FUNC_1:\$s8closures8SuperSubC1c[_0-9a-zA-Z]*]] : $@convention(thin) (@guaranteed SuperSub) -> ()
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
// CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[INNER]]([[SELF_COPY]])
// CHECK: [[BORROWED_PA:%.*]] = begin_borrow [lexical] [var_decl] [[PA]]
// CHECK: [[PA_COPY:%.*]] = copy_value [[BORROWED_PA]]
// CHECK: [[B:%.*]] = begin_borrow [[PA_COPY]]
// CHECK: apply [[B]]()
// CHECK: [[MOVED_PA:%.*]] = move_value [lexical] [var_decl] [[PA]]
// CHECK: [[B:%.*]] = begin_borrow [[MOVED_PA]]
// CHECK: [[B_COPY:%.*]] = copy_value [[B]]
// CHECK: [[B2:%.*]] = begin_borrow [[B_COPY]]
// CHECK: apply [[B2]]()
// CHECK: end_borrow [[B2]]
// CHECK: destroy_value [[B_COPY]]
// CHECK: end_borrow [[B]]
// CHECK: destroy_value [[PA_COPY]]
// CHECK: end_borrow [[BORROWED_PA]]
// CHECK: destroy_value [[PA]]
// CHECK: destroy_value [[MOVED_PA]]
// CHECK: } // end sil function '$s8closures8SuperSubC1cyyF'
func c() {
// CHECK: sil private [ossa] @[[INNER_FUNC_1]] : $@convention(thin) (@guaranteed SuperSub) -> ()
@@ -526,14 +527,15 @@ class SuperSub : SuperBase {
// CHECK: [[INNER:%.*]] = function_ref @[[INNER_FUNC_1:\$s8closures8SuperSubC1d[_0-9a-zA-Z]*]] : $@convention(thin) (@guaranteed SuperSub) -> ()
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
// CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[INNER]]([[SELF_COPY]])
// CHECK: [[BORROWED_PA:%.*]] = begin_borrow [lexical] [var_decl] [[PA]]
// CHECK: [[PA_COPY:%.*]] = copy_value [[BORROWED_PA]]
// CHECK: [[B:%.*]] = begin_borrow [[PA_COPY]]
// CHECK: apply [[B]]()
// CHECK: end_borrow [[B]]
// CHECK: destroy_value [[PA_COPY]]
// CHECK: end_borrow [[BORROWED_PA]]
// CHECK: destroy_value [[PA]]
// CHECK: [[MOVED_PA:%.*]] = move_value [lexical] [var_decl] [[PA]]
// CHECK: [[B:%.*]] = begin_borrow [[MOVED_PA]]
// CHECK: [[PA_COPY:%.*]] = copy_value [[B]]
// CHECK: [[B2:%.*]] = begin_borrow [[PA_COPY]]
// CHECK: apply [[B2]]()
// CHECK: end_borrow [[B2]]
// CHECK: destroy_value [[B_COPY]]
// CHECK: end_borrow [[B]]
// CHECK: destroy_value [[MOVED_PA]]
// CHECK: } // end sil function '$s8closures8SuperSubC1dyyF'
func d() {
// CHECK: sil private [ossa] @[[INNER_FUNC_1]] : $@convention(thin) (@guaranteed SuperSub) -> () {
@@ -569,14 +571,15 @@ class SuperSub : SuperBase {
// CHECK: [[INNER:%.*]] = function_ref @[[INNER_FUNC_NAME2:\$s8closures8SuperSubC1e.*]] : $@convention(thin)
// CHECK: [[ARG_COPY:%.*]] = copy_value [[ARG]]
// CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[INNER]]([[ARG_COPY]])
// CHECK: [[BORROWED_PA:%.*]] = begin_borrow [lexical] [var_decl] [[PA]]
// CHECK: [[PA_COPY:%.*]] = copy_value [[BORROWED_PA]]
// CHECK: [[B:%.*]] = begin_borrow [[PA_COPY]]
// CHECK: apply [[B]]() : $@callee_guaranteed () -> ()
// CHECK: end_borrow [[B]]
// CHECK: destroy_value [[PA_COPY]]
// CHECK: end_borrow [[BORROWED_PA]]
// CHECK: destroy_value [[PA]]
// CHECK: [[MOVED_PA:%.*]] = move_value [lexical] [var_decl] [[PA]]
// CHECK: [[B:%.*]] = begin_borrow [[MOVED_PA]]
// CHECK: [[PA_COPY:%.*]] = copy_value [[B]]
// CHECK: [[B2:%.*]] = begin_borrow [[PA_COPY]]
// CHECK: apply [[B2]]()
// CHECK: end_borrow [[B2]]
// CHECK: destroy_value [[B_COPY]]
// CHECK: end_borrow [[B]]
// CHECK: destroy_value [[MOVED_PA]]
// CHECK: } // end sil function '[[INNER_FUNC_NAME1]]'
func e1() {
// CHECK: sil private [ossa] @[[INNER_FUNC_NAME2]] : $@convention(thin)
@@ -601,7 +604,8 @@ class SuperSub : SuperBase {
// CHECK: [[INNER:%.*]] = function_ref @[[INNER_FUNC_1:\$s8closures8SuperSubC1fyyFyycfU_]] : $@convention(thin) (@guaranteed SuperSub) -> ()
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
// CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[INNER]]([[SELF_COPY]])
// CHECK: destroy_value [[PA]]
// CHECK: [[MOVED_PA:%.*]] = move_value [lexical] [var_decl] [[PA]]
// CHECK: destroy_value [[MOVED_PA]]
// CHECK: } // end sil function '$s8closures8SuperSubC1fyyF'
func f() {
// CHECK: sil private [ossa] @[[INNER_FUNC_1]] : $@convention(thin) (@guaranteed SuperSub) -> () {

View File

@@ -47,7 +47,8 @@ func testArrayUpcast(_ array: [BridgedObjC]) {
// CHECK: [[ARRAY_COPY:%.*]] = copy_value [[ARRAY]]
// CHECK: [[UPCAST_FN:%[0-9]+]] = function_ref @$ss15_arrayForceCast{{.*}}F : $@convention(thin) <τ_0_0, τ_0_1> (@guaranteed Array<τ_0_0>) -> @owned Array<τ_0_1>
// CHECK: [[RESULT:%.*]] = apply [[UPCAST_FN]]<BridgedObjC, AnyObject>([[ARRAY_COPY]]) : $@convention(thin) <τ_0_0, τ_0_1> (@guaranteed Array<τ_0_0>) -> @owned Array<τ_0_1>
// CHECK: destroy_value [[RESULT]]
// CHECK: [[RESULT_LIFETIME:%.*]] = move_value [var_decl] [[RESULT]]
// CHECK: destroy_value [[RESULT_LIFETIME]]
// CHECK-NOT: destroy_value [[ARRAY]]
let anyObjectArr: [AnyObject] = array
}
@@ -59,7 +60,8 @@ func testArrayUpcastBridged(_ array: [BridgedSwift]) {
// CHECK: [[ARRAY_COPY:%.*]] = copy_value [[ARRAY]]
// CHECK: [[BRIDGE_FN:%[0-9]+]] = function_ref @$ss15_arrayForceCast{{.*}}F : $@convention(thin) <τ_0_0, τ_0_1> (@guaranteed Array<τ_0_0>) -> @owned Array<τ_0_1>
// CHECK: [[RESULT:%.*]] = apply [[BRIDGE_FN]]<BridgedSwift, AnyObject>([[ARRAY_COPY]]) : $@convention(thin) <τ_0_0, τ_0_1> (@guaranteed Array<τ_0_0>) -> @owned Array<τ_0_1>
// CHECK: destroy_value [[RESULT]]
// CHECK: [[RESULT_LIFETIME:%.*]] = move_value [var_decl] [[RESULT]]
// CHECK: destroy_value [[RESULT_LIFETIME]]
// CHECK-NOT: destroy_value [[ARRAY]]
let anyObjectArr = array as [AnyObject]
}
@@ -71,7 +73,8 @@ func testDictionaryUpcast(_ dict: Dictionary<BridgedObjC, BridgedObjC>) {
// CHECK: [[DICT_COPY:%.*]] = copy_value [[DICT]]
// CHECK: [[UPCAST_FN:%[0-9]+]] = function_ref @$ss17_dictionaryUpCast{{.*}}F : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_0 : Hashable, τ_0_2 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned Dictionary<τ_0_2, τ_0_3>
// CHECK: [[RESULT:%.*]] = apply [[UPCAST_FN]]<BridgedObjC, BridgedObjC, NSObject, AnyObject>([[DICT_COPY]]) : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_0 : Hashable, τ_0_2 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned Dictionary<τ_0_2, τ_0_3>
// CHECK: destroy_value [[RESULT]]
// CHECK: [[RESULT_LIFETIME:%.*]] = move_value [var_decl] [[RESULT]]
// CHECK: destroy_value [[RESULT_LIFETIME]]
// CHECK-NOT: destroy_value [[DICT]]
let anyObjectDict: Dictionary<NSObject, AnyObject> = dict
}
@@ -82,7 +85,8 @@ func testDictionaryUpcastBridged(_ dict: Dictionary<BridgedSwift, BridgedSwift>)
// CHECK: [[DICT_COPY:%.*]] = copy_value [[DICT]]
// CHECK: [[BRIDGE_FN:%[0-9]+]] = function_ref @$ss17_dictionaryUpCast{{.*}}F
// CHECK: [[RESULT:%.*]] = apply [[BRIDGE_FN]]<BridgedSwift, BridgedSwift, NSObject, AnyObject>([[DICT_COPY]]) : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_0 : Hashable, τ_0_2 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned Dictionary<τ_0_2, τ_0_3>
// CHECK: destroy_value [[RESULT]]
// CHECK: [[RESULT_LIFETIME:%.*]] = move_value [var_decl] [[RESULT]]
// CHECK: destroy_value [[RESULT_LIFETIME]]
// CHECK-NOT: destroy_value [[DICT]]
let anyObjectDict = dict as Dictionary<NSObject, AnyObject>
}
@@ -93,7 +97,8 @@ func testSetUpcast(_ dict: Set<BridgedObjC>) {
// CHECK: [[SET_COPY:%.*]] = copy_value [[SET]]
// CHECK: [[BRIDGE_FN:%[0-9]+]] = function_ref @$ss10_setUpCast{{.*}}F : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Hashable, τ_0_1 : Hashable> (@guaranteed Set<τ_0_0>) -> @owned Set<τ_0_1>
// CHECK: [[RESULT:%.*]] = apply [[BRIDGE_FN]]<BridgedObjC, NSObject>([[SET_COPY]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Hashable, τ_0_1 : Hashable> (@guaranteed Set<τ_0_0>) -> @owned Set<τ_0_1>
// CHECK: destroy_value [[RESULT]]
// CHECK: [[RESULT_LIFETIME:%.*]] = move_value [var_decl] [[RESULT]]
// CHECK: destroy_value [[RESULT_LIFETIME]]
// CHECK-NOT: destroy_value [[SET]]
let anyObjectSet: Set<NSObject> = dict
}
@@ -104,7 +109,8 @@ func testSetUpcastBridged(_ set: Set<BridgedSwift>) {
// CHECK: [[SET_COPY:%.*]] = copy_value [[SET]]
// CHECK: [[BRIDGE_FN:%[0-9]+]] = function_ref @$ss10_setUpCast{{.*}}F
// CHECK: [[RESULT:%.*]] = apply [[BRIDGE_FN]]<BridgedSwift, NSObject>([[SET_COPY]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Hashable, τ_0_1 : Hashable> (@guaranteed Set<τ_0_0>) -> @owned Set<τ_0_1>
// CHECK: destroy_value [[RESULT]]
// CHECK: [[RESULT_LIFETIME:%.*]] = move_value [var_decl] [[RESULT]]
// CHECK: destroy_value [[RESULT_LIFETIME]]
// CHECK-NOT: destroy_value [[SET]]
let anyObjectSet = set as Set<NSObject>
}

View File

@@ -8,7 +8,8 @@ protocol P {
// CHECK-LABEL: sil hidden [ossa] @$s7consume15testLoadableLetyyF : $@convention(thin) () -> () {
// CHECK: [[ORIG_VALUE:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick Klass.Type) -> @owned Klass
// CHECK: [[BORROWED_VALUE:%.*]] = begin_borrow [lexical] [var_decl] [[ORIG_VALUE]]
// CHECK: [[MOVED_VALUE:%.*]] = move_value [lexical] [var_decl] [[ORIG_VALUE]]
// CHECK: [[BORROWED_VALUE:%.*]] = begin_borrow [[MOVED_VALUE]]
// CHECK: [[COPY:%.*]] = copy_value [[BORROWED_VALUE:%.*]]
// CHECK: move_value [allows_diagnostics] [[COPY]]
// CHECK: } // end sil function '$s7consume15testLoadableLetyyF'

View File

@@ -25,7 +25,8 @@ struct ContainKlass {
// CHECK-LABEL: sil hidden [ossa] @$s9copy_expr22testCopyLoadableRValueyyF : $@convention(thin) () -> () {
// CHECK: [[X:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thin ContainKlass.Type) -> @owned ContainKlass
// CHECK: [[BORROW:%.*]] = begin_borrow [lexical] [var_decl] [[X]]
// CHECK: [[MOVE:%.*]] = move_value [lexical] [var_decl] [[X]]
// CHECK: [[BORROW:%.*]] = begin_borrow [[MOVE]]
// CHECK: [[COPY_BORROW:%.*]] = copy_value [[BORROW]]
// CHECK: explicit_copy_value [[COPY_BORROW]]
// CHECK: } // end sil function '$s9copy_expr22testCopyLoadableRValueyyF'
@@ -114,7 +115,8 @@ func testCopyAddressOnlyLValueArg<T : P>(_ x: inout T) {
// CHECK-LABEL: sil hidden [ossa] @$s9copy_expr31testCallMethodOnLoadableLetCopyyyF : $@convention(thin) () -> () {
// CHECK: [[ORIG_X:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thin ContainKlass.Type) -> @owned ContainKlass
// CHECK: [[X:%.*]] = begin_borrow [lexical] [var_decl] [[ORIG_X]]
// CHECK: [[MOVE:%.*]] = move_value [lexical] [var_decl] [[ORIG_X]]
// CHECK: [[X:%.*]] = begin_borrow [[MOVE]]
//
// Calling consumeFunc.
// CHECK: [[COPY_X:%.*]] = copy_value [[X]]
@@ -124,6 +126,7 @@ func testCopyAddressOnlyLValueArg<T : P>(_ x: inout T) {
// CHECK: destroy_value [[COPY_X]]
//
// Calling borrowingFunc.
// CHECK: [[X:%.*]] = begin_borrow [[MOVE]]
// CHECK: [[COPY_X:%.*]] = copy_value [[X]]
// CHECK: [[EXPLICIT_COPY_X:%.*]] = explicit_copy_value [[COPY_X]]
// CHECK: [[FUNC:%.*]] = function_ref @$s9copy_expr12ContainKlassV13borrowingFuncyyF : $@convention(method) (@guaranteed ContainKlass) -> ()
@@ -132,6 +135,7 @@ func testCopyAddressOnlyLValueArg<T : P>(_ x: inout T) {
// CHECK: destroy_value [[COPY_X]]
//
// Calling computedK. It is borrowed.
// CHECK: [[X:%.*]] = begin_borrow [[MOVE]]
// CHECK: [[COPY_X:%.*]] = copy_value [[X]]
// CHECK: [[EXPLICIT_COPY_X:%.*]] = explicit_copy_value [[COPY_X]]
// CHECK: [[BORROW_EXPLICIT_COPY_X:%.*]] = begin_borrow [[EXPLICIT_COPY_X]]
@@ -142,6 +146,7 @@ func testCopyAddressOnlyLValueArg<T : P>(_ x: inout T) {
// CHECK: destroy_value [[COPY_X]]
//
// Calling computed getter.
// CHECK: [[X:%.*]] = begin_borrow [[MOVE]]
// CHECK: [[COPY_X:%.*]] = copy_value [[X]]
// CHECK: [[EXPLICIT_COPY_X:%.*]] = explicit_copy_value [[COPY_X]]
// CHECK: [[BORROW_EXPLICIT_COPY_X:%.*]] = begin_borrow [[EXPLICIT_COPY_X]]

View File

@@ -107,11 +107,12 @@ func dont_return<T>(_ argument: T) throws -> T {
// Catch HomeworkError.CatAteIt.
// CHECK: [[MATCH]]([[T0:%.*]] : @owned $Cat):
// CHECK-NEXT: [[BORROWED_T0:%.*]] = begin_borrow [lexical] [var_decl] [[T0]]
// CHECK-NEXT: debug_value [[BORROWED_T0]] : $Cat
// CHECK-NEXT: [[MOVED_T0:%.*]] = move_value [lexical] [var_decl] [[T0]]
// CHECK-NEXT: debug_value [[MOVED_T0]] : $Cat
// CHECK-NEXT: [[BORROWED_T0:%.*]] = begin_borrow [[MOVED_T0]]
// CHECK-NEXT: [[T0_COPY:%.*]] = copy_value [[BORROWED_T0]]
// CHECK-NEXT: end_borrow [[BORROWED_T0]]
// CHECK-NEXT: destroy_value [[T0]]
// CHECK-NEXT: destroy_value [[MOVED_T0]]
// CHECK-NEXT: dealloc_stack [[DEST_TEMP]]
// CHECK-NEXT: destroy_addr [[SRC_TEMP]]
// CHECK-NEXT: dealloc_stack [[SRC_TEMP]]
@@ -314,10 +315,9 @@ func all_together_now_four(_ flag: Bool) throws -> Cat? {
// Catch HomeworkError.CatAteIt.
// CHECK: [[MATCH_ATE]]([[T0:%.*]] : @owned $Cat):
// CHECK-NEXT: [[T0_BORROW:%.*]] = begin_borrow [lexical] [var_decl] [[T0]]
// CHECK-NEXT: [[T0_COPY:%.*]] = copy_value [[T0_BORROW]]
// CHECK-NEXT: end_borrow [[T0_BORROW]]
// CHECK-NEXT: destroy_value [[T0]]
// CHECK-NEXT: [[MOVED_T0:%.*]] = move_value [lexical] [var_decl] [[T0]]
// CHECK-NEXT: [[T0_COPY:%.*]] = copy_value [[MOVED_T0]]
// CHECK-NEXT: destroy_value [[MOVED_T0]]
// CHECK-NEXT: dealloc_stack [[DEST_TEMP]]
// CHECK-NEXT: destroy_addr [[SRC_TEMP]]
// CHECK-NEXT: dealloc_stack [[SRC_TEMP]]
@@ -326,10 +326,9 @@ func all_together_now_four(_ flag: Bool) throws -> Cat? {
// Catch HomeworkError.CatHidIt.
// CHECK: [[MATCH_HID]]([[T0:%.*]] : @owned $Cat):
// CHECK-NEXT: [[T0_BORROW:%.*]] = begin_borrow [lexical] [var_decl] [[T0]]
// CHECK-NEXT: [[T0_COPY:%.*]] = copy_value [[T0_BORROW]]
// CHECK-NEXT: end_borrow [[T0_BORROW]]
// CHECK-NEXT: destroy_value [[T0]]
// CHECK-NEXT: [[MOVED_T0:%.*]] = move_value [lexical] [var_decl] [[T0]]
// CHECK-NEXT: [[T0_COPY:%.*]] = copy_value [[MOVED_T0]]
// CHECK-NEXT: destroy_value [[MOVED_T0]]
// CHECK-NEXT: dealloc_stack [[DEST_TEMP]]
// CHECK-NEXT: destroy_addr [[SRC_TEMP]]
// CHECK-NEXT: dealloc_stack [[SRC_TEMP]]

View File

@@ -555,18 +555,22 @@ func genericCollectionContinueBreak<T : Collection>(_ xx: T) {
func tupleElements(_ xx: [(C, C)]) {
// CHECK: bb{{.*}}([[PAYLOAD:%.*]] : @owned $(C, C)):
// CHECK: ([[A:%.*]], [[B:%.*]]) = destructure_tuple [[PAYLOAD]]
// CHECK: destroy_value [[B]]
// CHECK: destroy_value [[A]]
// CHECK: [[MOVED_A:%.*]] = move_value [lexical] [var_decl] [[A]]
// CHECK: [[MOVED_B:%.*]] = move_value [lexical] [var_decl] [[B]]
// CHECK: destroy_value [[MOVED_B]]
// CHECK: destroy_value [[MOVED_A]]
for (a, b) in xx {}
// CHECK: bb{{.*}}([[PAYLOAD:%.*]] : @owned $(C, C)):
// CHECK: ([[A:%.*]], [[B:%.*]]) = destructure_tuple [[PAYLOAD]]
// CHECK: [[MOVED_A:%.*]] = move_value [lexical] [var_decl] [[A]]
// CHECK: destroy_value [[B]]
// CHECK: destroy_value [[A]]
// CHECK: destroy_value [[MOVED_A]]
for (a, _) in xx {}
// CHECK: bb{{.*}}([[PAYLOAD:%.*]] : @owned $(C, C)):
// CHECK: ([[A:%.*]], [[B:%.*]]) = destructure_tuple [[PAYLOAD]]
// CHECK: [[MOVED_B:%.*]] = move_value [lexical] [var_decl] [[B]]
// CHECK: destroy_value [[A]]
// CHECK: destroy_value [[B]]
// CHECK: destroy_value [[MOVED_B]]
for (_, b) in xx {}
// CHECK: bb{{.*}}([[PAYLOAD:%.*]] : @owned $(C, C)):
// CHECK: ([[A:%.*]], [[B:%.*]]) = destructure_tuple [[PAYLOAD]]

View File

@@ -23,7 +23,7 @@ func guaranteed_captures() {
// CHECK: [[IMMUTABLE_TRIVIAL:%.*]] = apply {{.*}} -> S
let immutableTrivial = S()
// CHECK: [[IMMUTABLE_RETAINABLE:%.*]] = apply {{.*}} -> @owned C
// CHECK: [[B_IMMUTABLE_RETAINABLE:%.*]] = begin_borrow [lexical] [var_decl] [[IMMUTABLE_RETAINABLE]] : $C
// CHECK: [[B_IMMUTABLE_RETAINABLE:%.*]] = move_value [lexical] [var_decl] [[IMMUTABLE_RETAINABLE]] : $C
let immutableRetainable = C()
// CHECK: [[IMMUTABLE_ADDRESS_ONLY:%.*]] = alloc_stack [lexical] $any P
let immutableAddressOnly: P = C()
@@ -38,8 +38,9 @@ func guaranteed_captures() {
// CHECK-NOT: copy_value [[MUTABLE_ADDRESS_ONLY_BOX_LIFETIME]]
// CHECK-NOT: copy_value [[IMMUTABLE_RETAINABLE]]
// CHECK: [[B_IMMUTABLE_RETAINABLE_BORROW:%.*]] = begin_borrow [[B_IMMUTABLE_RETAINABLE]] : $C
// CHECK: [[FN:%.*]] = function_ref [[FN_NAME:@\$s26guaranteed_closure_context0A9_capturesyyF17captureEverythingL_yyF]]
// CHECK: apply [[FN]]([[MUTABLE_TRIVIAL_BOX_BORROW]], [[MUTABLE_RETAINABLE_BOX_LIFETIME]], [[MUTABLE_ADDRESS_ONLY_BOX_LIFETIME]], [[IMMUTABLE_TRIVIAL]], [[B_IMMUTABLE_RETAINABLE]], [[IMMUTABLE_ADDRESS_ONLY]])
// CHECK: apply [[FN]]([[MUTABLE_TRIVIAL_BOX_BORROW]], [[MUTABLE_RETAINABLE_BOX_LIFETIME]], [[MUTABLE_ADDRESS_ONLY_BOX_LIFETIME]], [[IMMUTABLE_TRIVIAL]], [[B_IMMUTABLE_RETAINABLE_BORROW]], [[IMMUTABLE_ADDRESS_ONLY]])
captureEverything()
// CHECK-NOT: copy_value [[MUTABLE_TRIVIAL_BOX]]

View File

@@ -458,11 +458,12 @@ class LetFieldClass {
// CHECK-NEXT: apply [[KRAKEN_METH]]([[KRAKEN]])
// CHECK: [[KRAKEN_ADDR:%.*]] = ref_element_addr [[CLS]] : $LetFieldClass, #LetFieldClass.letk
// CHECK-NEXT: [[KRAKEN:%.*]] = load [copy] [[KRAKEN_ADDR]]
// CHECK: [[REBORROWED_KRAKEN:%.*]] = begin_borrow [lexical] [var_decl] [[KRAKEN]]
// CHECK: [[MOVED_KRAKEN:%.*]] = move_value [lexical] [var_decl] [[KRAKEN]]
// CHECK: [[REBORROWED_KRAKEN:%.*]] = begin_borrow [[MOVED_KRAKEN]]
// CHECK: [[DESTROY_SHIP_FUN:%.*]] = function_ref @$s15guaranteed_self11destroyShipyyAA6KrakenCF : $@convention(thin) (@guaranteed Kraken) -> ()
// CHECK-NEXT: apply [[DESTROY_SHIP_FUN]]([[REBORROWED_KRAKEN]])
// CHECK-NEXT: end_borrow [[REBORROWED_KRAKEN]]
// CHECK-NEXT: destroy_value [[KRAKEN]]
// CHECK-NEXT: destroy_value [[MOVED_KRAKEN]]
// CHECK-NEXT: [[KRAKEN_BOX:%.*]] = alloc_box ${ var Kraken }
// CHECK-NEXT: [[KRAKEN_LIFETIME:%.+]] = begin_borrow [lexical] [var_decl] [[KRAKEN_BOX]]
// CHECK-NEXT: [[PB:%.*]] = project_box [[KRAKEN_LIFETIME]]
@@ -505,9 +506,11 @@ class LetFieldClass {
// CHECK-NEXT: destroy_value [[KRAKEN]]
// CHECK-NEXT: [[KRAKEN_GETTER_FUN:%.*]] = class_method [[CLS]] : $LetFieldClass, #LetFieldClass.vark!getter : (LetFieldClass) -> () -> Kraken, $@convention(method) (@guaranteed LetFieldClass) -> @owned Kraken
// CHECK-NEXT: [[KRAKEN:%.*]] = apply [[KRAKEN_GETTER_FUN]]([[CLS]])
// CHECK: [[BORROWED_KRAKEN:%.*]] = begin_borrow [lexical] [var_decl] [[KRAKEN]]
// CHECK: [[MOVED_KRAKEN:%.*]] = move_value [lexical] [var_decl] [[KRAKEN]]
// CHECK: [[BORROWED_KRAKEN:%.*]] = begin_borrow [[MOVED_KRAKEN]]
// CHECK: [[DESTROY_SHIP_FUN:%.*]] = function_ref @$s15guaranteed_self11destroyShipyyAA6KrakenCF : $@convention(thin) (@guaranteed Kraken) -> ()
// CHECK-NEXT: apply [[DESTROY_SHIP_FUN]]([[BORROWED_KRAKEN]])
// CHECK-NEXT: end_borrow [[BORROWED_KRAKEN]]
// CHECK-NEXT: [[KRAKEN_BOX:%.*]] = alloc_box ${ var Kraken }
// CHECK-NEXT: [[KRAKEN_LIFETIME:%.+]] = begin_borrow [lexical] [var_decl] [[KRAKEN_BOX]]
// CHECK-NEXT: [[PB:%.*]] = project_box [[KRAKEN_LIFETIME]]
@@ -522,8 +525,7 @@ class LetFieldClass {
// CHECK-NEXT: destroy_value [[KRAKEN_COPY]]
// CHECK-NEXT: end_borrow [[KRAKEN_LIFETIME]]
// CHECK-NEXT: destroy_value [[KRAKEN_BOX]]
// CHECK-NEXT: end_borrow [[BORROWED_KRAKEN]]
// CHECK-NEXT: destroy_value [[KRAKEN]]
// CHECK-NEXT: destroy_value [[MOVED_KRAKEN]]
// CHECK-NEXT: tuple
// CHECK-NEXT: return
func varkMethod() {

View File

@@ -219,14 +219,15 @@ actor BlueActorImpl {
// CHECK: bb0([[BLUE:%[0-9]+]] : @guaranteed $BlueActorImpl):
// CHECK: hop_to_executor [[BLUE]] : $BlueActorImpl
// CHECK: [[RED:%[0-9]+]] = apply {{%[0-9]+}}({{%[0-9]+}}) : $@convention(method) (@thick RedActorImpl.Type) -> @owned RedActorImpl
// CHECK: [[REDBORROW:%[0-9]+]] = begin_borrow [lexical] [var_decl] [[RED]] : $RedActorImpl
// CHECK: [[REDMOVE:%[0-9]+]] = move_value [lexical] [var_decl] [[RED]] : $RedActorImpl
// CHECK: [[REDBORROW:%[0-9]+]] = begin_borrow [[REDMOVE]] : $RedActorImpl
// CHECK: [[INTARG:%[0-9]+]] = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int
// CHECK: [[METH:%[0-9]+]] = class_method [[REDBORROW]] : $RedActorImpl, #RedActorImpl.hello : (isolated RedActorImpl) -> (Int) -> (), $@convention(method) (Int, @guaranteed RedActorImpl) -> ()
// CHECK: hop_to_executor [[REDBORROW]] : $RedActorImpl
// CHECK-NEXT: = apply [[METH]]([[INTARG]], [[REDBORROW]]) : $@convention(method) (Int, @guaranteed RedActorImpl) -> ()
// CHECK-NEXT: hop_to_executor [[BLUE]] : $BlueActorImpl
// CHECK: end_borrow [[REDBORROW]] : $RedActorImpl
// CHECK: destroy_value [[RED]] : $RedActorImpl
// CHECK: destroy_value [[REDMOVE]] : $RedActorImpl
// CHECK: } // end sil function '$s4test13BlueActorImplC14createAndGreetyyYaF'
func createAndGreet() async {
let red = RedActorImpl() // <- key difference from `poke` is local construction of the actor

View File

@@ -23,11 +23,12 @@ func if_no_else() {
// CHECK: br [[CONT:bb[0-9]+]]
if let x = foo() {
// CHECK: [[YES]]([[VAL:%[0-9]+]] : @owned $String):
// CHECK: [[BORROWED_VAL:%.*]] = begin_borrow [var_decl] [[VAL]]
// CHECK: [[MOVED_VAL:%.*]] = move_value [var_decl] [[VAL]]
// CHECK: [[BORROWED_VAL:%.*]] = begin_borrow [[MOVED_VAL]]
// CHECK: [[A:%.*]] = function_ref @$s16if_while_binding1a
// CHECK: apply [[A]]([[BORROWED_VAL]])
// CHECK: end_borrow [[BORROWED_VAL]]
// CHECK: destroy_value [[VAL]]
// CHECK: destroy_value [[MOVED_VAL]]
// CHECK: br [[CONT]]
a(x)
}
@@ -43,12 +44,13 @@ func if_else_chain() {
// CHECK-NEXT: switch_enum [[OPT_RES]] : $Optional<String>, case #Optional.some!enumelt: [[YESX:bb[0-9]+]], case #Optional.none!enumelt: [[NOX:bb[0-9]+]]
if let x = foo() {
// CHECK: [[YESX]]([[VAL:%[0-9]+]] : @owned $String):
// CHECK: [[BORROWED_VAL:%.*]] = begin_borrow [var_decl] [[VAL]]
// CHECK: debug_value [[BORROWED_VAL]] : $String, let, name "x"
// CHECK: [[MOVED_VAL:%.*]] = move_value [var_decl] [[VAL]]
// CHECK: debug_value [[MOVED_VAL]] : $String, let, name "x"
// CHECK: [[BORROWED_VAL:%.*]] = begin_borrow [[MOVED_VAL]]
// CHECK: [[A:%.*]] = function_ref @$s16if_while_binding1a
// CHECK: apply [[A]]([[BORROWED_VAL]])
// CHECK: end_borrow [[BORROWED_VAL]]
// CHECK: destroy_value [[VAL]]
// CHECK: destroy_value [[MOVED_VAL]]
// CHECK: br [[CONT_X:bb[0-9]+]]
a(x)
//
@@ -83,17 +85,19 @@ func while_loop() {
// CHECK: br [[LOOP_EXIT:bb[0-9]+]]
while let x = foo() {
// CHECK: [[LOOP_BODY]]([[X:%[0-9]+]] : @owned $String):
// CHECK: [[MOVED_X:%.*]] = move_value [var_decl] [[X]]
// CHECK: switch_enum {{.*}} : $Optional<String>, case #Optional.some!enumelt: [[YES:bb[0-9]+]], case #Optional.none!enumelt: [[FAILURE_DEST_2:bb[0-9]+]]
if let y = bar() {
// CHECK: [[YES]]([[Y:%[0-9]+]] : @owned $String):
// CHECK: [[MOVED_Y:%.*]] = move_value [var_decl] [[Y]]
a(y)
break
// CHECK: destroy_value [[Y]]
// CHECK: destroy_value [[X]]
// CHECK: destroy_value [[MOVED_Y]]
// CHECK: destroy_value [[MOVED_X]]
// CHECK: br [[LOOP_EXIT]]
}
// CHECK: [[FAILURE_DEST_2]]:
// CHECK: destroy_value [[X]]
// CHECK: destroy_value [[MOVED_X]]
// CHECK: br [[LOOP_ENTRY]]
}
// CHECK: [[LOOP_EXIT]]:
@@ -136,25 +140,26 @@ func while_loop_multi() {
// CHECK: br [[LOOP_EXIT0:bb[0-9]+]]
// CHECK: [[CHECKBUF2]]([[A:%[0-9]+]] : @owned $String):
// CHECK: [[AL:%.*]] = begin_borrow [var_decl] [[A]]
// CHECK: debug_value [[AL]] : $String, let, name "a"
// CHECK: [[MOVED_A:%.*]] = move_value [var_decl] [[A]]
// CHECK: debug_value [[MOVED_A]] : $String, let, name "a"
// CHECK: switch_enum {{.*}}, case #Optional.some!enumelt: [[LOOP_BODY:bb.*]], case #Optional.none!enumelt: [[LOOP_EXIT2a:bb[0-9]+]]
// CHECK: [[LOOP_EXIT2a]]:
// CHECK: destroy_value [[A]]
// CHECK: destroy_value [[MOVED_A]]
// CHECK: br [[LOOP_EXIT0]]
// CHECK: [[LOOP_BODY]]([[B:%[0-9]+]] : @owned $String):
// CHECK: [[MOVED_B:%.*]] = move_value [var_decl] [[B]]
// CHECK: debug_value [[MOVED_B]] : $String, let, name "b"
while let a = foo(), let b = bar() {
// CHECK: [[BL:%.*]] = begin_borrow [var_decl] [[B]]
// CHECK: debug_value [[BL]] : $String, let, name "b"
// CHECK: [[AL:%.*]] = begin_borrow [[MOVED_A]]
// CHECK: [[A_COPY:%.*]] = copy_value [[AL]]
// CHECK: [[BORROWED_A:%.*]] = begin_borrow [var_decl] [[A_COPY]]
// CHECK: debug_value [[BORROWED_A]] : $String, let, name "c"
// CHECK: destroy_value [[A_COPY]]
// CHECK: destroy_value [[B]]
// CHECK: destroy_value [[A]]
// CHECK: [[MOVED_C:%.*]] = move_value [var_decl] [[A_COPY]]
// CHECK: debug_value [[MOVED_C]] : $String, let, name "c"
// CHECK: destroy_value [[MOVED_C]]
// CHECK: destroy_value [[MOVED_B]]
// CHECK: destroy_value [[MOVED_A]]
// CHECK: br [[LOOP_ENTRY]]
let c = a
}
@@ -171,8 +176,8 @@ func if_multi() {
// CHECK: br [[IF_DONE:bb[0-9]+]]
// CHECK: [[CHECKBUF2]]([[A:%[0-9]+]] : @owned $String):
// CHECK: [[AL:%.*]] = begin_borrow [var_decl] [[A]]
// CHECK: debug_value [[AL]] : $String, let, name "a"
// CHECK: [[MOVED_A:%.*]] = move_value [var_decl] [[A]]
// CHECK: debug_value [[MOVED_A]] : $String, let, name "a"
// CHECK: [[B:%[0-9]+]] = alloc_box ${ var String }, var, name "b"
// CHECK: [[BL:%[0-9]+]] = begin_borrow [var_decl] [[B]]
// CHECK: [[PB:%[0-9]+]] = project_box [[BL]]
@@ -180,7 +185,7 @@ func if_multi() {
// CHECK: [[IF_EXIT1a]]:
// CHECK: dealloc_box {{.*}} ${ var String }
// CHECK: destroy_value [[A]]
// CHECK: destroy_value [[MOVED_A]]
// CHECK: br [[IF_DONE]]
// CHECK: [[IF_BODY]]([[BVAL:%[0-9]+]] : @owned $String):
@@ -188,7 +193,7 @@ func if_multi() {
// CHECK: store [[BVAL]] to [init] [[PB]] : $*String
// CHECK: debug_value {{.*}} : $String, let, name "c"
// CHECK: destroy_value [[B]]
// CHECK: destroy_value [[A]]
// CHECK: destroy_value [[MOVED_A]]
// CHECK: br [[IF_DONE]]
let c = a
}
@@ -204,8 +209,8 @@ func if_multi_else() {
// CHECK: [[NONE_TRAMPOLINE]]:
// CHECK: br [[ELSE:bb[0-9]+]]
// CHECK: [[CHECKBUF2]]([[A:%[0-9]+]] : @owned $String):
// CHECK: [[AL:%.*]] = begin_borrow [var_decl] [[A]]
// CHECK: debug_value [[AL]] : $String, let, name "a"
// CHECK: [[MOVED_A:%.*]] = move_value [var_decl] [[A]]
// CHECK: debug_value [[MOVED_A]] : $String, let, name "a"
// CHECK: [[B:%[0-9]+]] = alloc_box ${ var String }, var, name "b"
// CHECK: [[BL:%[0-9]+]] = begin_borrow [var_decl] [[B]]
// CHECK: [[PB:%[0-9]+]] = project_box [[BL]]
@@ -213,7 +218,7 @@ func if_multi_else() {
// CHECK: [[IF_EXIT1a]]:
// CHECK: dealloc_box {{.*}} ${ var String }
// CHECK: destroy_value [[A]]
// CHECK: destroy_value [[MOVED_A]]
// CHECK: br [[ELSE]]
// CHECK: [[IF_BODY]]([[BVAL:%[0-9]+]] : @owned $String):
@@ -221,7 +226,7 @@ func if_multi_else() {
// CHECK: store [[BVAL]] to [init] [[PB]] : $*String
// CHECK: debug_value {{.*}} : $String, let, name "c"
// CHECK: destroy_value [[B]]
// CHECK: destroy_value [[A]]
// CHECK: destroy_value [[MOVED_A]]
// CHECK: br [[IF_DONE:bb[0-9]+]]
let c = a
} else {
@@ -242,15 +247,15 @@ func if_multi_where() {
// CHECK: [[NONE_TRAMPOLINE]]:
// CHECK: br [[DONE:bb[0-9]+]]
// CHECK: [[CHECKBUF2]]([[A:%[0-9]+]] : @owned $String):
// CHECK: [[AL:%.*]] = begin_borrow [var_decl] [[A]]
// CHECK: debug_value [[AL]] : $String, let, name "a"
// CHECK: [[MOVED_A:%.*]] = move_value [var_decl] [[A]]
// CHECK: debug_value [[MOVED_A]] : $String, let, name "a"
// CHECK: [[BBOX:%[0-9]+]] = alloc_box ${ var String }, var, name "b"
// CHECK: [[PL:%[0-9]+]] = begin_borrow [var_decl] [[BBOX]]
// CHECK: [[PB:%[0-9]+]] = project_box [[PL]]
// CHECK: switch_enum {{.*}}, case #Optional.some!enumelt: [[CHECK_WHERE:bb.*]], case #Optional.none!enumelt: [[IF_EXIT1a:bb[0-9]+]]
// CHECK: [[IF_EXIT1a]]:
// CHECK: dealloc_box {{.*}} ${ var String }
// CHECK: destroy_value [[A]]
// CHECK: destroy_value [[MOVED_A]]
// CHECK: br [[DONE]]
// CHECK: [[CHECK_WHERE]]([[B:%[0-9]+]] : @owned $String):
@@ -259,13 +264,13 @@ func if_multi_where() {
if let a = foo(), var b = bar(), a == b {
// CHECK: [[IF_BODY]]:
// CHECK: destroy_value [[BBOX]]
// CHECK: destroy_value [[A]]
// CHECK: destroy_value [[MOVED_A]]
// CHECK: br [[DONE]]
let c = a
}
// CHECK: [[IF_EXIT3]]:
// CHECK: destroy_value [[BBOX]]
// CHECK: destroy_value [[A]]
// CHECK: destroy_value [[MOVED_A]]
// CHECK: br [[DONE]]
// CHECK: [[DONE]]:
// CHECK-NEXT: tuple ()
@@ -291,13 +296,14 @@ func if_leading_boolean(_ a : Int) {
// CHECK: switch_enum [[OPTRESULT]] : $Optional<String>, case #Optional.some!enumelt: [[SUCCESS:bb.*]], case #Optional.none!enumelt: [[IFDONE:bb[0-9]+]]
// CHECK: [[SUCCESS]]([[B:%[0-9]+]] : @owned $String):
// CHECK: [[BL:%.*]] = begin_borrow [var_decl] [[B]]
// CHECK: debug_value [[BL]] : $String, let, name "b"
// CHECK: [[C:%.*]] = copy_value [[BL]]
// CHECK: [[CL:%.*]] = begin_borrow [var_decl] [[C]]
// CHECK: debug_value [[CL]] : $String, let, name "c"
// CHECK: destroy_value [[C]]
// CHECK: destroy_value [[B]]
// CHECK: [[MOVED_B:%.*]] = move_value [var_decl] [[B]]
// CHECK: debug_value [[MOVED_B]] : $String, let, name "b"
// CHECK: [[BB:%.*]] = begin_borrow [[MOVED_B]]
// CHECK: [[C:%.*]] = copy_value [[BB]]
// CHECK: [[MOVED_C:%.*]] = move_value [var_decl] [[C]]
// CHECK: debug_value [[MOVED_C]] : $String, let, name "c"
// CHECK: destroy_value [[MOVED_C]]
// CHECK: destroy_value [[MOVED_B]]
// CHECK: br [[IFDONE:bb[0-9]+]]
if a == a, let b = foo() {
let c = b
@@ -340,10 +346,10 @@ func testAsPatternInIfLet(_ a : BaseClass?) {
// CHECK: switch_enum [[OPTVAL]] : $Optional<DerivedClass>, case #Optional.some!enumelt: [[ISDERIVEDBB:bb[0-9]+]], case #Optional.none!enumelt: [[NILBB:bb[0-9]+]]
// CHECK: [[ISDERIVEDBB]]([[DERIVEDVAL:%[0-9]+]] : @owned $DerivedClass):
// CHECK: [[BORROWED_DERIVED_VAL:%.*]] = begin_borrow [lexical] [var_decl] [[DERIVEDVAL]]
// CHECK: debug_value [[BORROWED_DERIVED_VAL]] : $DerivedClass
// CHECK: [[MOVED_DERIVED_VAL:%.*]] = move_value [lexical] [var_decl] [[DERIVEDVAL]]
// CHECK: debug_value [[MOVED_DERIVED_VAL]] : $DerivedClass
// => SEMANTIC SIL TODO: This is benign, but scoping wise, this end borrow should be after derived val.
// CHECK: destroy_value [[DERIVEDVAL]] : $DerivedClass
// CHECK: destroy_value [[MOVED_DERIVED_VAL]] : $DerivedClass
// CHECK: br [[EXITBB]]
// CHECK: [[EXITBB]]:

View File

@@ -46,11 +46,12 @@ public func useClass(d: Double, opts: SomeClass.Options) {
// CHECK: [[OBJ:%[0-9]+]] = apply [[CTOR]]([[D]])
let o = SomeClass(value: d)
// CHECK: [[BORROWED_OBJ:%.*]] = begin_borrow [lexical] [var_decl] [[OBJ]]
// CHECK: [[MOVED_OBJ:%.*]] = move_value [lexical] [var_decl] [[OBJ]]
// CHECK: [[BORROWED_OBJ:%.*]] = begin_borrow [[MOVED_OBJ]]
// CHECK: [[APPLY_FN:%[0-9]+]] = function_ref @IAMSomeClassApplyOptions : $@convention(c) (SomeClass, SomeClass.Options) -> ()
// CHECK: apply [[APPLY_FN]]([[BORROWED_OBJ]], [[OPTS]])
// CHECK: end_borrow [[BORROWED_OBJ]]
// CHECK: destroy_value [[OBJ]]
// CHECK: destroy_value [[MOVED_OBJ]]
o.applyOptions(opts)
}

View File

@@ -366,11 +366,13 @@ func guardTreeA<T>(_ tree: TreeA<T>) {
// CHECK: [[TUPLE_COPY:%.*]] = copy_value [[TUPLE]]
// CHECK: end_borrow [[TUPLE]]
// CHECK: ([[L:%.*]], [[R:%.*]]) = destructure_tuple [[TUPLE_COPY]]
// CHECK: [[MOVED_L:%.*]] = move_value [lexical] [var_decl] [[L]]
// CHECK: [[MOVED_R:%.*]] = move_value [lexical] [var_decl] [[R]]
// CHECK: destroy_value [[BOX]]
guard case .Branch(left: let l, right: let r) = tree else { return }
// CHECK: destroy_value [[R]]
// CHECK: destroy_value [[L]]
// CHECK: destroy_value [[MOVED_R]]
// CHECK: destroy_value [[MOVED_L]]
// CHECK: destroy_addr [[X]]
}
@@ -408,9 +410,11 @@ func guardTreeA<T>(_ tree: TreeA<T>) {
// CHECK: [[TUPLE_COPY:%.*]] = copy_value [[TUPLE]]
// CHECK: end_borrow [[TUPLE]]
// CHECK: ([[L:%.*]], [[R:%.*]]) = destructure_tuple [[TUPLE_COPY]]
// CHECK: [[MOVED_L:%.*]] = move_value [lexical] [var_decl] [[L]]
// CHECK: [[MOVED_R:%.*]] = move_value [lexical] [var_decl] [[R]]
// CHECK: destroy_value [[BOX]]
// CHECK: destroy_value [[R]]
// CHECK: destroy_value [[L]]
// CHECK: destroy_value [[MOVED_R]]
// CHECK: destroy_value [[MOVED_L]]
if case .Branch(left: let l, right: let r) = tree { }
}
// CHECK: [[NO3]]([[ORIGINAL_VALUE:%.*]] : @owned $TreeA<T>):

View File

@@ -68,15 +68,16 @@ func test3() {
// CHECK-NEXT: [[STR:%[0-9]+]] = apply [[GETFN]]()
let o = getAString()
// CHECK-NEXT: [[STR_BORROW:%.*]] = begin_borrow [var_decl] [[STR]]
// CHECK-NEXT: [[STR_MOV:%.*]] = move_value [var_decl] [[STR]]
// CHECK-NEXT: debug_value
// CHECK-NOT: destroy_value
// CHECK: [[STR_BORROW:%.*]] = begin_borrow [[STR_MOV]]
// CHECK: [[USEFN:%[0-9]+]] = function_ref{{.*}}useAString
// CHECK-NEXT: [[USE:%[0-9]+]] = apply [[USEFN]]([[STR_BORROW]])
useAString(o)
// CHECK: destroy_value [[STR]]
// CHECK: destroy_value [[STR_MOV]]
}
// CHECK: } // end sil function '{{.*}}test3{{.*}}'

View File

@@ -44,8 +44,8 @@ struct NonlexicalBox<X> {
// CHECK-LABEL: sil hidden [ossa] @lexical_borrow_let_class
// CHECK: [[INIT_C:%[^,]+]] = function_ref @$s6borrow1CCACycfC
// CHECK: [[INSTANCE:%[^,]+]] = apply [[INIT_C]]({{%[0-9]+}})
// CHECK: [[BORROW:%[^,]+]] = begin_borrow [lexical] [var_decl] [[INSTANCE]] : $C
// CHECK: end_borrow [[BORROW:%[^,]+]]
// CHECK: [[MOVE:%[^,]+]] = move_value [lexical] [var_decl] [[INSTANCE]] : $C
// CHECK: destroy_value [[MOVE:%[^,]+]]
// CHECK-LABEL: } // end sil function 'lexical_borrow_let_class'
@_silgen_name("lexical_borrow_let_class")
func lexical_borrow_let_class() {
@@ -57,8 +57,8 @@ func lexical_borrow_let_class() {
// CHECK: [[INSTANCE:%[^,]+]] = apply [[INIT_C]]({{%[^,]+}})
// CHECK: switch_enum [[INSTANCE]] : $Optional<C>, case #Optional.some!enumelt: [[BASIC_BLOCK2:bb[^,]+]], case #Optional.none!enumelt: {{bb[^,]+}}
// CHECK: [[BASIC_BLOCK2]]([[INSTANCE:%[^,]+]] : @owned $C):
// CHECK: [[BORROW:%[^,]+]] = begin_borrow [lexical] [var_decl] [[INSTANCE]] : $C
// CHECK: end_borrow [[BORROW]] : $C
// CHECK: [[MOVE:%[^,]+]] = move_value [lexical] [var_decl] [[INSTANCE]] : $C
// CHECK: destroy_value [[MOVE:%[^,]+]]
// CHECK-LABEL: // end sil function 'lexical_borrow_if_let_class'
@_silgen_name("lexical_borrow_if_let_class")
func lexical_borrow_if_let_class() {
@@ -70,8 +70,8 @@ func lexical_borrow_if_let_class() {
// CHECK-LABEL: sil hidden [ossa] @lexical_borrow_let_class_in_struct
// CHECK: [[INIT_S:%[^,]+]] = function_ref @$s6borrow1SV1cAcA1CC_tcfC
// CHECK: [[INSTANCE:%[^,]+]] = apply [[INIT_S]]({{%[0-9]+}}, {{%[0-9]+}})
// CHECK: [[BORROW:%[^,]+]] = begin_borrow [lexical] [var_decl] [[INSTANCE]] : $S
// CHECK: end_borrow [[BORROW:%[^,]+]]
// CHECK: [[MOVE:%[^,]+]] = move_value [lexical] [var_decl] [[INSTANCE]]
// CHECK: destroy_value [[MOVE:%[^,]+]]
// CHECK-LABEL: } // end sil function 'lexical_borrow_let_class_in_struct'
@_silgen_name("lexical_borrow_let_class_in_struct")
func lexical_borrow_let_class_in_struct() {
@@ -80,8 +80,8 @@ func lexical_borrow_let_class_in_struct() {
// CHECK-LABEL: sil hidden [ossa] @lexical_borrow_let_class_in_enum
// CHECK: [[INSTANCE:%[^,]+]] = enum $E, #E.e!enumelt, {{%[0-9]+}} : $C
// CHECK: [[BORROW:%[^,]+]] = begin_borrow [lexical] [var_decl] [[INSTANCE]] : $E
// CHECK: end_borrow [[BORROW:%[^,]+]]
// CHECK: [[MOVE:%[^,]+]] = move_value [lexical] [var_decl] [[INSTANCE]]
// CHECK: destroy_value [[MOVE:%[^,]+]]
// CHECK-LABEL: } // end sil function 'lexical_borrow_let_class_in_enum'
@_silgen_name("lexical_borrow_let_class_in_enum")
func lexical_borrow_let_class_in_enum() {

View File

@@ -14,7 +14,8 @@ func local_recursion(_ x: Int, y: Int) {
// CHECK: [[SELF_RECURSIVE_REF:%.*]] = function_ref [[SELF_RECURSIVE]]
// CHECK: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[SELF_RECURSIVE_REF]]([[X]])
// CHECK: [[BORROWED_CLOSURE:%.*]] = begin_borrow [lexical] [var_decl] [[CLOSURE]]
// CHECK: [[MOVED_CLOSURE:%.*]] = move_value [lexical] [var_decl] [[CLOSURE]]
// CHECK: [[BORROWED_CLOSURE:%.*]] = begin_borrow [[MOVED_CLOSURE]]
// CHECK: [[CLOSURE_COPY:%.*]] = copy_value [[BORROWED_CLOSURE]]
let sr = self_recursive
// CHECK: [[B:%.*]] = begin_borrow [[CLOSURE_COPY]]
@@ -50,7 +51,8 @@ func local_recursion(_ x: Int, y: Int) {
// CHECK: [[TRANS_CAPTURE_REF:%.*]] = function_ref [[TRANS_CAPTURE]]
// CHECK: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[TRANS_CAPTURE_REF]]([[X]], [[Y]])
// CHECK: [[BORROWED_CLOSURE:%.*]] = begin_borrow [lexical] [var_decl] [[CLOSURE]]
// CHECK: [[MOVED_CLOSURE:%.*]] = move_value [lexical] [var_decl] [[CLOSURE]]
// CHECK: [[BORROWED_CLOSURE:%.*]] = begin_borrow [[MOVED_CLOSURE]]
// CHECK: [[CLOSURE_COPY:%.*]] = copy_value [[BORROWED_CLOSURE]]
let tc = transitive_capture_2
// CHECK: [[B:%.*]] = begin_borrow [[CLOSURE_COPY]]
@@ -68,7 +70,8 @@ func local_recursion(_ x: Int, y: Int) {
// CHECK: [[CLOSURE_REF:%.*]] = function_ref @$s15local_recursionAA_1yySi_SitFySicfU0_
// CHECK: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE_REF]]([[X]], [[Y]])
// CHECK: [[BORROWED_CLOSURE:%.*]] = begin_borrow [lexical] [var_decl] [[CLOSURE]]
// CHECK: [[MOVED_CLOSURE:%.*]] = move_value [lexical] [var_decl] [[CLOSURE]]
// CHECK: [[BORROWED_CLOSURE:%.*]] = begin_borrow [[MOVED_CLOSURE]]
// CHECK: [[CLOSURE_COPY:%.*]] = copy_value [[BORROWED_CLOSURE]]
// CHECK: [[B:%.*]] = begin_borrow [[CLOSURE_COPY]]
// CHECK: apply [[B]]([[X]])

View File

@@ -731,7 +731,7 @@ var booleanGuard2: Bool { false }
// This case is copyable
// CHECK: [[BB_E_3]]([[BBARG:%.*]] : @guaranteed
// CHECK: [[BBARG_COPY:%.*]] = copy_value [[BBARG]]
// CHECK: begin_borrow [lexical] [var_decl] [[BBARG_COPY]]
// CHECK: move_value [lexical] [var_decl] [[BBARG_COPY]]
// CHECK: end_borrow [[BORROWED_VALUE]]
// CHECK: br [[BB_CONT]]
//
@@ -749,7 +749,7 @@ var booleanGuard2: Bool { false }
// Copyable case
// CHECK: [[BB_E2_LHS]]([[BBARG:%.*]] : @guaranteed
// CHECK: [[BBARG_COPY:%.*]] = copy_value [[BBARG]]
// CHECK: begin_borrow [lexical] [var_decl] [[BBARG_COPY]]
// CHECK: move_value [lexical] [var_decl] [[BBARG_COPY]]
// CHECK: end_borrow [[BORROWED_VALUE]]
// CHECK: br [[BB_CONT]]
//

View File

@@ -90,7 +90,8 @@ func testGlobalClosureCaptureVar() {
// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
// CHECK: mark_function_escape [[PROJECT]]
// CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX_COPY]])
// CHECK: [[BORROW_PAI:%.*]] = begin_borrow [lexical] [var_decl] [[PAI]]
// CHECK: [[MOVE_PAI:%.*]] = move_value [lexical] [var_decl] [[PAI]]
// CHECK: [[BORROW_PAI:%.*]] = begin_borrow [[MOVE_PAI]]
// CHECK: [[COPY_BORROW_PAI:%.*]] = copy_value [[BORROW_PAI]]
// CHECK: [[BORROW_COPY_BORROW_PAI:%.*]] = begin_borrow [[COPY_BORROW_PAI]]
// CHECK: apply [[BORROW_COPY_BORROW_PAI]]()
@@ -400,7 +401,8 @@ func testGlobalClosureCaptureLet() {
// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
// CHECK: mark_function_escape [[PROJECT]]
// CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX_COPY]])
// CHECK: [[BORROW_PAI:%.*]] = begin_borrow [lexical] [var_decl] [[PAI]]
// CHECK: [[MOVE_PAI:%.*]] = move_value [lexical] [var_decl] [[PAI]]
// CHECK: [[BORROW_PAI:%.*]] = begin_borrow [[MOVE_PAI]]
// CHECK: [[COPY_BORROW_PAI:%.*]] = copy_value [[BORROW_PAI]]
// CHECK: [[BORROW_COPY_BORROW_PAI:%.*]] = begin_borrow [[COPY_BORROW_PAI]]
// CHECK: apply [[BORROW_COPY_BORROW_PAI]]()
@@ -922,7 +924,8 @@ func testGlobalClosureCaptureConsuming(_ x: consuming SingleElt) {
// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
// CHECK: mark_function_escape [[PROJECT]]
// CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX_COPY]])
// CHECK: [[BORROW_PAI:%.*]] = begin_borrow [lexical] [var_decl] [[PAI]]
// CHECK: [[MOVE_PAI:%.*]] = move_value [lexical] [var_decl] [[PAI]]
// CHECK: [[BORROW_PAI:%.*]] = begin_borrow [[MOVE_PAI]]
// CHECK: [[COPY_BORROW_PAI:%.*]] = copy_value [[BORROW_PAI]]
// CHECK: [[BORROW_COPY_BORROW_PAI:%.*]] = begin_borrow [[COPY_BORROW_PAI]]
// CHECK: apply [[BORROW_COPY_BORROW_PAI]]()
@@ -1175,7 +1178,8 @@ func testGlobalClosureCaptureOwned(_ x: __owned SingleElt) {
// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
// CHECK: mark_function_escape [[PROJECT]]
// CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX_COPY]])
// CHECK: [[BORROW_PAI:%.*]] = begin_borrow [lexical] [var_decl] [[PAI]]
// CHECK: [[MOVE_PAI:%.*]] = move_value [lexical] [var_decl] [[PAI]]
// CHECK: [[BORROW_PAI:%.*]] = begin_borrow [[MOVE_PAI]]
// CHECK: [[COPY_BORROW_PAI:%.*]] = copy_value [[BORROW_PAI]]
// CHECK: [[BORROW_COPY_BORROW_PAI:%.*]] = begin_borrow [[COPY_BORROW_PAI]]
// CHECK: apply [[BORROW_COPY_BORROW_PAI]]()

View File

@@ -338,7 +338,7 @@ func callClosureIntOwned() {
//
// CHECK-LABEL: sil hidden [ossa] @$s14noimplicitcopy10printKlassyyF : $@convention(thin) () -> () {
// CHECK: [[X:%.*]] = move_value [lexical] [var_decl] {{%[0-9]+}} : $Klass
// CHECK: [[X_MOVEONLYWRAPPED:%.*]] = copyable_to_moveonlywrapper [owned] [[X_COPY]]
// CHECK: [[X_MOVEONLYWRAPPED:%.*]] = copyable_to_moveonlywrapper [owned] [[X]]
// CHECK: [[X_MOVEONLYWRAPPED_MARKED:%.*]] = mark_unresolved_non_copyable_value [consumable_and_assignable] [[X_MOVEONLYWRAPPED]]
// CHECK: [[BORROWED_X_MOVEONLYWRAPPED_MARKED:%.*]] = begin_borrow [[X_MOVEONLYWRAPPED_MARKED]]
// CHECK: [[FUNC:%.*]] = class_method [[BORROWED_X_MOVEONLYWRAPPED_MARKED]]

View File

@@ -113,10 +113,11 @@ class MyNSError : NSError {
// CHECK: [[NSERROR_SUBCLASS:%.*]] = apply {{.*}}({{.*}}) : $@convention(method) (@thick MyNSError.Type) -> @owned MyNSError
// CHECK: [[UPCAST:%.*]] = upcast [[NSERROR_SUBCLASS]] : $MyNSError to $NSError
// CHECK: [[EXISTENTIAL_REF:%.*]] = init_existential_ref [[UPCAST]]
// CHECK: [[BORROWED_EXISTENTIAL_REF:%.*]] = begin_borrow [lexical] [var_decl] [[EXISTENTIAL_REF]]
// CHECK: [[MOVED_EXISTENTIAL_REF:%.*]] = move_value [lexical] [var_decl] [[EXISTENTIAL_REF]]
// CHECK: [[BORROWED_EXISTENTIAL_REF:%.*]] = begin_borrow [[MOVED_EXISTENTIAL_REF]]
// CHECK: [[COPY_BORROWED_EXISTENTIAL_REF:%.*]] = copy_value [[BORROWED_EXISTENTIAL_REF]]
// CHECK: end_borrow [[BORROWED_EXISTENTIAL_REF]]
// CHECK: destroy_value [[EXISTENTIAL_REF]]
// CHECK: destroy_value [[MOVED_EXISTENTIAL_REF]]
// CHECK: return [[COPY_BORROWED_EXISTENTIAL_REF]]
// CHECK: } // end sil function '$s10objc_error14eraseMyNSError{{[_0-9a-zA-Z]*}}F'
func eraseMyNSError() -> Error {

View File

@@ -81,7 +81,7 @@ extension Sub {
// CHECK: [[OLD_NSSTRING:%.*]] = apply [[GET_SUPER_METHOD]]([[BORROWED_UPCAST_SELF_COPY]])
// CHECK: bb3([[OLD_NSSTRING_BRIDGED:%.*]] : @owned $Optional<String>):
// CHECK: [[BORROWED_OLD_NSSTRING_BRIDGED:%.*]] = begin_borrow [var_decl] [[OLD_NSSTRING_BRIDGED]]
// CHECK: [[MOVED_OLD_NSSTRING_BRIDGED:%.*]] = move_value [var_decl] [[OLD_NSSTRING_BRIDGED]]
// This next line is completely not needed. But we are emitting it now.
// CHECK: destroy_value [[UPCAST_SELF_COPY]]
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
@@ -99,10 +99,11 @@ extension Sub {
// CHECK: destroy_value [[BRIDGED_NEW_STRING]]
// CHECK: destroy_value [[UPCAST_SELF_COPY]]
// This is an identity cast that should be eliminated by SILGen peepholes.
// CHECK: [[BORROWED_OLD_NSSTRING_BRIDGED:%.*]] = begin_borrow [[MOVED_OLD_NSSTRING_BRIDGED]]
// CHECK: [[DIDSET_NOTIFIER:%.*]] = function_ref @$s15objc_extensions3SubC4propSSSgvW : $@convention(method) (@guaranteed Optional<String>, @guaranteed Sub) -> ()
// CHECK: apply [[DIDSET_NOTIFIER]]([[BORROWED_OLD_NSSTRING_BRIDGED]], [[SELF]])
// CHECK: end_borrow [[BORROWED_OLD_NSSTRING_BRIDGED]]
// CHECK: destroy_value [[OLD_NSSTRING_BRIDGED]]
// CHECK: destroy_value [[MOVED_OLD_NSSTRING_BRIDGED]]
// CHECK: destroy_value [[NEW_VALUE]]
// CHECK: } // end sil function '$s15objc_extensions3SubC4propSSSgvs'

View File

@@ -501,11 +501,11 @@ public enum EnumWithTwoSameAddressOnlyPayloads<T> {
// CHECK-SAME: case #EnumWithTwoSameAddressOnlyPayloads.yes!enumelt: [[YES_BLOCK:bb[0-9]+]],
// CHECK-SAME: case #EnumWithTwoSameAddressOnlyPayloads.and!enumelt: [[AND_BLOCK:bb[0-9]+]]
// CHECK: [[YES_BLOCK]]([[YES_VALUE:%[^,]+]] :
// CHECK: [[YES_LIFETIME:%[^,]+]] = begin_borrow [lexical] [var_decl] [[YES_VALUE]]
// CHECK: [[YES_LIFETIME:%[^,]+]] = move_value [lexical] [var_decl] [[YES_VALUE]]
// CHECK: [[YES_COPY:%[^,]+]] = copy_value [[YES_LIFETIME]]
// CHECK: store [[YES_COPY]] to [init] [[RESULT_STORAGE]]
// CHECK: [[AND_BLOCK]]([[AND_VALUE:%[^,]+]] :
// CHECK: [[AND_LIFETIME:%[^,]+]] = begin_borrow [lexical] [var_decl] [[AND_VALUE]]
// CHECK: [[AND_LIFETIME:%[^,]+]] = move_value [lexical] [var_decl] [[AND_VALUE]]
// CHECK: [[AND_COPY:%[^,]+]] = copy_value [[AND_LIFETIME]]
// CHECK: store [[AND_COPY]] to [init] [[RESULT_STORAGE]]
// CHECK-LABEL: } // end sil function 'EnumWithTwoSameAddressOnlyPayloads_getPayload'

View File

@@ -723,8 +723,9 @@ func testRedundantRetains() {
// CHECK-LABEL: sil hidden [ossa] @$s10properties20testRedundantRetainsyyF : $@convention(thin) () -> () {
// CHECK: [[A:%[0-9]+]] = apply
// CHECK: [[MOVED_A:%[0-9]+]] = move_value [lexical] [var_decl] [[A]]
// CHECK-NOT: copy_value
// CHECK: destroy_value [[A]] : $RedundantRetains
// CHECK: destroy_value [[MOVED_A]] : $RedundantRetains
// CHECK-NOT: copy_value
// CHECK-NOT: destroy_value
// CHECK: return

View File

@@ -26,7 +26,8 @@ class Box<T> {
// CHECK: // function_ref Box.__allocating_init(_:)
// CHECK: [[INIT_F:%.*]] = function_ref @$s4main3BoxCyACyxGxcfC : $@convention(method) <τ_0_0> (@in τ_0_0, @thick Box<τ_0_0>.Type) -> @owned Box<τ_0_0>
// CHECK: [[CALL:%.*]] = apply [[INIT_F]]<(Int, () -> ())>(%{{.*}}, %{{.*}}) : $@convention(method) <τ_0_0> (@in τ_0_0, @thick Box<τ_0_0>.Type) -> @owned Box<τ_0_0>
// CHECK: [[BORROW_CALL:%.*]] = begin_borrow [lexical] [var_decl] [[CALL]] : $Box<(Int, () -> ())>
// CHECK: [[MOVE_CALL:%.*]] = move_value [lexical] [var_decl] [[CALL]] : $Box<(Int, () -> ())>
// CHECK: [[BORROW_CALL:%.*]] = begin_borrow [[MOVE_CALL]] : $Box<(Int, () -> ())>
// CHECK: [[REF:%.*]] = ref_element_addr [[BORROW_CALL]] : $Box<(Int, () -> ())>, #Box.value
// CHECK: [[TUPLEC:%.*]] = load [copy] [[REF]] : $*(Int, @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>)
// CHECK: ([[TUPLEC_0:%.*]], [[TUPLEC_1:%.*]]) = destructure_tuple [[TUPLEC]]

View File

@@ -30,18 +30,23 @@ func main() {
// CHECK: [[wrappedString:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[globalString]] : $NSString
// CHECK: [[stringMetaType:%.*]] = metatype $@thin String.Type
// CHECK: [[bridgedString:%.*]] = apply [[bridgeStringFunc]]([[wrappedString]], [[stringMetaType]]) : $@convention(method) (@guaranteed Optional<NSString>, @thin String.Type) -> @owned String
// CHECK: [[movedBridgedString:%.*]] = move_value [var_decl] [[bridgedString]]
let string = globalString // Problematic case, wasn't being retained
// CHECK: [[load_1:%.*]] = load [copy] {{%.*}} : $*Optional<NSObject>
// CHECK: [[move_1:%.*]] = move_value [lexical] [var_decl] [[load_1]]
let object = globalObject
// CHECK: [[load_2:%.*]] = load [copy] {{%.*}} : $*Optional<AnyObject>
// CHECK: [[move_2:%.*]] = move_value [lexical] [var_decl] [[load_2]]
let id = globalId
// CHECK: [[load_3:%.*]] = load [copy] {{%.*}} : $*Optional<NSArray>
// CHECK: [[move_3:%.*]] = move_value [lexical] [var_decl] [[load_3]]
let arr = globalArray
// CHECK: [[load_4:%.*]] = load [copy] {{%.*}} : $*Optional<NSArray>
// CHECK: [[move_4:%.*]] = move_value [lexical] [var_decl] [[load_4]]
let constArr = globalConstArray
// Make sure there's no more copies
@@ -55,11 +60,11 @@ func main() {
// CHECK: [[PRINT_FUN:%.*]] = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> ()
// CHECK: apply [[PRINT_FUN]]({{.*}})
// CHECK: destroy_value [[load_4]]
// CHECK: destroy_value [[load_3]]
// CHECK: destroy_value [[load_2]]
// CHECK: destroy_value [[load_1]]
// CHECK: destroy_value [[bridgedString]]
// CHECK: destroy_value [[move_4]]
// CHECK: destroy_value [[move_3]]
// CHECK: destroy_value [[move_2]]
// CHECK: destroy_value [[move_1]]
// CHECK: destroy_value [[movedBridgedString]]
// Make sure there's no more destroys
// CHECK-NOT: destroy_value

View File

@@ -361,6 +361,7 @@ func test_do() {
do {
// CHECK: [[CTOR:%.*]] = function_ref @$s10statements7MyClassC{{[_0-9a-zA-Z]*}}fC
// CHECK: [[OBJ:%.*]] = apply [[CTOR]](
// CHECK: [[OBJMOVE:%.*]] = move_value [lexical] [var_decl] [[OBJ]]
let obj = MyClass()
_ = obj
@@ -370,7 +371,7 @@ func test_do() {
bar(1)
// CHECK-NOT: br bb
// CHECK: destroy_value [[OBJ]]
// CHECK: destroy_value [[OBJMOVE]]
// CHECK-NOT: br bb
}
@@ -391,6 +392,7 @@ func test_do_labeled() {
lbl: do {
// CHECK: [[CTOR:%.*]] = function_ref @$s10statements7MyClassC{{[_0-9a-zA-Z]*}}fC
// CHECK: [[OBJ:%.*]] = apply [[CTOR]](
// CHECK: [[OBJMOVE:%.*]] = move_value [lexical] [var_decl] [[OBJ]]
let obj = MyClass()
_ = obj
@@ -403,7 +405,7 @@ func test_do_labeled() {
// CHECK: cond_br {{%.*}}, bb2, bb3
if (global_cond) {
// CHECK: bb2:
// CHECK: destroy_value [[OBJ]]
// CHECK: destroy_value [[OBJMOVE]]
// CHECK: br bb1
continue lbl
}
@@ -418,7 +420,7 @@ func test_do_labeled() {
// CHECK: cond_br {{%.*}}, bb4, bb5
if (global_cond) {
// CHECK: bb4:
// CHECK: destroy_value [[OBJ]]
// CHECK: destroy_value [[OBJMOVE]]
// CHECK: br bb6
break lbl
}
@@ -429,7 +431,7 @@ func test_do_labeled() {
// CHECK: apply [[BAR]](
bar(3)
// CHECK: destroy_value [[OBJ]]
// CHECK: destroy_value [[OBJMOVE]]
// CHECK: br bb6
}
@@ -604,11 +606,12 @@ func testRequireOptional2(_ a : String?) -> String {
guard let t = a else { abort() }
// CHECK: [[SOME_BB]]([[STR:%.*]] : @owned $String):
// CHECK-NEXT: [[BORROWED_STR:%.*]] = begin_borrow [var_decl] [[STR]]
// CHECK-NEXT: debug_value [[BORROWED_STR]] : $String, let, name "t"
// CHECK: [[STRMOVE:%.*]] = move_value [var_decl] [[STR]]
// CHECK-NEXT: debug_value [[STRMOVE]] : $String, let, name "t"
// CHECK-NEXT: [[BORROWED_STR:%.*]] = begin_borrow [[STRMOVE]]
// CHECK-NEXT: [[RETURN:%.*]] = copy_value [[BORROWED_STR]]
// CHECK-NEXT: end_borrow [[BORROWED_STR]]
// CHECK-NEXT: destroy_value [[STR]] : $String
// CHECK-NEXT: destroy_value [[STRMOVE]] : $String
// CHECK-NEXT: return [[RETURN]] : $String
// CHECK: [[NONE_BB]]:
@@ -648,11 +651,12 @@ func test_as_pattern(_ y : BaseClass) -> DerivedClass {
// CHECK: bb{{.*}}([[PTR:%[0-9]+]] : @owned $DerivedClass):
// CHECK-NEXT: [[BORROWED_PTR:%.*]] = begin_borrow [lexical] [var_decl] [[PTR]]
// CHECK-NEXT: debug_value [[BORROWED_PTR]] : $DerivedClass, let, name "result"
// CHECK-NEXT: [[MOVED_PTR:%.*]] = move_value [lexical] [var_decl] [[PTR]]
// CHECK-NEXT: debug_value [[MOVED_PTR]] : $DerivedClass, let, name "result"
// CHECK-NEXT: [[BORROWED_PTR:%.*]] = begin_borrow [[MOVED_PTR]]
// CHECK-NEXT: [[RESULT:%.*]] = copy_value [[BORROWED_PTR]]
// CHECK-NEXT: end_borrow [[BORROWED_PTR]]
// CHECK-NEXT: destroy_value [[PTR]] : $DerivedClass
// CHECK-NEXT: destroy_value [[MOVED_PTR]] : $DerivedClass
// CHECK-NEXT: return [[RESULT]] : $DerivedClass
return result
}

View File

@@ -543,22 +543,23 @@ func test_isa_class_2(x: B) -> AnyObject {
case let y as D1 where runced():
// CHECK: [[IS_D1]]([[CAST_D1:%.*]] : @guaranteed $D1):
// CHECK: [[CAST_D1_COPY:%.*]] = copy_value [[CAST_D1]]
// CHECK: [[BORROWED_CAST_D1_COPY:%.*]] = begin_borrow [lexical] [var_decl] [[CAST_D1_COPY]]
// CHECK: [[MOVED_D1_COPY:%.*]] = move_value [lexical] [var_decl] [[CAST_D1_COPY]]
// CHECK: function_ref @$s6switch6runcedSbyF
// CHECK: cond_br {{%.*}}, [[CASE1:bb[0-9]+]], [[NO_CASE1:bb[0-9]+]]
// CHECK: [[CASE1]]:
// CHECK: function_ref @$s6switch1ayyF
// CHECK: [[BORROWED_CAST_D1_COPY:%.*]] = begin_borrow [[MOVED_D1_COPY]]
// CHECK: [[CAST_D1_COPY_COPY:%.*]] = copy_value [[BORROWED_CAST_D1_COPY]]
// CHECK: [[RET:%.*]] = init_existential_ref [[CAST_D1_COPY_COPY]]
// CHECK: end_borrow [[BORROWED_CAST_D1_COPY]]
// CHECK: destroy_value [[CAST_D1_COPY]]
// CHECK: destroy_value [[MOVED_D1_COPY]]
// CHECK: br [[CONT:bb[0-9]+]]([[RET]] : $AnyObject)
a()
return y
// CHECK: [[NO_CASE1]]:
// CHECK: destroy_value [[CAST_D1_COPY]]
// CHECK: destroy_value [[MOVED_D1_COPY]]
// CHECK: br [[NEXT_CASE:bb5]]
// CHECK: [[IS_NOT_D1]]([[NOCAST_D1:%.*]] : @guaranteed $B):
@@ -569,12 +570,13 @@ func test_isa_class_2(x: B) -> AnyObject {
case let y as D2:
// CHECK: [[CASE2]]([[CAST_D2:%.*]] : @guaranteed $D2):
// CHECK: [[CAST_D2_COPY:%.*]] = copy_value [[CAST_D2]]
// CHECK: [[BORROWED_CAST_D2_COPY:%.*]] = begin_borrow [lexical] [var_decl] [[CAST_D2_COPY]]
// CHECK: [[MOVED_CAST_D2_COPY:%.*]] = move_value [lexical] [var_decl] [[CAST_D2_COPY]]
// CHECK: function_ref @$s6switch1byyF
// CHECK: [[BORROWED_CAST_D2_COPY:%.*]] = begin_borrow [[MOVED_CAST_D2_COPY]]
// CHECK: [[CAST_D2_COPY_COPY:%.*]] = copy_value [[BORROWED_CAST_D2_COPY]]
// CHECK: [[RET:%.*]] = init_existential_ref [[CAST_D2_COPY_COPY]]
// CHECK: end_borrow [[BORROWED_CAST_D2_COPY]]
// CHECK: destroy_value [[CAST_D2_COPY]]
// CHECK: destroy_value [[MOVED_CAST_D2_COPY]]
// CHECK: br [[CONT]]([[RET]] : $AnyObject)
b()
return y
@@ -584,22 +586,23 @@ func test_isa_class_2(x: B) -> AnyObject {
case let y as E where funged():
// CHECK: [[IS_E]]([[CAST_E:%.*]] : @guaranteed $E):
// CHECK: [[CAST_E_COPY:%.*]] = copy_value [[CAST_E]]
// CHECK: [[BORROWED_CAST_E_COPY:%.*]] = begin_borrow [lexical] [var_decl] [[CAST_E_COPY]]
// CHECK: [[MOVED_CAST_E_COPY:%.*]] = move_value [lexical] [var_decl] [[CAST_E_COPY]]
// CHECK: function_ref @$s6switch6fungedSbyF
// CHECK: cond_br {{%.*}}, [[CASE3:bb[0-9]+]], [[NO_CASE3:bb[0-9]+]]
// CHECK: [[CASE3]]:
// CHECK: function_ref @$s6switch1cyyF
// CHECK: [[BORROWED_CAST_E_COPY:%.*]] = begin_borrow [[MOVED_CAST_E_COPY]]
// CHECK: [[CAST_E_COPY_COPY:%.*]] = copy_value [[BORROWED_CAST_E_COPY]]
// CHECK: [[RET:%.*]] = init_existential_ref [[CAST_E_COPY_COPY]]
// CHECK: end_borrow [[BORROWED_CAST_E_COPY]]
// CHECK: destroy_value [[CAST_E_COPY]]
// CHECK: destroy_value [[MOVED_CAST_E_COPY]]
// CHECK: br [[CONT]]([[RET]] : $AnyObject)
c()
return y
// CHECK: [[NO_CASE3]]:
// CHECK: destroy_value [[CAST_E_COPY]]
// CHECK: destroy_value [[MOVED_CAST_E_COPY]]
// CHECK: br [[NEXT_CASE:bb[0-9]+]]
// CHECK: [[IS_NOT_E]]([[NOCAST_E:%.*]] : @guaranteed $B):
@@ -610,12 +613,13 @@ func test_isa_class_2(x: B) -> AnyObject {
case let y as C:
// CHECK: [[CASE4]]([[CAST_C:%.*]] : @guaranteed $C):
// CHECK: [[CAST_C_COPY:%.*]] = copy_value [[CAST_C]]
// CHECK: [[BORROWED_CAST_C_COPY:%.*]] = begin_borrow [lexical] [var_decl] [[CAST_C_COPY]]
// CHECK: [[MOVED_CAST_C_COPY:%.*]] = move_value [lexical] [var_decl] [[CAST_C_COPY]]
// CHECK: function_ref @$s6switch1dyyF
// CHECK: [[BORROWED_CAST_C_COPY:%.*]] = begin_borrow [[MOVED_CAST_C_COPY]]
// CHECK: [[CAST_C_COPY_COPY:%.*]] = copy_value [[BORROWED_CAST_C_COPY]]
// CHECK: [[RET:%.*]] = init_existential_ref [[CAST_C_COPY_COPY]]
// CHECK: end_borrow [[BORROWED_CAST_C_COPY]]
// CHECK: destroy_value [[CAST_C_COPY]]
// CHECK: destroy_value [[MOVED_CAST_C_COPY]]
// CHECK: br [[CONT]]([[RET]] : $AnyObject)
d()
return y
@@ -1371,10 +1375,9 @@ func partial_address_only_tuple_dispatch(_ name: Klass, _ value: Any?) {
//
// CHECK: [[IS_ANY_BB]]:
// CHECK-NEXT: [[ANYOBJECT:%.*]] = load [take] [[ANYOBJECT_ADDR]]
// CHECK-NEXT: begin_borrow
// CHECK-NEXT: [[MOVED:%.*]] = move_value
// CHECK-NEXT: debug_value
// CHECK-NEXT: end_borrow
// CHECK-NEXT: destroy_value [[ANYOBJECT]]
// CHECK-NEXT: destroy_value [[MOVED]]
// CHECK-NEXT: dealloc_stack [[ANYOBJECT_ADDR]]
// CHECK-NEXT: destroy_addr [[SOME_ANY_ADDR]]
// CHECK-NEXT: dealloc_stack [[OPT_ANY_ADDR]]
@@ -1538,15 +1541,16 @@ func addressOnlyFallthroughCaller() {
//
// CHECK: [[BB_A]]([[BB_A_ARG:%.*]] : @guaranteed
// CHECK: [[BB_A_ARG_COPY:%.*]] = copy_value [[BB_A_ARG]]
// CHECK: [[BB_A_ARG_COPY_BORROW:%.*]] = begin_borrow [lexical] [var_decl] [[BB_A_ARG_COPY]]
// CHECK: [[BB_A_ARG_COPY_MOVE:%.*]] = move_value [lexical] [var_decl] [[BB_A_ARG_COPY]]
// CHECK: [[BB_A_ARG_COPY_BORROW:%.*]] = begin_borrow [[BB_A_ARG_COPY_MOVE]]
// CHECK: apply {{%.*}}([[BB_A_ARG_COPY_BORROW]])
// CHECK: [[RESULT:%.*]] = copy_value [[BB_A_ARG_COPY_BORROW]]
// CHECK: [[RESULT:%.*]] = copy_value [[BB_A_ARG_COPY_MOVE]]
// CHECK: br [[BB_AB:bb[0-9]+]]([[RESULT]] :
//
// CHECK: [[BB_B]]([[BB_B_ARG:%.*]] : @guaranteed
// CHECK: [[BB_B_ARG_COPY:%.*]] = copy_value [[BB_B_ARG]]
// CHECK: [[BB_B_ARG_COPY_BORROW:%.*]] = begin_borrow [lexical] [var_decl] [[BB_B_ARG_COPY]]
// CHECK: [[RESULT:%.*]] = copy_value [[BB_B_ARG_COPY_BORROW]]
// CHECK: [[BB_B_ARG_COPY_MOVE:%.*]] = move_value [lexical] [var_decl] [[BB_B_ARG_COPY]]
// CHECK: [[RESULT:%.*]] = copy_value [[BB_B_ARG_COPY_MOVE]]
// CHECK: br [[BB_AB:bb[0-9]+]]([[RESULT]] :
//
// CHECK: [[BB_AB:bb[0-9]+]]([[BB_AB_PHI:%.*]] : @owned
@@ -1557,8 +1561,8 @@ func addressOnlyFallthroughCaller() {
//
// CHECK: [[BB_C]]([[BB_C_ARG:%.*]] : @guaranteed
// CHECK: [[BB_C_COPY:%.*]] = copy_value [[BB_C_ARG]]
// CHECK: [[BB_C_BORROWED_COPY:%.*]] = begin_borrow [lexical] [var_decl] [[BB_C_COPY]]
// CHECK: [[RESULT:%.*]] = copy_value [[BB_C_BORROWED_COPY]]
// CHECK: [[BB_C_BORROWED_MOVE:%.*]] = move_value [lexical] [var_decl] [[BB_C_COPY]]
// CHECK: [[RESULT:%.*]] = copy_value [[BB_C_BORROWED_MOVE]]
// CHECK: br [[BB_ABC]]([[RESULT]] :
//
// CHECK: [[BB_ABC]]([[BB_ABC_ARG:%.*]] : @owned

View File

@@ -65,27 +65,23 @@ func guardFn(_ l: D, _ r: D) -> Bool { return true }
//
// CHECK: [[L_CAST_YES]]([[L:%.*]] : @guaranteed $D):
// CHECK: [[L2:%.*]] = copy_value [[L]]
// CHECK: [[BORROWED_R2:%.*]] = begin_borrow [lexical] [var_decl] [[R2]]
// CHECK: [[BORROWED_L2:%.*]] = begin_borrow [lexical] [var_decl] [[L2]]
// CHECK: [[MOVED_R2:%.*]] = move_value [lexical] [var_decl] [[R2]]
// CHECK: [[MOVED_L2:%.*]] = move_value [lexical] [var_decl] [[L2]]
// CHECK: function_ref @$s10switch_isa7guardFnySbAA1DC_ADtF
// CHECK: cond_br {{%.*}}, [[GUARD_YES:bb[0-9]+]], [[GUARD_NO:bb[0-9]+]]
//
// CHECK: [[GUARD_YES]]:
// CHECK-NEXT: debug_value [[BORROWED_R2]]
// CHECK-NEXT: debug_value [[BORROWED_L2]]
// CHECK-NEXT: end_borrow [[BORROWED_L2]]
// CHECK-NEXT: destroy_value [[L2]]
// CHECK-NEXT: end_borrow [[BORROWED_R2]]
// CHECK-NEXT: destroy_value [[R2]]
// CHECK-NEXT: debug_value [[MOVED_R2]]
// CHECK-NEXT: debug_value [[MOVED_L2]]
// CHECK-NEXT: destroy_value [[MOVED_L2]]
// CHECK-NEXT: destroy_value [[MOVED_R2]]
// CHECK-NEXT: end_borrow [[BORROWED_TUP]]
// CHECK-NEXT: destroy_value [[TUP]]
// CHECK-NEXT: br [[EXIT:bb[0-9]+]]
//
// CHECK: [[GUARD_NO]]:
// CHECK-NEXT: end_borrow [[BORROWED_L2]]
// CHECK-NEXT: destroy_value [[L2]]
// CHECK-NEXT: end_borrow [[BORROWED_R2]]
// CHECK-NEXT: destroy_value [[R2]]
// CHECK-NEXT: destroy_value [[MOVED_L2]]
// CHECK-NEXT: destroy_value [[MOVED_R2]]
// CHECK-NEXT: end_borrow [[BORROWED_TUP]]
// CHECK-NEXT: br [[CONT:bb[0-9]+]]
//

View File

@@ -417,46 +417,50 @@ func test_let() {
// CHECK: [[VAL:%.*]] = apply [[FOOS]]()
// CHECK: [[BORROWED_VAL:%.*]] = begin_borrow [[VAL]]
// CHECK: [[VAL_COPY:%.*]] = copy_value [[BORROWED_VAL]]
// CHECK: [[VAL_LIFETIME:%.*]] = begin_borrow [var_decl] [[VAL_COPY]]
// CHECK: [[VAL_MOVE:%.*]] = move_value [var_decl] [[VAL_COPY]]
// CHECK: function_ref @$s10switch_var6runcedSbyF
// CHECK: cond_br {{%.*}}, [[CASE1:bb[0-9]+]], [[NO_CASE1:bb[0-9]+]]
switch foos() {
case let x where runced():
// CHECK: [[CASE1]]:
// CHECK: [[VAL_BORROW:%.*]] = begin_borrow [[VAL_MOVE]]
// CHECK: [[A:%.*]] = function_ref @$s10switch_var1a1xySS_tF
// CHECK: apply [[A]]([[VAL_LIFETIME]])
// CHECK: destroy_value [[VAL_COPY]]
// CHECK: apply [[A]]([[VAL_BORROW]])
// CHECK: end_borrow [[VAL_BORROW]]
// CHECK: destroy_value [[VAL_MOVE]]
// CHECK: destroy_value [[VAL]]
// CHECK: br [[CONT:bb[0-9]+]]
a(x: x)
// CHECK: [[NO_CASE1]]:
// CHECK: destroy_value [[VAL_COPY]]
// CHECK: destroy_value [[VAL_MOVE]]
// CHECK: [[BORROWED_VAL_2:%.*]] = begin_borrow [[VAL]]
// CHECK: [[VAL_COPY_2:%.*]] = copy_value [[BORROWED_VAL_2]]
// CHECK: [[BORROWED_VAL_COPY_2:%.*]] = begin_borrow [var_decl] [[VAL_COPY_2]]
// CHECK: [[VAL_MOVE_2:%.*]] = move_value [var_decl] [[VAL_COPY_2]]
// CHECK: function_ref @$s10switch_var6fungedSbyF
// CHECK: cond_br {{%.*}}, [[CASE2:bb[0-9]+]], [[NO_CASE2:bb[0-9]+]]
case let y where funged():
// CHECK: [[CASE2]]:
// CHECK: [[BORROWED_VAL_MOVE_2:%.*]] = begin_borrow [[VAL_MOVE_2]]
// CHECK: [[B:%.*]] = function_ref @$s10switch_var1b1xySS_tF
// CHECK: apply [[B]]([[BORROWED_VAL_COPY_2]])
// CHECK: destroy_value [[VAL_COPY_2]]
// CHECK: apply [[B]]([[BORROWED_VAL_MOVE_2]])
// CHECK: destroy_value [[VAL_MOVE_2]]
// CHECK: destroy_value [[VAL]]
// CHECK: br [[CONT]]
b(x: y)
// CHECK: [[NO_CASE2]]:
// CHECK: destroy_value [[VAL_COPY_2]]
// CHECK: destroy_value [[VAL_MOVE_2]]
// CHECK: [[BORROWED_VAL_3:%.*]] = begin_borrow [[VAL]]
// CHECK: [[VAL_COPY_3:%.*]] = copy_value [[BORROWED_VAL_3]]
// CHECK: [[BORROWED_VAL_COPY_3:%.*]] = begin_borrow [var_decl] [[VAL_COPY_3]]
// CHECK: [[VAL_MOVE_3:%.*]] = move_value [var_decl] [[VAL_COPY_3]]
// CHECK: function_ref @$s10switch_var4barsSSyF
// CHECK: [[SB:%.*]] = store_borrow [[BORROWED_VAL_COPY_3]] to [[IN_ARG:%.*]] :
// CHECK: [[BORROWED_VAL_MOVE_3:%.*]] = begin_borrow [[VAL_MOVE_3]]
// CHECK: [[SB:%.*]] = store_borrow [[BORROWED_VAL_MOVE_3]] to [[IN_ARG:%.*]] :
// CHECK: apply {{%.*}}<String>({{.*}}, [[SB]])
// CHECK: cond_br {{%.*}}, [[YES_CASE3:bb[0-9]+]], [[NO_CASE3:bb[0-9]+]]
// ExprPatterns implicitly contain a 'let' binding.
case bars():
// CHECK: [[YES_CASE3]]:
// CHECK: destroy_value [[VAL_COPY_3]]
// CHECK: destroy_value [[VAL_MOVE_3]]
// CHECK: [[FUNC:%.*]] = function_ref @$s10switch_var1cyyF
// CHECK-NEXT: apply [[FUNC]](
// CHECK: destroy_value [[VAL]]
@@ -465,7 +469,7 @@ func test_let() {
case _:
// CHECK: [[NO_CASE3]]:
// CHECK: destroy_value [[VAL_COPY_3]]
// CHECK: destroy_value [[VAL_MOVE_3]]
// CHECK: function_ref @$s10switch_var1dyyF
// CHECK: destroy_value [[VAL]]
// CHECK: br [[CONT]]
@@ -506,31 +510,33 @@ func test_mixed_let_var() {
// CHECK: destroy_value [[BOX]]
// CHECK: [[BORROWED_VAL:%.*]] = begin_borrow [[VAL]]
// CHECK: [[VAL_COPY:%.*]] = copy_value [[BORROWED_VAL]]
// CHECK: [[BORROWED_VAL_COPY:%.*]] = begin_borrow [var_decl] [[VAL_COPY]]
// CHECK: [[VAL_MOVE:%.*]] = move_value [var_decl] [[VAL_COPY]]
// CHECK: cond_br {{.*}}, [[CASE2:bb[0-9]+]], [[NOCASE2:bb[0-9]+]]
case let y where funged():
// CHECK: [[CASE2]]:
// CHECK: [[BORROWED_VAL_MOVE:%.*]] = begin_borrow [[VAL_MOVE]]
// CHECK: [[B:%.*]] = function_ref @$s10switch_var1b1xySS_tF
// CHECK: apply [[B]]([[BORROWED_VAL_COPY]])
// CHECK: end_borrow [[BORROWED_VAL_COPY]]
// CHECK: destroy_value [[VAL_COPY]]
// CHECK: apply [[B]]([[BORROWED_VAL_MOVE]])
// CHECK: end_borrow [[BORROWED_VAL_MOVE]]
// CHECK: destroy_value [[VAL_MOVE]]
// CHECK: destroy_value [[VAL]]
// CHECK: br [[CONT]]
b(x: y)
// CHECK: [[NOCASE2]]:
// CHECK: destroy_value [[VAL_COPY]]
// CHECK: destroy_value [[VAL_MOVE]]
// CHECK: [[BORROWED_VAL:%.*]] = begin_borrow [[VAL]]
// CHECK: [[VAL_COPY:%.*]] = copy_value [[BORROWED_VAL]]
// CHECK: [[BORROWED_VAL_COPY:%.*]] = begin_borrow [var_decl] [[VAL_COPY]]
// CHECK: [[SB:%.*]] = store_borrow [[BORROWED_VAL_COPY]] to [[TMP_VAL_COPY_ADDR:%.*]] :
// CHECK: [[VAL_MOVE:%.*]] = move_value [var_decl] [[VAL_COPY]]
// CHECK: [[BORROWED_VAL_MOVE:%.*]] = begin_borrow [[VAL_MOVE]]
// CHECK: [[SB:%.*]] = store_borrow [[BORROWED_VAL_MOVE]] to [[TMP_VAL_COPY_ADDR:%.*]] :
// CHECK: apply {{.*}}<String>({{.*}}, [[SB]])
// CHECK: cond_br {{.*}}, [[CASE3:bb[0-9]+]], [[NOCASE3:bb[0-9]+]]
case bars():
// CHECK: [[CASE3]]:
// CHECK: destroy_value [[VAL_COPY]]
// CHECK: destroy_value [[VAL_MOVE]]
// CHECK: [[FUNC:%.*]] = function_ref @$s10switch_var1cyyF : $@convention(thin) () -> ()
// CHECK: apply [[FUNC]]()
// CHECK: destroy_value [[VAL]]
@@ -538,7 +544,7 @@ func test_mixed_let_var() {
c()
// CHECK: [[NOCASE3]]:
// CHECK: destroy_value [[VAL_COPY]]
// CHECK: destroy_value [[VAL_MOVE]]
// CHECK: [[D_FUNC:%.*]] = function_ref @$s10switch_var1dyyF : $@convention(thin) () -> ()
// CHECK: apply [[D_FUNC]]()
// CHECK: destroy_value [[VAL]]
@@ -728,11 +734,12 @@ func test_multiple_patterns_value_semantics(_ y: C) {
switch y {
// CHECK: checked_cast_br C in {{%.*}} : $C to D, [[AS_D:bb[0-9]+]], [[NOT_AS_D:bb[0-9]+]]
// CHECK: [[AS_D]]({{.*}}):
// CHECK: [[ORIG_BORROW:%.*]] = begin_borrow [lexical] [var_decl] [[ORIG:%.*]] :
// CHECK: [[ORIG_MOVE:%.*]] = move_value [lexical] [var_decl] [[ORIG:%.*]] :
// CHECK: [[ORIG_BORROW:%.*]] = begin_borrow [[ORIG_MOVE:%.*]] :
// CHECK: cond_br {{%.*}}, [[F_TRUE:bb[0-9]+]], [[F_FALSE:bb[0-9]+]]
// CHECK: [[F_TRUE]]:
// CHECK: [[BINDING:%.*]] = copy_value [[ORIG_BORROW]] :
// CHECK: destroy_value [[ORIG]]
// CHECK: [[BINDING:%.*]] = copy_value [[ORIG_MOVE]] :
// CHECK: destroy_value [[ORIG_MOVE]]
// CHECK: br {{bb[0-9]+}}([[BINDING]]
case let x as D where f(x), let x as D: break
default: break

View File

@@ -191,23 +191,24 @@ public func testTupleAssign(x: inout [Int]) {
// CHECK: [[X:%.*]] = copy_value %0 : $C
// CHECK: [[Z:%.*]] = copy_value %2 : $String
// CHECK: [[INPUT:%.*]] = tuple $(x: C, y: Int, z: String) ([[X]], %1, [[Z]])
// CHECK: [[INPUT_BORROW:%.*]] = begin_borrow [lexical] [var_decl] [[INPUT]] : $(x: C, y: Int, z: String)
// CHECK: [[INPUT_MOVE:%.*]] = move_value [lexical] [var_decl] [[INPUT]] : $(x: C, y: Int, z: String)
// CHECK: [[OUTPUT:%.*]] = alloc_stack [lexical] $(y: Optional<Int>, z: Any, x: AnyObject)
// CHECK: [[INPUT_BORROW:%.*]] = begin_borrow [[INPUT_MOVE]] : $(x: C, y: Int, z: String)
// CHECK: [[INPUT_COPY:%.*]] = copy_value [[INPUT_BORROW]] : $(x: C, y: Int, z: String)
// CHECK: ([[X:%.*]], [[Y:%.*]], [[Z:%.*]]) = destructure_tuple %12 : $(x: C, y: Int, z: String)
// CHECK: ([[X:%.*]], [[Y:%.*]], [[Z:%.*]]) = destructure_tuple [[INPUT_COPY]] : $(x: C, y: Int, z: String)
// CHECK: [[Y_ADDR:%.*]] = tuple_element_addr [[OUTPUT]] : $*(y: Optional<Int>, z: Any, x: AnyObject), 0
// CHECK: [[Z_ADDR:%.*]] = tuple_element_addr [[OUTPUT]] : $*(y: Optional<Int>, z: Any, x: AnyObject), 1
// CHECK: [[X_ADDR:%.*]] = tuple_element_addr [[OUTPUT]] : $*(y: Optional<Int>, z: Any, x: AnyObject), 2
// CHECK: [[NEW_Y:%.*]] = enum $Optional<Int>, #Optional.some!enumelt, %14 : $Int
// CHECK: [[NEW_Y:%.*]] = enum $Optional<Int>, #Optional.some!enumelt, [[Y]] : $Int
// CHECK: store [[NEW_Y]] to [trivial] [[Y_ADDR]] : $*Optional<Int>
// CHECK: [[NEW_Z:%.*]] = init_existential_addr [[Z_ADDR]] : $*Any, $String
// CHECK: store [[Z]] to [init] [[NEW_Z]] : $*String
// CHECK: [[NEW_X:%.*]] = init_existential_ref [[X]] : $C : $C, $AnyObject
// CHECK: store [[NEW_X]] to [init] [[X_ADDR]] : $*AnyObject
// CHECK: end_borrow [[INPUT_BORROW]] : $(x: C, y: Int, z: String)
// CHECK: destroy_addr [[OUTPUT]] : $*(y: Optional<Int>, z: Any, x: AnyObject)
// CHECK: dealloc_stack [[OUTPUT]] : $*(y: Optional<Int>, z: Any, x: AnyObject)
// CHECK: end_borrow [[INPUT_BORROW]] : $(x: C, y: Int, z: String)
// CHECK: destroy_value [[INPUT]] : $(x: C, y: Int, z: String)
// CHECK: destroy_value [[INPUT_MOVE]] : $(x: C, y: Int, z: String)
public func testTupleSubtype(x: C, y: Int, z: String) {
let input = (x: x, y: y, z: z)

View File

@@ -89,10 +89,11 @@ func testunowned_local() -> C {
// CHECK: [[C:%.*]] = apply
let c = C()
// CHECK: [[BORROWED_C:%.*]] = begin_borrow [lexical] [var_decl] [[C]]
// CHECK: [[MOVED_C:%.*]] = move_value [lexical] [var_decl] [[C]]
// CHECK: [[UC:%.*]] = alloc_box ${ var @sil_unowned C }, let, name "uc"
// CHECK: [[UC_LIFETIME:%[^,]+]] = begin_borrow [lexical] [var_decl] [[UC]]
// CHECK: [[PB_UC:%.*]] = project_box [[UC_LIFETIME]]
// CHECK: [[BORROWED_C:%.*]] = begin_borrow [[MOVED_C]]
// CHECK: [[C_COPY:%.*]] = copy_value [[BORROWED_C]]
// CHECK: [[tmp1:%.*]] = ref_to_unowned [[C_COPY]] : $C to $@sil_unowned C
// CHECK: [[tmp1_copy:%.*]] = copy_value [[tmp1]]
@@ -107,7 +108,7 @@ func testunowned_local() -> C {
// CHECK: end_borrow [[UC_LIFETIME]]
// CHECK: destroy_value [[UC]]
// CHECK: destroy_value [[C]]
// CHECK: destroy_value [[MOVED_C]]
// CHECK: return [[tmp3]]
}

View File

@@ -126,7 +126,7 @@ func copyOrThrowIntoTuple<each T>(_ args: repeat each T) throws -> (repeat each
// CHECK-NEXT: debug_value [[A]] : $Int
// CHECK-NEXT: [[B:%.*]] = load [take] [[R1]] : $*String
// CHECK-NEXT: [[C:%.*]] = load [take] [[R2]] : $*String
// CHECK-NEXT: [[C_LIFETIME:%.*]] = begin_borrow [var_decl] [[C]]
// CHECK-NEXT: [[C_LIFETIME:%.*]] = move_value [var_decl] [[C]]
// CHECK-NEXT: debug_value [[C_LIFETIME]] : $String
// CHECK-NEXT: destroy_value [[B]] : $String
// End of statement.
@@ -139,8 +139,7 @@ func copyOrThrowIntoTuple<each T>(_ args: repeat each T) throws -> (repeat each
// CHECK-NEXT: [[SEQUENCE_FN:%.*]] = function_ref @$s4main8sequenceyyF
// CHECK-NEXT: apply [[SEQUENCE_FN]]()
// Leave the function.
// CHECK-NEXT: end_borrow [[C_LIFETIME]] : $String
// CHECK-NEXT: destroy_value [[C]] : $String
// CHECK-NEXT: destroy_value [[C_LIFETIME]] : $String
// CHECK-NEXT: [[RET:%.*]] = tuple ()
// CHECK-NEXT: return [[RET]] : $()
func callCopyAndDestructure(a: Int, b: String, c: String) {

View File

@@ -240,7 +240,8 @@ struct TupleHolder<each T> {
// CHECK: [[T0:%.*]] = copy_value %0 :
// CHECK: [[T1:%.*]] = begin_borrow [[T0]]
// CHECK: [[RESULT:%.*]] = apply [[T1]]() :
// CHECK: destroy_value [[RESULT]]
// CHECK: [[MOVE:%.*]] = move_value [var_decl] [[RESULT]]
// CHECK: destroy_value [[MOVE]]
func takesConcreteTupleHolderFactory(factory: () -> TupleHolder<Int, String>) {
let holder = factory()
}

View File

@@ -88,7 +88,8 @@ func modifyAndPerform<T>(_ _: UnsafeMutablePointer<T>, closure: () ->()) {
// CHECK-LABEL: sil hidden [ossa] @$s25without_actually_escaping0A24ActuallyEscapingConflictyyF : $@convention(thin) () -> () {
// CHECK: [[CLOSURE_1_FUN:%.*]] = function_ref @$s25without_actually_escaping0A24ActuallyEscapingConflictyyFyycfU_ :
// CHECK: [[CLOSURE_1:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE_1_FUN]](
// CHECK: [[BORROWED_CLOSURE_1:%.*]] = begin_borrow [lexical] [var_decl] [[CLOSURE_1]]
// CHECK: [[MOVED_CLOSURE_1:%.*]] = move_value [lexical] [var_decl] [[CLOSURE_1]]
// CHECK: [[BORROWED_CLOSURE_1:%.*]] = begin_borrow [[MOVED_CLOSURE_1]]
// CHECK: [[COPY_BORROWED_CLOSURE_1:%.*]] = copy_value [[BORROWED_CLOSURE_1]]
// CHECK: [[COPY_2_BORROWED_CLOSURE_1:%.*]] = copy_value [[COPY_BORROWED_CLOSURE_1]]
// CHECK: [[THUNK_FUNC:%.*]] = function_ref @$sIeg_Ieg_TR :

View File

@@ -48,6 +48,7 @@ func testSimpleInterpolation() {
// CHECK-DAG: try_apply [[FOREACH]]<Array<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>>({{%.*}}, [[SB:%[0-9]+]])
// CHECK-DAG: [[SB]] = store_borrow [[FINARR:%[0-9]+]] to [[ARGSARRAYADDR:%[0-9]+]]
// We need to wade through some borrows and copy values here.
// CHECK-DAG: [[FINARR]] = move_value [var_decl] [[FINARR:%[0-9]+]]
// CHECK-DAG: [[FINARRFUNC:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
// CHECK-DAG: [[FINARR]] = apply [[FINARRFUNC]]<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>([[ARGSARRAY:%[0-9]+]])
// CHECK-DAG: ([[ARGSARRAY]], {{%.*}}) = destructure_tuple [[ARRAYINITRES:%[0-9]+]]
@@ -91,6 +92,7 @@ func testInterpolationWithFormatOptions() {
// CHECK-DAG: [[FOREACH:%[0-9]+]] = function_ref @$sSTsE7forEachyyy7ElementQzKXEKF
// CHECK-DAG: try_apply [[FOREACH]]<Array<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>>({{%.*}}, [[SB:%[0-9]+]])
// CHECK-DAG: [[SB]] = store_borrow [[FINARR:%[0-9]+]] to [[ARGSARRAYADDR:%[0-9]+]]
// CHECK-DAG: [[FINARR]] = move_value [var_decl] [[FINARR:%[0-9]+]]
// CHECK-DAG: [[FINARRFUNC:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
// CHECK-DAG: [[FINARR]] = apply [[FINARRFUNC]]<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>([[ARGSARRAY:%[0-9]+]])
// CHECK-DAG: ([[ARGSARRAY]], {{%.*}}) = destructure_tuple [[ARRAYINITRES:%[0-9]+]]
@@ -136,6 +138,7 @@ func testInterpolationWithFormatOptionsAndPrivacy() {
// CHECK-DAG: [[FOREACH:%[0-9]+]] = function_ref @$sSTsE7forEachyyy7ElementQzKXEKF
// CHECK-DAG: try_apply [[FOREACH]]<Array<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>>({{%.*}}, [[SB:%[0-9]+]])
// CHECK-DAG: [[SB]] = store_borrow [[FINARR:%[0-9]+]] to [[ARGSARRAYADDR:%[0-9]+]]
// CHECK-DAG: [[FINARR]] = move_value [var_decl] [[FINARR:%[0-9]+]]
// CHECK-DAG: [[FINARRFUNC:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
// CHECK-DAG: [[FINARR]] = apply [[FINARRFUNC]]<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>([[ARGSARRAY:%[0-9]+]])
// CHECK-DAG: ([[ARGSARRAY]], {{%.*}}) = destructure_tuple [[ARRAYINITRES:%[0-9]+]]
@@ -187,6 +190,7 @@ func testInterpolationWithMultipleArguments() {
// CHECK-DAG: [[FOREACH:%[0-9]+]] = function_ref @$sSTsE7forEachyyy7ElementQzKXEKF
// CHECK-DAG: try_apply [[FOREACH]]<Array<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>>({{%.*}}, [[SB:%[0-9]+]])
// CHECK-DAG: [[SB]] = store_borrow [[FINARR:%[0-9]+]] to [[ARGSARRAYADDR:%[0-9]+]]
// CHECK-DAG: [[FINARR]] = move_value [var_decl] [[FINARR:%[0-9]+]]
// CHECK-DAG: [[ARGSARRAYADDR]] = alloc_stack $Array<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>
// CHECK-DAG: [[FINARRFUNC:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
// CHECK-DAG: [[FINARR]] = apply [[FINARRFUNC]]<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>([[ARGSARRAY:%[0-9]+]])
@@ -235,6 +239,7 @@ func testLogMessageWithoutData() {
// CHECK-DAG: [[FOREACH:%[0-9]+]] = function_ref @$sSTsE7forEachyyy7ElementQzKXEKF
// CHECK-DAG: try_apply [[FOREACH]]<Array<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>>({{%.*}}, [[SB:%[0-9]+]])
// CHECK-DAG: [[SB]] = store_borrow [[ARGSARRAY:%[0-9]+]] to {{.*}}
// CHECK-DAG: [[ARGSARRAY]] = move_value [var_decl] [[ARGSARRAY:%[0-9]+]]
// CHECK-DAG: ([[ARGSARRAY]], {{%.*}}) = destructure_tuple [[ARRAYINITRES:%[0-9]+]]
// CHECK-DAG: [[ARRAYINITRES]] = apply [[ARRAYINIT:%[0-9]+]]<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>([[ARRAYSIZE:%[0-9]+]])
// CHECK-DAG: [[ARRAYINIT]] = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF
@@ -305,6 +310,7 @@ func testMessageWithTooManyArguments() {
// CHECK-DAG: [[FOREACH:%[0-9]+]] = function_ref @$sSTsE7forEachyyy7ElementQzKXEKF
// CHECK-DAG: try_apply [[FOREACH]]<Array<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>>({{%.*}}, [[SB:%[0-9]+]])
// CHECK-DAG: [[SB]] = store_borrow [[FINARR:%[0-9]+]] to [[ARGSARRAYADDR:%[0-9]+]]
// CHECK-DAG: [[FINARR]] = move_value [var_decl] [[FINARR:%[0-9]+]]
// CHECK-DAG: [[FINARRFUNC:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
// CHECK-DAG: [[FINARR]] = apply [[FINARRFUNC]]<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>([[ARGSARRAY:%[0-9]+]])
// CHECK-DAG: ([[ARGSARRAY]], {{%.*}}) = destructure_tuple [[ARRAYINITRES:%[0-9]+]]
@@ -387,6 +393,7 @@ func testDynamicStringArguments() {
// CHECK-DAG: [[FOREACH:%[0-9]+]] = function_ref @$sSTsE7forEachyyy7ElementQzKXEKF
// CHECK-DAG: try_apply [[FOREACH]]<Array<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>>({{%.*}}, [[SB:%[0-9]+]])
// CHECK-DAG: [[SB]] = store_borrow [[FINARR:%[0-9]+]] to [[ARGSARRAYADDR:%[0-9]+]]
// CHECK-DAG: [[FINARR]] = move_value [var_decl] [[FINARR:%[0-9]+]]
// CHECK-DAG: [[FINARRFUNC:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
// CHECK-DAG: [[FINARR]] = apply [[FINARRFUNC]]<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>([[ARGSARRAY:%[0-9]+]])
// CHECK-DAG: ([[ARGSARRAY]], {{%.*}}) = destructure_tuple [[ARRAYINITRES:%[0-9]+]]
@@ -437,6 +444,7 @@ func testNSObjectInterpolation() {
// CHECK-DAG: [[FOREACH:%[0-9]+]] = function_ref @$sSTsE7forEachyyy7ElementQzKXEKF
// CHECK-DAG: try_apply [[FOREACH]]<Array<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>>({{%.*}}, [[SB:%[0-9]+]])
// CHECK-DAG: [[SB]] = store_borrow [[FINARR:%[0-9]+]] to [[ARGSARRAYADDR:%[0-9]+]]
// CHECK-DAG: [[FINARR]] = move_value [var_decl] [[FINARR:%[0-9]+]]
// CHECK-DAG: [[FINARRFUNC:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
// CHECK-DAG: [[FINARR]] = apply {{.*}}<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>([[ARGSARRAY:%[0-9]+]])
// CHECK-DAG: ([[ARGSARRAY]], {{%.*}}) = destructure_tuple [[ARRAYINITRES:%[0-9]+]]
@@ -482,6 +490,7 @@ func testDoubleInterpolation() {
// CHECK-DAG: [[FOREACH:%[0-9]+]] = function_ref @$sSTsE7forEachyyy7ElementQzKXEKF
// CHECK-DAG: try_apply [[FOREACH]]<Array<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>>({{%.*}}, [[SB:%[0-9]+]])
// CHECK-DAG: [[SB]] = store_borrow [[FINARR:%[0-9]+]] to [[ARGSARRAYADDR:%[0-9]+]]
// CHECK-DAG: [[FINARR]] = move_value [var_decl] [[FINARR:%[0-9]+]]
// CHECK-DAG: [[FINARRFUNC:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
// CHECK-DAG: [[FINARR]] = apply [[FINARRFUNC]]<(inout UnsafeMutablePointer<UInt8>, inout Optional<UnsafeMutablePointer<NSObject>>, inout Optional<UnsafeMutablePointer<Any>>) -> ()>([[ARGSARRAY:%[0-9]+]])
// CHECK-DAG: ([[ARGSARRAY]], {{%.*}}) = destructure_tuple [[ARRAYINITRES:%[0-9]+]]

View File

@@ -19,11 +19,11 @@
// CHECK: [[REGISTER_11:%[^,]+]] = load [trivial] [[BOX_COPY_ADDR]] : $*Int, loc {{.*}}:33:11, scope 4
// CHECK: destroy_value [[BOX_COPY]] : ${ var Int }, loc {{.*}}:33:11, scope 4
// CHECK: [[CLOSURE:%[^,]+]] = partial_apply [callee_guaranteed] [[SPECIALIZED_F]]([[REGISTER_11]]) : $@convention(thin) (Int) -> Int, loc {{.*}}:33:11, scope 4
// CHECK: [[BORROW:%.*]] = begin_borrow [lexical] [var_decl] [[CLOSURE]]
// CHECK: debug_value [[BORROW]] : $@callee_guaranteed () -> Int, let, name "f", loc {{.*}}:33:7, scope 6
// CHECK: [[CLOSURE_COPY:%[^,]+]] = copy_value [[BORROW]] : $@callee_guaranteed () -> Int, loc {{.*}}:34:10, scope 6
// CHECK: [[MOVE:%.*]] = move_value [lexical] [var_decl] [[CLOSURE]]
// CHECK: debug_value [[MOVE]] : $@callee_guaranteed () -> Int, let, name "f", loc {{.*}}:33:7, scope 6
// CHECK: [[CLOSURE_COPY:%[^,]+]] = copy_value [[MOVE]] : $@callee_guaranteed () -> Int, loc {{.*}}:34:10, scope 6
// There used to be an end_borrow here. We leave an emptyline here to preserve line numbers.
// CHECK: destroy_value [[CLOSURE]] : $@callee_guaranteed () -> Int, loc {{.*}}:35:1, scope 6
// CHECK: destroy_value [[MOVE]] : $@callee_guaranteed () -> Int, loc {{.*}}:35:1, scope 6
// CHECK: destroy_value [[BOX]] : ${ var Int }, loc {{.*}}:35:1, scope 6
// CHECK: return [[CLOSURE_COPY]] : $@callee_guaranteed () -> Int, loc {{.*}}:34:3, scope 6
// CHECK: }

View File

@@ -1,5 +1,5 @@
// RUN: %target-swift-frontend -emit-sil -O -parse-as-library -enable-copy-propagation=false -Xllvm -sil-print-all -module-name=main %s 2>&1 | %FileCheck %s
// RUN: %target-swift-frontend -emit-sil -O -parse-as-library -enable-lexical-lifetimes=false -Xllvm -sil-print-all -module-name=main %s 2>&1 | %FileCheck %s
// RUN: %target-swift-frontend -emit-sil -O -parse-as-library -enable-copy-propagation=false -Xllvm -sil-print-all -module-name=main %s 2>&1 | %FileCheck %s --check-prefixes CHECK,CHECK-NOCOPYPROP
// RUN: %target-swift-frontend -emit-sil -O -parse-as-library -enable-lexical-lifetimes=false -Xllvm -sil-print-all -module-name=main %s 2>&1 | %FileCheck %s --check-prefixes CHECK,CHECK-COPYPROP
// REQUIRES: swift_in_compiler
@@ -14,10 +14,12 @@ func getOwned() -> AnyObject
// CHECK-LABEL: // testLexical()
// CHECK: [[A:%.*]] = apply %{{.*}}()
// CHECK: [[B:%.*]] = begin_borrow [lexical] [var_decl] [[A]]
// CHECK: apply %{{.*}}([[B]])
// CHECK: [[B:%.*]] = move_value [lexical] [var_decl] [[A]]
// CHECK: [[BB:%.*]] = begin_borrow [[B]]
// CHECK: apply %{{.*}}([[BB]])
// CHECK: end_borrow [[BB]]
// CHECK: apply
// CHECK: end_borrow [[B]]
// CHECK: destroy_value [[B]]
// CHECK-LABEL: } // end sil function
// LexicalLifetimeEliminator must strip the [lexical] flag
@@ -28,16 +30,17 @@ func getOwned() -> AnyObject
// CHECK-LABEL: *** SIL function after {{.*}} (sil-lexical-lifetime-eliminator)
// CHECK-LABEL: // testLexical()
// CHECK: [[A:%.*]] = apply %{{.*}}()
// CHECK: [[B:%.*]] = begin_borrow [var_decl] [[A]]
// CHECK: [[B:%.*]] = move_value [var_decl] [[A]]
// CHECK: apply %{{.*}}([[B]])
// CHECK: apply
// CHECK: end_borrow [[B]]
// CHECK: destroy_value [[B]]
// CHECK-LABEL: } // end sil function
// The first round of SemanticARCOpts must eliminate the borrow scope
// that was only needed for a lexical lifetime.
// The first round of SemanticARCOpts/CopyPropagation must eliminate the
// redundant move_value that was only needed for a lexical lifetime.
// CHECK-LABEL: *** SIL function after {{.*}} (onone-simplification)
// CHECK-NOCOPYPROP-LABEL: *** SIL function after {{.*}} (semantic-arc-opts)
// CHECK-COPYPROP-LABEL: *** SIL function after {{.*}} (copy-propagation)
// CHECK-LABEL: // testLexical()
// CHECK: [[A:%.*]] = apply %{{.*}}()
// CHECK: apply %{{.*}}([[A]])

View File

@@ -23,7 +23,7 @@ public func eliminate_copy_of_returned_then_consumed_owned_value(arg: __owned An
// CHECK: [[ARG_COPY:%[^,]+]] = copy_value [[ARG]]
let x = consumeAndProduce(arg)
// CHECK: [[X:%[^,]+]] = apply {{%[^,]+}}([[ARG_COPY]])
// CHECK: [[MOVE_X:%[^,]+]] = move_value [lexical] [[X]]
// CHECK: [[MOVE_X:%[^,]+]] = move_value [lexical] [var_decl] [[X]]
// no copy of 'x'
_ = consumeAndProduce(x)
// CHECK: [[RESULT:%[^,]+]] = apply {{%[^,]+}}([[MOVE_X]])