Skip to content

Commit 4e51846

Browse files
authored
Merge pull request #71641 from rjmccall/emit-enum-args-into-context
Emit enum element arguments directly into the enum payload
2 parents 716732f + 2d71c60 commit 4e51846

File tree

10 files changed

+324
-127
lines changed

10 files changed

+324
-127
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 199 additions & 68 deletions
Large diffs are not rendered by default.

lib/SILGen/SILGenConstructor.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -898,12 +898,21 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {
898898
LoweredParamsInContextGenerator loweredParams(*this);
899899

900900
// Emit the exploded constructor argument.
901-
ArgumentSource payload;
901+
SmallVector<ArgumentSource, 2> payloads;
902902
if (element->hasAssociatedValues()) {
903-
auto eltArgTy = element->getArgumentInterfaceType()->getCanonicalType();
904-
RValue arg = emitImplicitValueConstructorArg(*this, Loc, eltArgTy, element,
905-
loweredParams);
906-
payload = ArgumentSource(Loc, std::move(arg));
903+
auto elementFnTy =
904+
cast<AnyFunctionType>(
905+
cast<AnyFunctionType>(element->getInterfaceType()->getCanonicalType())
906+
.getResult());
907+
auto elementParams = elementFnTy.getParams();
908+
payloads.reserve(elementParams.size());
909+
910+
for (auto param: elementParams) {
911+
auto paramType = param.getParameterType();
912+
RValue arg = emitImplicitValueConstructorArg(*this, Loc, paramType,
913+
element, loweredParams);
914+
payloads.emplace_back(Loc, std::move(arg));
915+
}
907916
}
908917

909918
// Emit the metatype argument.
@@ -913,7 +922,7 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {
913922

914923
// If possible, emit the enum directly into the indirect return.
915924
SGFContext C = (dest ? SGFContext(dest.get()) : SGFContext());
916-
ManagedValue mv = emitInjectEnum(Loc, std::move(payload),
925+
ManagedValue mv = emitInjectEnum(Loc, payloads,
917926
enumTI.getLoweredType(),
918927
element, C);
919928

lib/SILGen/SILGenConvert.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,34 @@ ManagedValue SILGenFunction::manageOpaqueValue(ManagedValue value,
10261026
return value.copyUnmanaged(*this, loc);
10271027
}
10281028

1029+
ManagedValue SILGenFunction::emitAsOrig(SILLocation loc,
1030+
AbstractionPattern origType,
1031+
CanType substType,
1032+
SILType expectedTy,
1033+
SGFContext C,
1034+
ValueProducerRef produceValue) {
1035+
// If the lowered substituted type already matches the substitution,
1036+
// we can just emit directly.
1037+
if (getLoweredType(substType).getASTType() == expectedTy.getASTType()) {
1038+
auto result = produceValue(*this, loc, C);
1039+
1040+
// For convenience, force the result into the destination.
1041+
if (auto init = C.getEmitInto(); init && !result.isInContext()) {
1042+
result.forwardInto(*this, loc, init);
1043+
return ManagedValue::forInContext();
1044+
}
1045+
return result;
1046+
}
1047+
1048+
auto conversion =
1049+
Conversion::getSubstToOrig(origType, substType, expectedTy);
1050+
auto result = emitConvertedRValue(loc, conversion, C, produceValue);
1051+
1052+
// emitConvertedRValue always forces results into the context.
1053+
assert((C.getEmitInto() != nullptr) == result.isInContext());
1054+
return result;
1055+
}
1056+
10291057
ManagedValue SILGenFunction::emitConvertedRValue(Expr *E,
10301058
const Conversion &conversion,
10311059
SGFContext C) {

lib/SILGen/SILGenFunction.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1300,7 +1300,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
13001300
//===--------------------------------------------------------------------===//
13011301

13021302
ManagedValue emitInjectEnum(SILLocation loc,
1303-
ArgumentSource &&payload,
1303+
MutableArrayRef<ArgumentSource> payload,
13041304
SILType enumTy,
13051305
EnumElementDecl *element,
13061306
SGFContext C);
@@ -1562,6 +1562,22 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
15621562
SGFContext C,
15631563
ValueProducerRef produceValue);
15641564

1565+
/// Call the produceValue function and convert the result to the given
1566+
/// original abstraction pattern.
1567+
///
1568+
/// The SGFContext provided to the produceValue function includes the
1569+
/// conversion, if it's non-trivial, and thus permits it to be peepholed
1570+
/// and combined with other conversions. This can result in substantially
1571+
/// more efficient code than just emitting the value and reabstracting
1572+
/// it afterwards.
1573+
///
1574+
/// If the provided SGFContext includes an initialization, the result
1575+
/// will always be ManagedValue::forInContext().
1576+
ManagedValue emitAsOrig(SILLocation loc, AbstractionPattern origType,
1577+
CanType substType, SILType expectedTy,
1578+
SGFContext C,
1579+
ValueProducerRef produceValue);
1580+
15651581
/// Emit the given expression as an r-value that follows the
15661582
/// abstraction patterns of the original type.
15671583
ManagedValue emitRValueAsOrig(Expr *E, AbstractionPattern origPattern,

test/IRGen/enum_resilience.swift

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -135,22 +135,11 @@ public func constructResilientEnumPayload(_ s: Size) -> Medium {
135135
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr [[METADATA]], [[INT]] -1
136136
// CHECK-NEXT: [[VWT:%.*]] = load ptr, ptr [[VWT_ADDR]]
137137

138-
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds %swift.vwtable, ptr [[VWT]], i32 0, i32 8
139-
// CHECK-NEXT: [[WITNESS_FOR_SIZE:%size]] = load [[INT]], ptr [[WITNESS_ADDR]]
140-
// CHECK-NEXT: [[ALLOCA:%.*]] = alloca i8, {{.*}} [[WITNESS_FOR_SIZE]], align 16
141-
// CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i32|i64)}} -1, ptr [[ALLOCA]])
142-
143138
// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds ptr, ptr [[VWT]], i32 2
144139
// CHECK-NEXT: [[WITNESS:%.*]] = load ptr, ptr [[WITNESS_ADDR]]
145140
// CHECK-arm64e-NEXT: ptrtoint ptr [[WITNESS_ADDR]] to i64
146141
// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend
147-
// CHECK-NEXT: call ptr [[WITNESS]](ptr noalias [[ALLOCA]], ptr noalias %1, ptr [[METADATA]])
148-
149-
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds ptr, ptr [[VWT]], i32 4
150-
// CHECK-NEXT: [[WITNESS:%.*]] = load ptr, ptr [[WITNESS_ADDR]]
151-
// CHECK-arm64e-NEXT: ptrtoint ptr [[WITNESS_ADDR]] to i64
152-
// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend
153-
// CHECK-NEXT: call ptr [[WITNESS]](ptr noalias %0, ptr noalias [[ALLOCA]], ptr [[METADATA]])
142+
// CHECK-NEXT: call ptr [[WITNESS]](ptr noalias %0, ptr noalias %1, ptr [[METADATA]])
154143

155144
// CHECK-NEXT: [[TAG:%.*]] = load i32, ptr @"$s14resilient_enum6MediumO8PostcardyAC0A7_struct4SizeVcACmFWC"
156145
// CHECK-NEXT: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s14resilient_enum6MediumOMa"([[INT]] 0)
@@ -165,7 +154,6 @@ public func constructResilientEnumPayload(_ s: Size) -> Medium {
165154
// CHECK-arm64e-NEXT: ptrtoint ptr [[WITNESS_ADDR]] to i64
166155
// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend
167156
// CHECK-NEXT: call void [[WITNESS_FN]](ptr noalias %0, i32 [[TAG]], ptr [[METADATA2]])
168-
// CHECK-NEXT: call void @llvm.lifetime.end.p0({{(i32|i64)}} -1, ptr [[ALLOCA]])
169157

170158
// CHECK-NEXT: ret void
171159

test/SILGen/enum.swift

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,13 @@ func AddressOnly_cases(_ s: S) {
6363
_ = AddressOnly.nought
6464

6565
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin AddressOnly.Type
66-
// CHECK-NEXT: [[P_BUF:%.*]] = alloc_stack $any P
67-
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = init_existential_addr [[P_BUF]]
68-
// CHECK-NEXT: store %0 to [trivial] [[PAYLOAD_ADDR]]
6966
// CHECK-NEXT: [[MERE:%.*]] = alloc_stack $AddressOnly
7067
// CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[MERE]]
71-
// CHECK-NEXT: copy_addr [take] [[P_BUF]] to [init] [[PAYLOAD]] : $*any P
68+
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = init_existential_addr [[PAYLOAD]]
69+
// CHECK-NEXT: store %0 to [trivial] [[PAYLOAD_ADDR]]
7270
// CHECK-NEXT: inject_enum_addr [[MERE]]
7371
// CHECK-NEXT: destroy_addr [[MERE]]
7472
// CHECK-NEXT: dealloc_stack [[MERE]]
75-
// CHECK-NEXT: dealloc_stack [[P_BUF]] : $*any P
7673
_ = AddressOnly.mere(s)
7774

7875
// Address-only enum vs loadable payload
@@ -105,15 +102,12 @@ func PolyOptionable_cases<T>(_ t: T) {
105102
_ = PolyOptionable<T>.nought
106103

107104
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin PolyOptionable<T>.Type
108-
// CHECK-NEXT: [[T_BUF:%.*]] = alloc_stack $T
109-
// CHECK-NEXT: copy_addr %0 to [init] [[T_BUF]]
110105
// CHECK-NEXT: [[MERE:%.*]] = alloc_stack $PolyOptionable<T>
111106
// CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[MERE]]
112-
// CHECK-NEXT: copy_addr [take] [[T_BUF]] to [init] [[PAYLOAD]] : $*T
107+
// CHECK-NEXT: copy_addr %0 to [init] [[PAYLOAD]] : $*T
113108
// CHECK-NEXT: inject_enum_addr [[MERE]]
114109
// CHECK-NEXT: destroy_addr [[MERE]]
115110
// CHECK-NEXT: dealloc_stack [[MERE]]
116-
// CHECK-NEXT: dealloc_stack [[T_BUF]] : $*T
117111
_ = PolyOptionable<T>.mere(t)
118112

119113
// CHECK-NOT: destroy_addr %0
@@ -265,3 +259,27 @@ enum rdar81817725 {
265259
}
266260
}
267261
}
262+
263+
enum Indirected {
264+
case a
265+
case b
266+
indirect case c(Int)
267+
}
268+
func throwingFunction() throws -> Int { return 0 }
269+
270+
// CHECK-LABEL: sil hidden [ossa] @$s4enum29throwInIndirectConstructorArgAA10IndirectedOyKF
271+
// CHECK: [[BOX:%.*]] = alloc_box ${ var Int }
272+
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = project_box [[BOX]]
273+
// CHECK-NEXT: // function_ref
274+
// CHECK-NEXT: [[FN:%.*]] = function_ref
275+
// CHECK-NEXT: try_apply [[FN]]()
276+
// CHECK: bb1([[RESULT:%.*]] : $Int):
277+
// CHECK-NEXT: store [[RESULT]] to [trivial] [[PAYLOAD_ADDR]]
278+
// CHECK-NEXT: [[ENUM:%.*]] = enum $Indirected, #Indirected.c!enumelt, [[BOX]]
279+
// CHECK-NEXT: return [[ENUM]] : $Indirected
280+
// CHECK: bb2([[ERROR:%.*]] : @owned $any Error):
281+
// CHECK-NEXT: dealloc_box [[BOX]]
282+
// CHECK-NEXT: throw [[ERROR]]
283+
func throwInIndirectConstructorArg() throws -> Indirected {
284+
return .c(try throwingFunction())
285+
}

test/SILGen/generic_closures.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ class NestedGeneric<U> {
132132
// CHECK-LABEL: sil hidden [ossa] @$s16generic_closures13NestedGenericC20nested_reabstraction{{[_0-9a-zA-Z]*}}F
133133
// CHECK: [[REABSTRACT:%.*]] = function_ref @$sIeg_ytIegr_TR
134134
// CHECK: partial_apply [callee_guaranteed] [[REABSTRACT]]
135-
func nested_reabstraction<T>(_ x: T) -> Optionable<() -> ()> {
136-
return .some({})
135+
func nested_reabstraction<T>(_ x: T, fn: @escaping () -> ()) -> Optionable<() -> ()> {
136+
return .some(fn)
137137
}
138138
}
139139

test/SILGen/indirect_enum.swift

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,21 @@ func TreeA_cases<T>(_ t: T, l: TreeA<T>, r: TreeA<T>) {
1616
let _ = TreeA<T>.Nil
1717

1818
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin TreeA<T>.Type
19-
// CHECK-NEXT: [[T_BUF:%.*]] = alloc_stack $T
20-
// CHECK-NEXT: copy_addr [[ARG1]] to [init] [[T_BUF]] : $*T
2119
// CHECK-NEXT: [[BOX:%.*]] = alloc_box $<τ_0_0> { var τ_0_0 } <T>
2220
// CHECK-NEXT: [[PB:%.*]] = project_box [[BOX]]
23-
// CHECK-NEXT: copy_addr [take] [[T_BUF]] to [init] [[PB]]
21+
// CHECK-NEXT: copy_addr [[ARG1]] to [init] [[PB]]
2422
// CHECK-NEXT: [[LEAF:%.*]] = enum $TreeA<T>, #TreeA.Leaf!enumelt, [[BOX]]
2523
// CHECK-NEXT: destroy_value [[LEAF]]
26-
// CHECK-NEXT: dealloc_stack [[T_BUF]] : $*T
2724
let _ = TreeA<T>.Leaf(t)
2825

2926
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin TreeA<T>.Type
30-
// CHECK-NEXT: [[ARG2_COPY:%.*]] = copy_value [[ARG2]]
31-
// CHECK-NEXT: [[ARG3_COPY:%.*]] = copy_value [[ARG3]]
3227
// CHECK-NEXT: [[BOX:%.*]] = alloc_box $<τ_0_0> { var (left: TreeA<τ_0_0>, right: TreeA<τ_0_0>) } <T>
3328
// CHECK-NEXT: [[PB:%.*]] = project_box [[BOX]]
3429
// CHECK-NEXT: [[LEFT:%.*]] = tuple_element_addr [[PB]] : $*(left: TreeA<T>, right: TreeA<T>), 0
3530
// CHECK-NEXT: [[RIGHT:%.*]] = tuple_element_addr [[PB]] : $*(left: TreeA<T>, right: TreeA<T>), 1
31+
// CHECK-NEXT: [[ARG2_COPY:%.*]] = copy_value [[ARG2]]
3632
// CHECK-NEXT: store [[ARG2_COPY]] to [init] [[LEFT]]
33+
// CHECK-NEXT: [[ARG3_COPY:%.*]] = copy_value [[ARG3]]
3734
// CHECK-NEXT: store [[ARG3_COPY]] to [init] [[RIGHT]]
3835
// CHECK-NEXT: [[BRANCH:%.*]] = enum $TreeA<T>, #TreeA.Branch!enumelt, [[BOX]]
3936
// CHECK-NEXT: destroy_value [[BRANCH]]
@@ -46,9 +43,9 @@ func TreeA_cases<T>(_ t: T, l: TreeA<T>, r: TreeA<T>) {
4643
func TreeA_reabstract(_ f: @escaping (Int) -> Int) {
4744
// CHECK: bb0([[ARG:%.*]] : @guaranteed $@callee_guaranteed (Int) -> Int):
4845
// CHECK: [[METATYPE:%.*]] = metatype $@thin TreeA<(Int) -> Int>.Type
49-
// CHECK-NEXT: [[ARG_COPY:%.*]] = copy_value [[ARG]]
5046
// CHECK-NEXT: [[BOX:%.*]] = alloc_box $<τ_0_0> { var τ_0_0 } <(Int) -> Int>
5147
// CHECK-NEXT: [[PB:%.*]] = project_box [[BOX]]
48+
// CHECK-NEXT: [[ARG_COPY:%.*]] = copy_value [[ARG]]
5249
// CHECK: [[THUNK:%.*]] = function_ref @$sS2iIegyd_S2iIegnr_TR
5350
// CHECK-NEXT: [[FN:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[ARG_COPY]])
5451
// CHECK-NEXT: [[FNC:%.*]] = convert_function [[FN]]
@@ -77,36 +74,27 @@ func TreeB_cases<T>(_ t: T, l: TreeB<T>, r: TreeB<T>) {
7774
let _ = TreeB<T>.Nil
7875

7976
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin TreeB<T>.Type
80-
// CHECK-NEXT: [[T_BUF:%.*]] = alloc_stack $T
81-
// CHECK-NEXT: copy_addr %0 to [init] [[T_BUF]]
8277
// CHECK-NEXT: [[LEAF:%.*]] = alloc_stack $TreeB<T>
8378
// CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[LEAF]] : $*TreeB<T>, #TreeB.Leaf!enumelt
84-
// CHECK-NEXT: copy_addr [take] [[T_BUF]] to [init] [[PAYLOAD]]
79+
// CHECK-NEXT: copy_addr %0 to [init] [[PAYLOAD]]
8580
// CHECK-NEXT: inject_enum_addr [[LEAF]] : $*TreeB<T>, #TreeB.Leaf!enumelt
8681
// CHECK-NEXT: destroy_addr [[LEAF]]
8782
// CHECK-NEXT: dealloc_stack [[LEAF]]
88-
// CHECK-NEXT: dealloc_stack [[T_BUF]]
8983
let _ = TreeB<T>.Leaf(t)
9084

9185
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin TreeB<T>.Type
92-
// CHECK-NEXT: [[ARG1_COPY:%.*]] = alloc_stack $TreeB<T>
93-
// CHECK-NEXT: copy_addr %1 to [init] [[ARG1_COPY]] : $*TreeB<T>
94-
// CHECK-NEXT: [[ARG2_COPY:%.*]] = alloc_stack $TreeB<T>
95-
// CHECK-NEXT: copy_addr %2 to [init] [[ARG2_COPY]] : $*TreeB<T>
9686
// CHECK-NEXT: [[BOX:%.*]] = alloc_box $<τ_0_0> { var (left: TreeB<τ_0_0>, right: TreeB<τ_0_0>) } <T>
9787
// CHECK-NEXT: [[PB:%.*]] = project_box [[BOX]]
9888
// CHECK-NEXT: [[LEFT:%.*]] = tuple_element_addr [[PB]]
9989
// CHECK-NEXT: [[RIGHT:%.*]] = tuple_element_addr [[PB]]
100-
// CHECK-NEXT: copy_addr [take] [[ARG1_COPY]] to [init] [[LEFT]] : $*TreeB<T>
101-
// CHECK-NEXT: copy_addr [take] [[ARG2_COPY]] to [init] [[RIGHT]] : $*TreeB<T>
90+
// CHECK-NEXT: copy_addr %1 to [init] [[LEFT]] : $*TreeB<T>
91+
// CHECK-NEXT: copy_addr %2 to [init] [[RIGHT]] : $*TreeB<T>
10292
// CHECK-NEXT: [[BRANCH:%.*]] = alloc_stack $TreeB<T>
10393
// CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[BRANCH]]
10494
// CHECK-NEXT: store [[BOX]] to [init] [[PAYLOAD]]
10595
// CHECK-NEXT: inject_enum_addr [[BRANCH]] : $*TreeB<T>, #TreeB.Branch!enumelt
10696
// CHECK-NEXT: destroy_addr [[BRANCH]]
10797
// CHECK-NEXT: dealloc_stack [[BRANCH]]
108-
// CHECK-NEXT: dealloc_stack [[ARG2_COPY]]
109-
// CHECK-NEXT: dealloc_stack [[ARG1_COPY]]
11098
let _ = TreeB<T>.Branch(left: l, right: r)
11199

112100
// CHECK: return
@@ -126,13 +114,13 @@ func TreeInt_cases(_ t: Int, l: TreeInt, r: TreeInt) {
126114
let _ = TreeInt.Leaf(t)
127115

128116
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin TreeInt.Type
129-
// CHECK-NEXT: [[ARG2_COPY:%.*]] = copy_value [[ARG2]] : $TreeInt
130-
// CHECK-NEXT: [[ARG3_COPY:%.*]] = copy_value [[ARG3]] : $TreeInt
131117
// CHECK-NEXT: [[BOX:%.*]] = alloc_box ${ var (left: TreeInt, right: TreeInt) }
132118
// CHECK-NEXT: [[PB:%.*]] = project_box [[BOX]]
133119
// CHECK-NEXT: [[LEFT:%.*]] = tuple_element_addr [[PB]]
134120
// CHECK-NEXT: [[RIGHT:%.*]] = tuple_element_addr [[PB]]
121+
// CHECK-NEXT: [[ARG2_COPY:%.*]] = copy_value [[ARG2]] : $TreeInt
135122
// CHECK-NEXT: store [[ARG2_COPY]] to [init] [[LEFT]]
123+
// CHECK-NEXT: [[ARG3_COPY:%.*]] = copy_value [[ARG3]] : $TreeInt
136124
// CHECK-NEXT: store [[ARG3_COPY]] to [init] [[RIGHT]]
137125
// CHECK-NEXT: [[BRANCH:%.*]] = enum $TreeInt, #TreeInt.Branch!enumelt, [[BOX]]
138126
// CHECK-NEXT: destroy_value [[BRANCH]]

test/SILGen/variadic-generic-tuples.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,27 @@ func test() {
399399
let tuple = identityOnVariadicTuples((1, 2, 3))
400400
takesVariadicTuple(tuple: tuple)
401401
}
402+
403+
func createTuple<each T>(including: repeat Stored<each T>, from: Int) -> (repeat each T) {
404+
fatalError()
405+
}
406+
407+
// rdar://121489308
408+
func testTupleExpansionInEnumConstructor<each T>(
409+
from: repeat Stored<each T>,
410+
to: @escaping (Result<(repeat each T), Error>) -> ()
411+
) {
412+
_ = {
413+
let tuple = createTuple(including: repeat each from,
414+
from: 42)
415+
to(.success(tuple))
416+
}
417+
}
418+
// CHECK-LABEL: sil {{.*}}@$s4main35testTupleExpansionInEnumConstructor4from2toyAA6StoredVyxGxQp_ys6ResultOyxxQp_ts5Error_pGctRvzlFyycfU_ :
419+
// CHECK: [[VAR:%.*]] = alloc_stack [lexical] $(repeat each T), let, name "tuple"
420+
// (a few moments later)
421+
// CHECK: metatype $@thin Result<(repeat each T), any Error>.Type
422+
// CHECK: [[RESULT_TEMP:%.*]] = alloc_stack $Result<(repeat each T), any Error>
423+
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = init_enum_data_addr [[RESULT_TEMP]] : $*Result<(repeat each T), any Error>, #Result.success
424+
// CHECK-NEXT: copy_addr [[VAR]] to [init] [[PAYLOAD_ADDR]] : $*(repeat each T)
425+
// CHECK-NEXT: inject_enum_addr [[RESULT_TEMP]] : $*Result<(repeat each T), any Error>, #Result.success

test/SILOptimizer/access_marker_verify.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -334,14 +334,9 @@ func testInitGenericEnum<T>(t: T) -> GenericEnum<T>? {
334334
// CHECK: alloc_box $<τ_0_0> { var GenericEnum<τ_0_0> } <T>, var, name "self"
335335
// CHECK: mark_uninitialized [delegatingself] %3 : $<τ_0_0> { var GenericEnum<τ_0_0> } <T>
336336
// CHECK: [[PROJ:%.*]] = project_box
337-
// CHECK: [[ADR1:%.*]] = alloc_stack $T
338-
// CHECK-NOT: begin_access
339-
// CHECK: copy_addr %1 to [init] [[ADR1]] : $*T
340337
// CHECK: [[STK:%.*]] = alloc_stack $GenericEnum<T>
341338
// CHECK: [[ENUMDATAADDR:%.*]] = init_enum_data_addr [[STK]]
342-
// CHECK: [[ACCESSENUM:%.*]] = begin_access [modify] [unsafe] [[ENUMDATAADDR]] : $*T
343-
// CHECK: copy_addr [take] [[ADR1]] to [init] [[ACCESSENUM]] : $*T
344-
// CHECK: end_access [[ACCESSENUM]] : $*T
339+
// CHECK: copy_addr %1 to [init] [[ENUMDATAADDR]] : $*T
345340
// CHECK: inject_enum_addr
346341
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [unknown] [[PROJ]]
347342
// CHECK: copy_addr [take] %{{.*}} to [[ACCESS]] : $*GenericEnum<T>
@@ -362,9 +357,9 @@ func testIndirectEnum() -> IndirectEnum {
362357
}
363358
// CHECK-LABEL: sil hidden [ossa] @$s20access_marker_verify16testIndirectEnumAA0eF0OyF : $@convention(thin) () -> @owned IndirectEnum {
364359
// CHECK: bb0:
365-
// CHECK: apply
366360
// CHECK: alloc_box ${ var Int }
367361
// CHECK: [[PROJ:%.*]] = project_box
362+
// CHECK: apply
368363
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [unsafe] [[PROJ]]
369364
// CHECK: store %{{.*}} to [trivial] [[ACCESS]] : $*Int
370365
// CHECK: end_access

0 commit comments

Comments
 (0)