Skip to content

Commit c7593fb

Browse files
committed
SILCombine: fix an assert in the optimization which promotes a concrete type of an existential
rdar://problem/45915705
1 parent e7dd1c1 commit c7593fb

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,9 +747,13 @@ static bool canReplaceCopiedArg(FullApplySite Apply,
747747
if (!DT->properlyDominates(AI, user))
748748
return false;
749749
} else {
750+
// The caller has to guarantee that there are no other instructions which
751+
// use the address. This is done in findInitExistential called from
752+
// the constructor of ConcreteExistentialInfo.
750753
assert(isa<CopyAddrInst>(user) || isa<InitExistentialAddrInst>(user) ||
751754
isa<OpenExistentialAddrInst>(user) ||
752755
isa<DeallocStackInst>(user) ||
756+
isa<ApplyInst>(user) || isa<TryApplyInst>(user) ||
753757
user->isDebugInstruction() && "Unexpected instruction");
754758
}
755759
}

test/SILOptimizer/sil_combine_concrete_existential.sil

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,3 +409,31 @@ bb0:
409409
%v = tuple ()
410410
return %v : $()
411411
}
412+
413+
sil @takeany : $@convention(thin) (@in_guaranteed AnyP) -> ()
414+
415+
// CHECK-LABEL: sil @testWitnessCopiedSelfWithIndirectResult2 : $@convention(thin) () -> () {
416+
// CHECK: [[IN:%[0-9]+]] = alloc_stack $AnyP
417+
// CHECK: [[EA:%[0-9]+]] = init_existential_addr [[IN]]
418+
// CHECK: [[OUT:%[0-9]+]] = alloc_stack $StructOfAnyP
419+
// 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
420+
// CHECK: apply %{{.*}}<StructOfAnyP>([[OUT]], [[EA]]) : $@convention(witness_method: AnyP) <τ_0_0 where τ_0_0 : AnyP> (@in_guaranteed τ_0_0) -> @out StructOfAnyP
421+
// CHECK-LABEL: } // end sil function 'testWitnessCopiedSelfWithIndirectResult2'
422+
sil @testWitnessCopiedSelfWithIndirectResult2 : $() -> () {
423+
bb0:
424+
%a0 = alloc_stack $AnyP
425+
%ie0 = init_existential_addr %a0 : $*AnyP, $StructOfAnyP
426+
%f1 = function_ref @takeany : $@convention(thin) (@in_guaranteed AnyP) -> ()
427+
%c1 = apply %f1(%a0) : $@convention(thin) (@in_guaranteed AnyP) -> ()
428+
%a1 = alloc_stack $AnyP
429+
copy_addr %a0 to [initialization] %a1 : $*AnyP
430+
%o0 = open_existential_addr immutable_access %a1 : $*AnyP to $*@opened("7C4DAF8E-D722-11E8-920A-D0817AD9F6DD") AnyP
431+
%a2 = alloc_stack $StructOfAnyP
432+
%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
433+
%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
434+
dealloc_stack %a2 : $*StructOfAnyP
435+
dealloc_stack %a1 : $*AnyP
436+
dealloc_stack %a0 : $*AnyP
437+
%v = tuple ()
438+
return %v : $()
439+
}

0 commit comments

Comments
 (0)