Skip to content

Commit 2c9f9bd

Browse files
committedFeb 15, 2021
[ownership] When lowering store_borrow, RAUW its result with its input dest.
A store_borrow is a manner to temporarily "borrow" a guaranteed value into memory for purposes like reabstraction. To make this safer in OSSA, we treat a store_borrow's result as an interior pointer into the stored guaranteed value, causing all uses of that result to be validated as being within the lifetime of the guaranteed value. NOTE: This is not the complete store_borrow verification story. We also will verify that the memory that is being store_borrowed into is not written to while the store_borrow's result is live.
1 parent b7f5aac commit 2c9f9bd

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed
 

Diff for: ‎lib/SILOptimizer/Mandatory/OwnershipModelEliminator.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,10 @@ bool OwnershipModelEliminatorVisitor::visitStoreBorrowInst(
255255
StoreOwnershipQualifier::Unqualified);
256256
});
257257

258-
// Then remove the qualified store.
258+
// Then remove the qualified store after RAUWing si with its dest. This
259+
// ensures that any uses of the interior pointer result of the store_borrow
260+
// are rewritten to be on the dest point.
261+
si->replaceAllUsesWith(si->getDest());
259262
eraseInstruction(si);
260263
return true;
261264
}

Diff for: ‎test/SILOptimizer/ownership_model_eliminator.sil

+21
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ sil_stage raw
55
import Builtin
66

77
sil @use_native_object : $@convention(thin) (@owned Builtin.NativeObject) -> ()
8+
sil @use_native_object_inguaranteed : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
89
sil @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
910

1011
enum Either<T, R> {
@@ -358,3 +359,23 @@ bb0(%0a : $PairOfInt):
358359
%0b = unchecked_value_cast %0a : $PairOfInt to $Builtin.Int64
359360
return %0b : $Builtin.Int64
360361
}
362+
363+
// Make sure we RAUW the store_borrow's result with its dest while lowering.
364+
//
365+
// CHECK-LABEL: sil @lower_store_borrow_result_correctly : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
366+
// CHECK: bb0([[ARG:%.*]] :
367+
// CHECK: [[STACK:%.*]] = alloc_stack
368+
// CHECK: store [[ARG]] to [[STACK]]
369+
// CHECK: apply {{%.*}}([[STACK]])
370+
// CHECK: } // end sil function 'lower_store_borrow_result_correctly'
371+
sil [ossa] @lower_store_borrow_result_correctly : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
372+
bb0(%0 : @guaranteed $Builtin.NativeObject):
373+
// This is materializing %0 into memory to be passed as an in_guaranteed arg.
374+
%1 = alloc_stack $Builtin.NativeObject
375+
%result = store_borrow %0 to %1 : $*Builtin.NativeObject
376+
%f = function_ref @use_native_object_inguaranteed : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
377+
apply %f(%result) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
378+
dealloc_stack %1 : $*Builtin.NativeObject
379+
%9999 = tuple()
380+
return %9999 : $()
381+
}

0 commit comments

Comments
 (0)