Skip to content

Commit 53bffd2

Browse files
committed
[MoveOnlyAddressChecker] Handle takes of copyable.
Treat a take of a copyable value as a take.
1 parent 4f6f8d9 commit 53bffd2

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2222,16 +2222,27 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
22222222
// Before we do anything, see if this load is of a copyable field or is a
22232223
// trivial load. If it is, then we just treat this as a liveness requiring
22242224
// use.
2225-
if (li->getOwnershipQualifier() == LoadOwnershipQualifier::Trivial ||
2226-
isCopyableValue(li)) {
2225+
auto qualifier = li->getOwnershipQualifier();
2226+
if (qualifier == LoadOwnershipQualifier::Trivial || isCopyableValue(li)) {
22272227
SmallVector<TypeTreeLeafTypeRange, 2> leafRanges;
22282228
TypeTreeLeafTypeRange::get(op, getRootAddress(), leafRanges);
22292229
if (!leafRanges.size()) {
22302230
LLVM_DEBUG(llvm::dbgs() << "Failed to form leaf type range!\n");
22312231
return false;
22322232
}
22332233
for (auto leafRange : leafRanges) {
2234-
useState.recordLivenessUse(user, leafRange);
2234+
switch (qualifier) {
2235+
case LoadOwnershipQualifier::Unqualified:
2236+
llvm_unreachable("unqualified load in ossa!?");
2237+
case LoadOwnershipQualifier::Take:
2238+
useState.recordTakeUse(user, leafRange);
2239+
break;
2240+
case LoadOwnershipQualifier::Copy:
2241+
LLVM_FALLTHROUGH;
2242+
case LoadOwnershipQualifier::Trivial:
2243+
useState.recordLivenessUse(user, leafRange);
2244+
break;
2245+
}
22352246
}
22362247
return true;
22372248
}

test/SILOptimizer/moveonly_addresschecker_unmaximized.sil

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// RUN: -move-only-address-checker-disable-lifetime-extension=true \
99
// RUN: | %FileCheck %s
1010

11+
import Builtin
12+
1113
@_moveOnly
1214
struct M {
1315
deinit {}
@@ -180,3 +182,25 @@ entry(%m4_addr : $*M4):
180182
%retval = tuple ()
181183
return %retval : $()
182184
}
185+
186+
struct S : ~Copyable {
187+
var o: Builtin.NativeObject
188+
}
189+
190+
// CHECK-LABEL: sil [ossa] @load_take_copyable : {{.*}} {
191+
// CHECK: bb0([[S:%[^,]+]] :
192+
// CHECK: [[O_ADDR:%[^,]+]] = struct_element_addr [[S]] : $*S, #S.o
193+
// CHECK: [[O:%[^,]+]] = load [take] [[O_ADDR]]
194+
// CHECK: [[OM:%[^,]+]] = move_value [[O]]
195+
// CHECK: destroy_value [[OM]]
196+
// CHECK-LABEL: } // end sil function 'load_take_copyable'
197+
sil [ossa] @load_take_copyable : $@convention(thin) (@in S) -> () {
198+
bb0(%s_addr : $*S):
199+
%s = mark_unresolved_non_copyable_value [consumable_and_assignable] %s_addr : $*S
200+
%o_addr = struct_element_addr %s : $*S, #S.o
201+
%o = load [take] %o_addr : $*Builtin.NativeObject
202+
%om = move_value %o : $Builtin.NativeObject
203+
destroy_value %om : $Builtin.NativeObject
204+
%retval = tuple ()
205+
return %retval : $()
206+
}

0 commit comments

Comments
 (0)