Skip to content

Commit 991eb45

Browse files
Merge pull request #82557 from nate-chandler/rdar154407327
[DestroyAddrHoisting] Don't fold into read access.
2 parents a298c75 + 2e2dee7 commit 991eb45

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

lib/SILOptimizer/Transforms/DestroyAddrHoisting.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,11 @@ bool HoistDestroys::checkFoldingBarrier(
741741
auto loadee = load->getOperand();
742742
auto relativeAccessStorage = RelativeAccessStorageWithBase::compute(loadee);
743743
if (relativeAccessStorage.getStorage().hasIdenticalStorage(storage)) {
744+
// Only fold into access scopes which aren't [read].
745+
auto scoped = AccessStorageWithBase::computeInScope(loadee);
746+
auto *bai = dyn_cast_or_null<BeginAccessInst>(scoped.base);
747+
if (bai && bai->getAccessKind() == SILAccessKind::Read)
748+
return true;
744749
// If the access path from the loaded address to its root storage involves
745750
// a (layout non-equivalent) typecast--a load [take] of the casted address
746751
// would not be equivalent to a load [copy] followed by a destroy_addr of
@@ -760,6 +765,11 @@ bool HoistDestroys::checkFoldingBarrier(
760765
auto source = copy->getSrc();
761766
auto relativeAccessStorage = RelativeAccessStorageWithBase::compute(source);
762767
if (relativeAccessStorage.getStorage().hasIdenticalStorage(storage)) {
768+
// Only fold into access scopes which aren't [read].
769+
auto scoped = AccessStorageWithBase::computeInScope(source);
770+
auto *bai = dyn_cast_or_null<BeginAccessInst>(scoped.base);
771+
if (bai && bai->getAccessKind() == SILAccessKind::Read)
772+
return true;
763773
// If the access path from the copy_addr'd address to its root storage
764774
// involves a (layout non-equivalent) typecast--a copy_addr [take] of the
765775
// casted address would not be equivalent to a copy_addr followed by a

test/SILOptimizer/hoist_destroy_addr.sil

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ entry(%instance : @owned $S):
684684
%store_scope = begin_access [modify] [static] %addr : $*S
685685
store %instance to [init] %store_scope : $*S
686686
end_access %store_scope : $*S
687-
%load_scope = begin_access [read] [static] %addr : $*S
687+
%load_scope = begin_access [modify] [static] %addr : $*S
688688
%value = load [copy] %load_scope : $*S
689689
end_access %load_scope : $*S
690690
destroy_addr %addr : $*S
@@ -703,7 +703,7 @@ entry(%instance : @owned $S):
703703
%store_scope = begin_access [modify] [static] %addr : $*S
704704
store %instance to [init] %store_scope : $*S
705705
end_access %store_scope : $*S
706-
%load_scope = begin_access [read] [static] %addr : $*S
706+
%load_scope = begin_access [modify] [static] %addr : $*S
707707
%value = load [copy] %load_scope : $*S
708708
%unknown = function_ref @unknown : $@convention(thin) () -> ()
709709
apply %unknown() : $@convention(thin) () -> ()
@@ -725,7 +725,7 @@ entry(%instance : @owned $S):
725725
%store_scope = begin_access [modify] [static] %addr : $*S
726726
store %instance to [init] %store_scope : $*S
727727
end_access %store_scope : $*S
728-
%load_scope = begin_access [read] [static] %addr : $*S
728+
%load_scope = begin_access [modify] [static] %addr : $*S
729729
%value = load [copy] %load_scope : $*S
730730
%unknown = function_ref @unknown : $@convention(thin) () -> ()
731731
apply %unknown() : $@convention(thin) () -> ()
@@ -746,7 +746,7 @@ entry(%instance : @owned $S):
746746
%store_scope = begin_access [modify] [static] %addr : $*S
747747
store %instance to [init] %store_scope : $*S
748748
end_access %store_scope : $*S
749-
%load_scope = begin_access [read] [static] %addr : $*S
749+
%load_scope = begin_access [modify] [static] %addr : $*S
750750
%field_addr = struct_element_addr %load_scope : $*S, #S.x
751751
%field = load [copy] %field_addr : $*X
752752
end_access %load_scope : $*S
@@ -768,9 +768,9 @@ entry(%instance : @owned $S):
768768
%store_scope = begin_access [modify] [static] %addr : $*S
769769
store %instance to [init] %store_scope : $*S
770770
end_access %store_scope : $*S
771-
%outer = begin_access [read] [static] %addr : $*S
771+
%outer = begin_access [modify] [static] %addr : $*S
772772
apply undef(%outer) : $@convention(thin) (@inout S) -> ()
773-
%inner = begin_access [read] [static] %outer : $*S
773+
%inner = begin_access [modify] [static] %outer : $*S
774774
%field_addr = struct_element_addr %inner : $*S, #S.x
775775
%field_addr_2 = struct_element_addr %addr_2 : $*S, #S.x
776776
copy_addr %field_addr to [init] %field_addr_2 : $*X
@@ -795,9 +795,9 @@ entry(%instance : @owned $S):
795795
%store_scope = begin_access [modify] [static] %addr : $*S
796796
store %instance to [init] %store_scope : $*S
797797
end_access %store_scope : $*S
798-
%outer = begin_access [read] [static] %addr : $*S
798+
%outer = begin_access [modify] [static] %addr : $*S
799799
apply undef(%outer) : $@convention(thin) (@inout S) -> ()
800-
%inner = begin_access [read] [static] %outer : $*S
800+
%inner = begin_access [modify] [static] %outer : $*S
801801
copy_addr %inner to [init] %addr_2 : $*S
802802
end_access %inner : $*S
803803
destroy_addr %outer : $*S
@@ -1316,3 +1316,33 @@ bb0(%out : $*TwoCases):
13161316
inject_enum_addr %out, #TwoCases.A!enumelt
13171317
return %retval
13181318
}
1319+
1320+
// CHECK-LABEL: sil [ossa] @nofold_read_access_load : {{.*}} {
1321+
// CHECK: load [copy]
1322+
// CHECK-LABEL: } // end sil function 'nofold_read_access_load'
1323+
sil [ossa] @nofold_read_access_load : $@convention(thin) (@in X) -> () {
1324+
entry(%c_addr : $*X):
1325+
%c_access = begin_access [dynamic] [read] %c_addr
1326+
%c = load [copy] %c_access
1327+
end_access %c_access
1328+
destroy_addr %c_addr
1329+
apply undef(%c) : $@convention(thin) (@owned X) -> ()
1330+
%retval = tuple ()
1331+
return %retval
1332+
}
1333+
1334+
// CHECK-LABEL: sil [ossa] @nofold_read_access_copy_addr : {{.*}} {
1335+
// CHECK: copy_addr {{%[^,]+}} to [init]
1336+
// CHECK-LABEL: } // end sil function 'nofold_read_access_copy_addr'
1337+
sil [ossa] @nofold_read_access_copy_addr : $@convention(thin) (@in X) -> () {
1338+
entry(%c_addr : $*X):
1339+
%stack = alloc_stack $X
1340+
%c_access = begin_access [dynamic] [read] %c_addr
1341+
copy_addr %c_access to [init] %stack
1342+
end_access %c_access
1343+
destroy_addr %c_addr
1344+
apply undef(%stack) : $@convention(thin) (@in X) -> ()
1345+
dealloc_stack %stack
1346+
%retval = tuple ()
1347+
return %retval
1348+
}

0 commit comments

Comments
 (0)