Skip to content

Commit 2594cd7

Browse files
committed
[semantic-arcopts] Do not try to eliminate copy_value from an unowned argument.
1 parent 1113bde commit 2594cd7

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

lib/SIL/OwnershipUtils.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,35 @@ bool swift::isOwnershipForwardingInst(SILInstruction *i) {
7979

8080
bool swift::getUnderlyingBorrowIntroducers(SILValue inputValue,
8181
SmallVectorImpl<SILValue> &out) {
82+
if (inputValue.getOwnershipKind() != ValueOwnershipKind::Guaranteed)
83+
return false;
84+
8285
SmallVector<SILValue, 32> worklist;
8386
worklist.emplace_back(inputValue);
8487

8588
while (!worklist.empty()) {
8689
SILValue v = worklist.pop_back_val();
8790

8891
// First check if v is an introducer. If so, stash it and continue.
89-
if (isa<SILFunctionArgument>(v) || isa<LoadBorrowInst>(v) ||
92+
if (isa<LoadBorrowInst>(v) ||
9093
isa<BeginBorrowInst>(v)) {
9194
out.push_back(v);
9295
continue;
9396
}
9497

98+
// If we have a function argument with guaranteed convention, it is also an
99+
// introducer.
100+
if (auto *arg = dyn_cast<SILFunctionArgument>(v)) {
101+
if (arg->getOwnershipKind() == ValueOwnershipKind::Guaranteed) {
102+
out.push_back(v);
103+
continue;
104+
}
105+
106+
// Otherwise, we do not know how to handle this function argument, so
107+
// bail.
108+
return false;
109+
}
110+
95111
// Otherwise if v is an ownership forwarding value, add its defining
96112
// instruction
97113
if (isGuaranteedForwardingValue(v)) {

test/SILOptimizer/semantic-arc-opts.sil

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,19 @@ bb0(%0 : @guaranteed $Builtin.NativeObject):
172172
%9999 = tuple()
173173
return %9999 : $()
174174
}
175+
176+
// Do not eliminate a copy from an unowned value. This will cause us to pass the
177+
// unowned value as guaranteed... =><=.
178+
//
179+
// CHECK-LABEL: sil @unowned_arg_copy : $@convention(thin) (Builtin.NativeObject) -> () {
180+
// CHECK: copy_value
181+
// CHECK: } // end sil function 'unowned_arg_copy'
182+
sil @unowned_arg_copy : $@convention(thin) (Builtin.NativeObject) -> () {
183+
bb0(%0 : @unowned $Builtin.NativeObject):
184+
%1 = copy_value %0 : $Builtin.NativeObject
185+
%2 = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
186+
apply %2(%1) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
187+
destroy_value %1 : $Builtin.NativeObject
188+
%9999 = tuple()
189+
return %9999 : $()
190+
}

0 commit comments

Comments
 (0)