Skip to content

Commit f7a8e04

Browse files
committed
Load pack elements in memberwise initializers if they're loadable
SILGen expects this of values before we enter general routines. Fixes rdar://109911655
1 parent c9a36a0 commit f7a8e04

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

lib/SILGen/SILGenConstructor.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ static RValue emitImplicitValueConstructorArg(SILGenFunction &SGF,
222222
auto eltAddr =
223223
SGF.B.createPackElementGet(loc, packIndex, arg, eltTy);
224224
ManagedValue eltMV = emitManagedParameter(SGF, eltAddr, argIsConsumed);
225+
eltMV = SGF.B.createLoadIfLoadable(loc, eltMV);
225226
eltInit->copyOrInitValueInto(SGF, loc, eltMV, argIsConsumed);
226227
eltInit->finishInitialization(SGF);
227228
});
@@ -232,21 +233,18 @@ static RValue emitImplicitValueConstructorArg(SILGenFunction &SGF,
232233

233234
ManagedValue mvArg = emitManagedParameter(SGF, arg, argIsConsumed);
234235

236+
// This can happen if the value is resilient in the calling convention
237+
// but not resilient locally.
238+
if (argType.isAddress()) {
239+
mvArg = SGF.B.createLoadIfLoadable(loc, mvArg);
240+
}
241+
235242
if (argInit) {
236243
argInit->copyOrInitValueInto(SGF, loc, mvArg, argIsConsumed);
237244
argInit->finishInitialization(SGF);
238245
return RValue::forInContext();
239246
}
240247

241-
// This can happen if the value is resilient in the calling convention
242-
// but not resilient locally.
243-
if (argType.isLoadable(SGF.F) && argType.isAddress()) {
244-
if (mvArg.isPlusOne(SGF))
245-
mvArg = SGF.B.createLoadTake(loc, mvArg);
246-
else
247-
mvArg = SGF.B.createLoadBorrow(loc, mvArg);
248-
}
249-
250248
return RValue(SGF, loc, type, mvArg);
251249
}
252250

test/SILGen/variadic-generic-tuples.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,3 +331,24 @@ func testFancyTuple_pack<each T>(values: repeat each T) {
331331

332332
// rdar://107664237
333333
func f<each T>() -> (repeat Array<each T>) {}
334+
335+
// rdar://109911655
336+
struct GenericButLoadable<X, Y> { }
337+
struct StructOfLoadableTuple<each S> {
338+
let elements: (repeat GenericButLoadable<each S, each S>)
339+
}
340+
// Force the emission of the memberwise initializer.
341+
func testStructOfLoadableTuple() -> StructOfLoadableTuple<Int> {
342+
StructOfLoadableTuple(elements: (GenericButLoadable<Int, Int>()))
343+
}
344+
345+
// The memberwise initializer.
346+
// CHECK-LABEL: sil {{.*}}@$s4main21StructOfLoadableTupleV8elementsACyxxQp_QPGAA010GenericButD0VyxxGxQp_t_tcfC :
347+
// CHECK: bb0(%0 : $*StructOfLoadableTuple<repeat each S>, %1 : $*Pack{repeat GenericButLoadable<each S, each S>}, %2 : $@thin StructOfLoadableTuple<repeat each S>.Type):
348+
// CHECK-NEXT: [[TUPLE:%.*]] = alloc_stack $(repeat GenericButLoadable<each S, each S>)
349+
// CHECK: [[INDEX:%.*]] = dynamic_pack_index {{.*}} of $Pack{repeat GenericButLoadable<each S, each S>}
350+
// CHECK-NEXT: open_pack_element [[INDEX]] of <each S> at <Pack{repeat each S}>, shape $each S, uuid [[UUID:".*"]]
351+
// CHECK-NEXT: [[TUPLE_ELT_ADDR:%.*]] = tuple_pack_element_addr [[INDEX]] of [[TUPLE]] : $*(repeat GenericButLoadable<each S, each S>) as $*GenericButLoadable<@pack_element([[UUID]]) each S, @pack_element([[UUID]]) each S>
352+
// CHECK-NEXT: [[PACK_ELT_ADDR:%.*]] = pack_element_get [[INDEX]] of %1 : $*Pack{repeat GenericButLoadable<each S, each S>} as $*GenericButLoadable<@pack_element([[UUID]]) each S, @pack_element([[UUID]]) each S>
353+
// CHECK-NEXT: [[PACK_ELT:%.*]] = load [trivial] [[PACK_ELT_ADDR]] :
354+
// CHECK-NEXT: store [[PACK_ELT]] to [trivial] [[TUPLE_ELT_ADDR]] :

0 commit comments

Comments
 (0)