Skip to content

Commit 13498c4

Browse files
committed
Fix exclusivity accesss enforcement for partial_apply [stack]
1 parent 8bcc66f commit 13498c4

File tree

4 files changed

+29
-34
lines changed

4 files changed

+29
-34
lines changed

lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ static bool hasExpectedUsesOfNoEscapePartialApply(Operand *partialApplyUse) {
137137
case SILInstructionKind::ApplyInst:
138138
case SILInstructionKind::TryApplyInst:
139139
return true;
140+
// partial_apply [stack] is terminated by a dealloc_stack.
141+
case SILInstructionKind::DeallocStackInst:
142+
return true;
140143

141144
case SILInstructionKind::ConvertFunctionInst:
142145
return llvm::all_of(cast<ConvertFunctionInst>(user)->getUses(),

lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@ void SelectEnforcement::updateCapture(AddressCapture capture) {
508508
case SILInstructionKind::RetainValueInst:
509509
case SILInstructionKind::ReleaseValueInst:
510510
case SILInstructionKind::EndBorrowInst:
511+
// partial_apply [stack] is matched with dealloc_stack.
512+
case SILInstructionKind::DeallocStackInst:
511513
// Benign use.
512514
return;
513515
case SILInstructionKind::TupleExtractInst:

lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -956,8 +956,10 @@ template <typename FollowUse>
956956
static void checkNoEscapePartialApplyUse(Operand *oper, FollowUse followUses) {
957957
SILInstruction *user = oper->getUser();
958958

959-
// Ignore uses that are totally uninteresting.
960-
if (isIncidentalUse(user) || onlyAffectsRefCount(user))
959+
// Ignore uses that are totally uninteresting. partial_apply [stack] is
960+
// terminated by a dealloc_stack instruction.
961+
if (isIncidentalUse(user) || onlyAffectsRefCount(user) ||
962+
isa<DeallocStackInst>(user))
961963
return;
962964

963965
// Before checking conversions in general below (getSingleValueCopyOrCast),

test/SILOptimizer/access_enforcement_noescape.swift

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,10 @@ func inoutReadRead(x: inout Int) {
8585
doTwo({ _ = x }, { _ = x })
8686
}
8787
// CHECK-LABEL: sil hidden @$s27access_enforcement_noescape09inoutReadE01xySiz_tF : $@convention(thin) (@inout Int) -> () {
88-
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
89-
// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
90-
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
91-
// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
88+
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed] [on_stack]
89+
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
9290
// CHECK-NOT: begin_access
93-
// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
91+
// CHECK: apply %{{.*}}([[PA1]], [[PA2]])
9492
// CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape09inoutReadE01xySiz_tF'
9593

9694
// closure #1 in inoutReadRead(x:)
@@ -119,10 +117,9 @@ func readBoxRead() {
119117
// CHECK-LABEL: sil hidden @$s27access_enforcement_noescape11readBoxReadyyF : $@convention(thin) () -> () {
120118
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
121119
// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
122-
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
123-
// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
120+
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
124121
// CHECK-NOT: begin_access
125-
// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
122+
// CHECK: apply %{{.*}}([[CVT1]], [[PA2]])
126123
// CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape11readBoxReadyyF'
127124

128125
// closure #1 in readBoxRead()
@@ -153,12 +150,10 @@ func readWrite() {
153150
doTwo({ _ = x }, { x = 42 })
154151
}
155152
// CHECK-LABEL: sil hidden @$s27access_enforcement_noescape9readWriteyyF : $@convention(thin) () -> () {
156-
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
157-
// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
158-
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
159-
// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
153+
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed] [on_stack]
154+
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
160155
// CHECK-NOT: begin_access
161-
// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
156+
// CHECK: apply %{{.*}}([[PA1]], [[PA2]])
162157
// CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape9readWriteyyF'
163158

164159
// closure #1 in readWrite()
@@ -195,10 +190,9 @@ func readBoxWrite() {
195190
// CHECK-LABEL: sil hidden @$s27access_enforcement_noescape12readBoxWriteyyF : $@convention(thin) () -> () {
196191
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
197192
// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
198-
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
199-
// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
193+
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
200194
// CHECK-NOT: begin_access
201-
// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
195+
// CHECK: apply %{{.*}}([[CVT1]], [[PA2]])
202196
// CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape12readBoxWriteyyF'
203197

204198
// closure #1 in readBoxWrite()
@@ -230,11 +224,10 @@ func readWriteBox() {
230224

231225
// CHECK-LABEL: sil hidden @$s27access_enforcement_noescape12readWriteBoxyyF : $@convention(thin) () -> () {
232226
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
233-
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
234-
// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
227+
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
235228
// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
236229
// CHECK-NOT: begin_access
237-
// CHECK: apply %{{.*}}([[CVT2]], [[CVT1]])
230+
// CHECK: apply %{{.*}}([[PA2]], [[CVT1]])
238231
// CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape12readWriteBoxyyF'
239232

240233
// closure #1 in readWriteBox()
@@ -319,12 +312,10 @@ func writeWrite() {
319312
}
320313

321314
// CHECK-LABEL: sil hidden @$s27access_enforcement_noescape10writeWriteyyF : $@convention(thin) () -> () {
322-
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
323-
// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
324-
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
325-
// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
315+
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed] [on_stack]
316+
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
326317
// CHECK-NOT: begin_access
327-
// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
318+
// CHECK: apply %{{.*}}([[PA1]], [[PA2]])
328319
// CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape10writeWriteyyF'
329320

330321
// closure #1 in writeWrite()
@@ -348,12 +339,10 @@ func inoutWriteWrite(x: inout Int) {
348339
}
349340

350341
// CHECK-LABEL: sil hidden @$s27access_enforcement_noescape010inoutWriteE01xySiz_tF : $@convention(thin) (@inout Int) -> () {
351-
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
352-
// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
353-
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
354-
// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
342+
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed] [on_stack]
343+
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
355344
// CHECK-NOT: begin_access
356-
// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
345+
// CHECK: apply %{{.*}}([[PA1]], [[PA2]])
357346
// CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape010inoutWriteE01xySiz_tF'
358347

359348
// closure #1 in inoutWriteWrite(x:)
@@ -381,11 +370,10 @@ func writeWriteBox() {
381370

382371
// CHECK-LABEL: sil hidden @$s27access_enforcement_noescape13writeWriteBoxyyF : $@convention(thin) () -> () {
383372
// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
384-
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
385-
// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
373+
// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
386374
// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
387375
// CHECK-NOT: begin_access
388-
// CHECK: apply %{{.*}}([[CVT2]], [[CVT1]])
376+
// CHECK: apply %{{.*}}([[PA2]], [[CVT1]])
389377
// CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape13writeWriteBoxyyF'
390378

391379
// closure #1 in writeWriteBox()

0 commit comments

Comments
 (0)