Skip to content

Commit 0683b3f

Browse files
authored
Disable NRVO for alloc_stack [dynamic_lifetime] (#39972)
NRVO for alloc_stack [lifetime] will invalidate OSSA invariants
1 parent af7bee8 commit 0683b3f

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

lib/SILOptimizer/Transforms/CopyForwarding.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1471,7 +1471,8 @@ static bool canNRVO(CopyAddrInst *CopyInst) {
14711471
if (!CopyInst->isTakeOfSrc())
14721472
return false;
14731473

1474-
if (!isa<AllocStackInst>(CopyInst->getSrc()))
1474+
auto *asi = dyn_cast<AllocStackInst>(CopyInst->getSrc());
1475+
if (!asi || asi->hasDynamicLifetime())
14751476
return false;
14761477

14771478
// The copy's dest must be an indirect SIL argument. Otherwise, it may not

test/SILOptimizer/copyforward_ossa.sil

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ import Builtin
77
import Swift
88

99
class AClass {}
10+
11+
struct NonTrivialStruct {
12+
var cls : AClass
13+
}
14+
15+
sil @get_nontrivialstruct : $@convention(thin) () -> @out NonTrivialStruct
16+
sil @use_aclass : $@convention(thin) (@in_guaranteed AClass) -> ()
17+
1018
sil @f_in : $@convention(thin) <T> (@in T) -> ()
1119
sil @f_in_guaranteed : $@convention(thin) <T> (@in_guaranteed T) -> ()
1220
sil @f_out : $@convention(thin) <T> () -> @out T
@@ -847,3 +855,59 @@ bb0(%0 : $*Float, %1 : $Float):
847855
%15 = tuple ()
848856
return %15 : $()
849857
}
858+
859+
// CHECK-LABEL: sil [ossa] @test_dynamic_lifetime :
860+
// CHECK: [[STK:%.*]] = alloc_stack [dynamic_lifetime] $NonTrivialStruct
861+
// CHECK: copy_addr [take] {{.*}} to [initialization] [[STK]] : $*NonTrivialStruct
862+
// CHECK-LABEL: } // end sil function 'test_dynamic_lifetime'
863+
sil [ossa] @test_dynamic_lifetime : $@convention(thin) () -> @out NonTrivialStruct {
864+
bb0(%0 : $*NonTrivialStruct):
865+
%1 = alloc_stack $Builtin.Int1
866+
%2 = alloc_stack [dynamic_lifetime] $NonTrivialStruct
867+
%3 = integer_literal $Builtin.Int1, 0
868+
store %3 to [trivial] %1 : $*Builtin.Int1
869+
br bb1
870+
871+
bb1:
872+
%6 = load [trivial] %1 : $*Builtin.Int1
873+
cond_br %6, bb2, bb3
874+
875+
bb2:
876+
destroy_addr %2 : $*NonTrivialStruct
877+
br bb4
878+
879+
bb3:
880+
br bb4
881+
882+
bb4:
883+
%11 = integer_literal $Builtin.Int1, -1
884+
store %11 to [trivial] %1 : $*Builtin.Int1
885+
%13 = alloc_stack $NonTrivialStruct
886+
%14 = function_ref @get_nontrivialstruct : $@convention(thin) () -> @out NonTrivialStruct
887+
%15 = apply %14(%13) : $@convention(thin) () -> @out NonTrivialStruct
888+
copy_addr [take] %13 to [initialization] %2 : $*NonTrivialStruct
889+
dealloc_stack %13 : $*NonTrivialStruct
890+
%18 = struct_element_addr %2 : $*NonTrivialStruct, #NonTrivialStruct.cls
891+
%19 = function_ref @use_aclass : $@convention(thin) (@in_guaranteed AClass) -> ()
892+
apply %19(%18) : $@convention(thin) (@in_guaranteed AClass) -> ()
893+
cond_br undef, bb5, bb9
894+
895+
bb5:
896+
br bb10
897+
898+
bb9:
899+
br bb10
900+
901+
bb10:
902+
cond_br undef, bb11, bb12
903+
904+
bb11:
905+
br bb1
906+
907+
bb12:
908+
copy_addr [take] %2 to [initialization] %0 : $*NonTrivialStruct
909+
dealloc_stack %2 : $*NonTrivialStruct
910+
%33 = tuple ()
911+
dealloc_stack %1 : $*Builtin.Int1
912+
return %33 : $()
913+
}

0 commit comments

Comments
 (0)