Skip to content

Commit 99253b5

Browse files
authored
Merge pull request #20010 from atrick/5.0-silcombine-fix
Fix SILCombiner::propagateConcreteTypeOfInitExistential.
2 parents 16f0227 + 8f8537d commit 99253b5

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,8 @@ static bool canReplaceCopiedArg(FullApplySite Apply,
712712
// If the witness method mutates Arg, we cannot replace Arg with
713713
// the source of a copy. Otherwise the call would modify another value than
714714
// the original argument.
715-
if (Apply.getOrigCalleeType()->getParameters()[ArgIdx].isIndirectMutating())
715+
auto origConv = Apply.getOrigCalleeConv();
716+
if (origConv.getParamInfoForSILArg(ArgIdx).isIndirectMutating())
716717
return false;
717718

718719
auto *DT = DA->get(Apply.getFunction());
@@ -838,9 +839,15 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
838839
// Create the new set of arguments to apply including their substitutions.
839840
SubstitutionMap NewCallSubs = Apply.getSubstitutionMap();
840841
SmallVector<SILValue, 8> NewArgs;
841-
unsigned NumApplyArgs = Apply.getNumArguments();
842842
bool UpdatedArgs = false;
843-
for (unsigned ArgIdx = 0; ArgIdx < NumApplyArgs; ArgIdx++) {
843+
unsigned ArgIdx = 0;
844+
// Push the indirect result arguments.
845+
for (unsigned EndIdx = Apply.getSubstCalleeConv().getSILArgIndexOfFirstParam();
846+
ArgIdx < EndIdx; ++ArgIdx) {
847+
NewArgs.push_back(Apply.getArgument(ArgIdx));
848+
}
849+
// Transform the parameter arguments.
850+
for (unsigned EndIdx = Apply.getNumArguments(); ArgIdx < EndIdx; ++ArgIdx) {
844851
auto ArgIt = CEIs.find(ArgIdx);
845852
if (ArgIt == CEIs.end()) {
846853
// Use the old argument if it does not have a valid concrete existential.

test/SILOptimizer/sil_combine_concrete_existential.sil

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,42 @@ bb0:
370370
%v = tuple ()
371371
return %v : $()
372372
}
373+
374+
//===----------------------------------------------------------------------===//
375+
// testWitnessCopiedSelfWithIndirectResult: Call to a witness method
376+
// with an existential self that can be type-propagated. Exercise
377+
// `SILCombiner::canReplaceArg` when `self` is not in argument position zero.
378+
//
379+
// rdar://45415719 Assertion failed: (Index < Length && "Invalid index!")
380+
// ===----------------------------------------------------------------------===//
381+
382+
protocol AnyP {
383+
func returnsSelf() -> Self
384+
}
385+
386+
struct StructOfAnyP : AnyP {
387+
func returnsSelf() -> StructOfAnyP
388+
}
389+
390+
// CHECK-LABEL: sil @testWitnessCopiedSelfWithIndirectResult : $@convention(thin) () -> () {
391+
// CHECK: [[IN:%[0-9]+]] = alloc_stack $StructOfAnyP
392+
// CHECK: [[OUT:%[0-9]+]] = alloc_stack $StructOfAnyP
393+
// CHECK: witness_method $StructOfAnyP, #AnyP.returnsSelf!1 : <Self where Self : AnyP> (Self) -> () -> @dynamic_self Self : $@convention(witness_method: AnyP) <τ_0_0 where τ_0_0 : AnyP> (@in_guaranteed τ_0_0) -> @out StructOfAnyP
394+
// CHECK: apply %{{.*}}<StructOfAnyP>([[OUT]], [[IN]]) : $@convention(witness_method: AnyP) <τ_0_0 where τ_0_0 : AnyP> (@in_guaranteed τ_0_0) -> @out StructOfAnyP
395+
// CHECK-LABEL: } // end sil function 'testWitnessCopiedSelfWithIndirectResult'
396+
sil @testWitnessCopiedSelfWithIndirectResult : $() -> () {
397+
bb0:
398+
%a0 = alloc_stack $AnyP
399+
%ie0 = init_existential_addr %a0 : $*AnyP, $StructOfAnyP
400+
%a1 = alloc_stack $AnyP
401+
copy_addr %a0 to [initialization] %a1 : $*AnyP
402+
%o0 = open_existential_addr immutable_access %a1 : $*AnyP to $*@opened("7C4DAF8E-D722-11E8-920A-D0817AD9F6DD") AnyP
403+
%a2 = alloc_stack $StructOfAnyP
404+
%w0 = witness_method $@opened("7C4DAF8E-D722-11E8-920A-D0817AD9F6DD") AnyP, #AnyP.returnsSelf!1 : <Self where Self : AnyP> (Self) -> () -> @dynamic_self Self, %o0 : $*@opened("7C4DAF8E-D722-11E8-920A-D0817AD9F6DD") AnyP : $@convention(witness_method: AnyP) <τ_0_0 where τ_0_0 : AnyP> (@in_guaranteed τ_0_0) -> @out StructOfAnyP
405+
%c0 = apply %w0<@opened("7C4DAF8E-D722-11E8-920A-D0817AD9F6DD") AnyP>(%a2, %o0) : $@convention(witness_method: AnyP) <τ_0_0 where τ_0_0 : AnyP> (@in_guaranteed τ_0_0) -> @out StructOfAnyP
406+
dealloc_stack %a2 : $*StructOfAnyP
407+
dealloc_stack %a1 : $*AnyP
408+
dealloc_stack %a0 : $*AnyP
409+
%v = tuple ()
410+
return %v : $()
411+
}

0 commit comments

Comments
 (0)