Skip to content

Commit fb76ce2

Browse files
committed
TempRValueOptPass: fix a miscompile with open_existential_addr
The uses of open_existential_addr were not handled correctly. rdar://problem/56130674
1 parent 8743564 commit fb76ce2

File tree

2 files changed

+110
-2
lines changed

2 files changed

+110
-2
lines changed

lib/SILOptimizer/Transforms/CopyForwarding.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,7 +1694,7 @@ bool TempRValueOptPass::collectLoads(
16941694
"its source" << *user);
16951695
return false;
16961696
}
1697-
return true;
1697+
LLVM_FALLTHROUGH;
16981698
}
16991699
case SILInstructionKind::StructElementAddrInst:
17001700
case SILInstructionKind::TupleElementAddrInst: {
@@ -1713,7 +1713,8 @@ bool TempRValueOptPass::collectLoads(
17131713
}
17141714

17151715
case SILInstructionKind::LoadInst:
1716-
case SILInstructionKind::LoadBorrowInst: {
1716+
case SILInstructionKind::LoadBorrowInst:
1717+
case SILInstructionKind::WitnessMethodInst: {
17171718
// Loads are the end of the data flow chain. The users of the load can't
17181719
// access the temporary storage.
17191720
loadInsts.insert(user);

test/SILOptimizer/temp_rvalue_opt.sil

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,3 +471,110 @@ bb0(%0 : $*Klass):
471471
return %12 : $()
472472
}
473473

474+
protocol P {
475+
func foo()
476+
}
477+
478+
sil @getP : $@convention(thin) () -> @out Optional<P>
479+
480+
// CHECK-LABEL: sil @handle_open_existential_addr : $@convention(thin) () -> () {
481+
// CHECK: [[P:%.*]] = unchecked_take_enum_data_addr
482+
// CHECK-NOT: copy_addr
483+
// CHECK: open_existential_addr immutable_access [[P]]
484+
// CHECK: }
485+
sil @handle_open_existential_addr : $@convention(thin) () -> () {
486+
bb0:
487+
%2 = alloc_stack $Optional<P>
488+
%3 = function_ref @getP : $@convention(thin) () -> @out Optional<P>
489+
%4 = apply %3(%2) : $@convention(thin) () -> @out Optional<P>
490+
cond_br undef, bb1, bb3
491+
492+
bb1:
493+
%9 = unchecked_take_enum_data_addr %2 : $*Optional<P>, #Optional.some!enumelt.1
494+
%10 = alloc_stack $P
495+
copy_addr %9 to [initialization] %10 : $*P
496+
%13 = open_existential_addr immutable_access %10 : $*P to $*@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P
497+
%14 = witness_method $@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P, #P.foo!1 : <Self where Self : P> (Self) -> () -> (), %13 : $*@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
498+
%15 = apply %14<@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P>(%13) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
499+
destroy_addr %2 : $*Optional<P>
500+
destroy_addr %10 : $*P
501+
dealloc_stack %10 : $*P
502+
dealloc_stack %2 : $*Optional<P>
503+
br bb2
504+
505+
bb2:
506+
%23 = tuple ()
507+
return %23 : $()
508+
509+
bb3:
510+
destroy_addr %2 : $*Optional<P>
511+
dealloc_stack %2 : $*Optional<P>
512+
br bb2
513+
}
514+
// CHECK-LABEL: sil @open_existential_addr_blocks_optimization : $@convention(thin) () -> () {
515+
// CHECK: [[P:%.*]] = alloc_stack $P
516+
// CHECK: copy_addr {{.*}} to [initialization] [[P]]
517+
// CHECK: }
518+
sil @open_existential_addr_blocks_optimization : $@convention(thin) () -> () {
519+
bb0:
520+
%2 = alloc_stack $Optional<P>
521+
%3 = function_ref @getP : $@convention(thin) () -> @out Optional<P>
522+
%4 = apply %3(%2) : $@convention(thin) () -> @out Optional<P>
523+
cond_br undef, bb1, bb3
524+
525+
bb1:
526+
%9 = unchecked_take_enum_data_addr %2 : $*Optional<P>, #Optional.some!enumelt.1
527+
%10 = alloc_stack $P
528+
copy_addr %9 to [initialization] %10 : $*P
529+
destroy_addr %2 : $*Optional<P>
530+
%13 = open_existential_addr immutable_access %10 : $*P to $*@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P
531+
%14 = witness_method $@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P, #P.foo!1 : <Self where Self : P> (Self) -> () -> (), %13 : $*@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
532+
%15 = apply %14<@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P>(%13) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
533+
destroy_addr %10 : $*P
534+
dealloc_stack %10 : $*P
535+
dealloc_stack %2 : $*Optional<P>
536+
br bb2
537+
538+
bb2:
539+
%23 = tuple ()
540+
return %23 : $()
541+
542+
bb3:
543+
destroy_addr %2 : $*Optional<P>
544+
dealloc_stack %2 : $*Optional<P>
545+
br bb2
546+
}
547+
548+
// CHECK-LABEL: sil @witness_method_blocks_optimization : $@convention(thin) () -> () {
549+
// CHECK: [[P:%.*]] = alloc_stack $P
550+
// CHECK: copy_addr {{.*}} to [initialization] [[P]]
551+
// CHECK: }
552+
sil @witness_method_blocks_optimization : $@convention(thin) () -> () {
553+
bb0:
554+
%2 = alloc_stack $Optional<P>
555+
%3 = function_ref @getP : $@convention(thin) () -> @out Optional<P>
556+
%4 = apply %3(%2) : $@convention(thin) () -> @out Optional<P>
557+
cond_br undef, bb1, bb3
558+
559+
bb1:
560+
%9 = unchecked_take_enum_data_addr %2 : $*Optional<P>, #Optional.some!enumelt.1
561+
%10 = alloc_stack $P
562+
copy_addr %9 to [initialization] %10 : $*P
563+
%13 = open_existential_addr immutable_access %10 : $*P to $*@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P
564+
destroy_addr %2 : $*Optional<P>
565+
%14 = witness_method $@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P, #P.foo!1 : <Self where Self : P> (Self) -> () -> (), %13 : $*@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
566+
%15 = apply %14<@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637") P>(%13) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
567+
destroy_addr %10 : $*P
568+
dealloc_stack %10 : $*P
569+
dealloc_stack %2 : $*Optional<P>
570+
br bb2
571+
572+
bb2:
573+
%23 = tuple ()
574+
return %23 : $()
575+
576+
bb3:
577+
destroy_addr %2 : $*Optional<P>
578+
dealloc_stack %2 : $*Optional<P>
579+
br bb2
580+
}

0 commit comments

Comments
 (0)