Skip to content

Commit 6440e16

Browse files
committed
[move-only] Move object checking before PredMemOpts.
Otherwise in certain cases due to load promotion, we emit incorrect errors. As an example: let x = ... var y = x print(y) would show an error that x is consumed twice... which is incorrect.
1 parent 93a78b4 commit 6440e16

File tree

3 files changed

+38
-29
lines changed

3 files changed

+38
-29
lines changed

lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2841,6 +2841,11 @@ static AllocationInst *getOptimizableAllocation(SILInstruction *i) {
28412841
if (getMemoryType(alloc).aggregateHasUnreferenceableStorage())
28422842
return nullptr;
28432843

2844+
// Do not perform this on move only values since we introduce copies to
2845+
// promote things.
2846+
if (getMemoryType(alloc).isMoveOnly())
2847+
return nullptr;
2848+
28442849
// Otherwise we are good to go. Lets try to optimize this memory!
28452850
return alloc;
28462851
}

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ static void addMandatoryDiagnosticOptPipeline(SILPassPipelinePlan &P) {
163163
P.addMoveFunctionCanonicalization();
164164
P.addMoveKillsCopyableAddressesChecker();
165165

166+
// Now perform move object checking. We again do this before predictable
167+
// memory access opts to ensure that we do not get any non-source related
168+
// diagnostics due to value promotion.
169+
P.addMoveOnlyObjectChecker(); // Check noImplicitCopy and move only
170+
// types.
171+
166172
// Promote loads as necessary to ensure we have enough SSA formation to emit
167173
// SSA based diagnostics.
168174
P.addPredictableMemoryAccessOptimizations();
@@ -171,8 +177,6 @@ static void addMandatoryDiagnosticOptPipeline(SILPassPipelinePlan &P) {
171177
// SSA based move function checking and no implicit copy checking.
172178
P.addMoveKillsCopyableValuesChecker(); // No uses after _move of copyable
173179
// value.
174-
P.addMoveOnlyObjectChecker(); // Check noImplicitCopy and move only
175-
// types.
176180

177181
// Now that we have run move only checking, eliminate SILMoveOnly wrapped
178182
// trivial types from the IR. We cannot introduce extra "copies" of trivial

test/SILOptimizer/moveonly_diagnostics.swift

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ public func classAssignToVar1(_ x: Klass) { // expected-error {{'x' has guarante
225225
var x3 = x2 // expected-note {{consuming use}}
226226
x3 = x2 // expected-note {{consuming use}}
227227
x3 = x // expected-note {{consuming use}}
228-
print(x3) // expected-note {{consuming use}}
228+
print(x3)
229229
}
230230

231231
// TODO: We shouldn't see a consuming use on x3.
@@ -234,7 +234,7 @@ public func classAssignToVar1Arg(_ x: Klass, _ x2: Klass) { // expected-error {{
234234
var x3 = x2 // expected-note {{consuming use}}
235235
x3 = x2 // expected-note {{consuming use}}
236236
x3 = x // expected-note {{consuming use}}
237-
print(x3) // expected-note {{consuming use}}
237+
print(x3)
238238
}
239239

240240
// NOTE: print(x3) shouldn't be marked! This is most likely due to some form of
@@ -245,7 +245,7 @@ public func classAssignToVar1OwnedArg(_ x: Klass, _ x2: __owned Klass) { // expe
245245
var x3 = x2 // expected-note {{consuming use}}
246246
x3 = x2 // expected-note {{consuming use}}
247247
x3 = x // expected-note {{consuming use}}
248-
print(x3) // expected-note {{consuming use}}
248+
print(x3)
249249
}
250250

251251
public func classAssignToVar2(_ x: Klass) { // expected-error {{'x' has guaranteed ownership but was consumed}}
@@ -273,22 +273,22 @@ public func classAssignToVar3(_ x: Klass) { // expected-error {{'x' has guarante
273273
let x2 = x // expected-note {{consuming use}}
274274
var x3 = x2
275275
x3 = x // expected-note {{consuming use}}
276-
print(x3) // expected-note {{consuming use}}
276+
print(x3)
277277
}
278278

279279
// NOTE: print(x3) is a bug.
280280
public func classAssignToVar3Arg(_ x: Klass, _ x2: Klass) { // expected-error {{'x2' has guaranteed ownership but was consumed}}
281281
// expected-error @-1 {{'x' has guaranteed ownership but was consumed}}
282282
var x3 = x2 // expected-note {{consuming use}}
283283
x3 = x // expected-note {{consuming use}}
284-
print(x3) // expected-note {{consuming use}}
284+
print(x3)
285285
}
286286

287287
// This is a bug around print(x3)
288288
public func classAssignToVar3OwnedArg(_ x: Klass, _ x2: __owned Klass) { // expected-error {{'x' has guaranteed ownership but was consumed}}
289289
var x3 = x2
290290
x3 = x // expected-note {{consuming use}}
291-
print(x3) // expected-note {{consuming use}}
291+
print(x3)
292292
}
293293

294294
public func classAssignToVar4(_ x: Klass) { // expected-error {{'x' has guaranteed ownership but was consumed}}
@@ -319,7 +319,7 @@ public func classAssignToVar5(_ x: Klass) { // expected-error {{'x' has guarant
319319
// appropriately though.
320320
classUseMoveOnlyWithoutEscaping(x2)
321321
x3 = x // expected-note {{consuming use}}
322-
print(x3) // expected-note {{consuming use}}
322+
print(x3)
323323
}
324324

325325
public func classAssignToVar5Arg(_ x: Klass, _ x2: Klass) { // expected-error {{'x2' has guaranteed ownership but was consumed}}
@@ -329,7 +329,7 @@ public func classAssignToVar5Arg(_ x: Klass, _ x2: Klass) { // expected-error {{
329329
// appropriately though.
330330
classUseMoveOnlyWithoutEscaping(x2)
331331
x3 = x // expected-note {{consuming use}}
332-
print(x3) // expected-note {{consuming use}}
332+
print(x3)
333333
}
334334

335335
public func classAssignToVar5OwnedArg(_ x: Klass, _ x2: __owned Klass) { // expected-error {{'x2' consumed more than once}}
@@ -339,7 +339,7 @@ public func classAssignToVar5OwnedArg(_ x: Klass, _ x2: __owned Klass) { // expe
339339
// appropriately though.
340340
classUseMoveOnlyWithoutEscaping(x2)
341341
x3 = x // expected-note {{consuming use}}
342-
print(x3) // expected-note {{consuming use}}
342+
print(x3)
343343
}
344344

345345
public func classAccessAccessField(_ x: Klass) { // expected-error {{'x' has guaranteed ownership but was consumed}}
@@ -576,23 +576,23 @@ public func finalClassAssignToVar1(_ x: FinalKlass) { // expected-error {{'x' ha
576576
var x3 = x2 // expected-note {{consuming use}}
577577
x3 = x2 // expected-note {{consuming use}}
578578
x3 = x // expected-note {{consuming use}}
579-
print(x3) // expected-note {{consuming use}}
579+
print(x3)
580580
}
581581

582582
public func finalClassAssignToVar1Arg(_ x: FinalKlass, _ x2: FinalKlass) { // expected-error {{'x2' has guaranteed ownership but was consumed}}
583583
// expected-error @-1 {{'x' has guaranteed ownership but was consumed}}
584584
var x3 = x2 // expected-note {{consuming use}}
585585
x3 = x2 // expected-note {{consuming use}}
586586
x3 = x // expected-note {{consuming use}}
587-
print(x3) // expected-note {{consuming use}}
587+
print(x3)
588588
}
589589

590590
public func finalClassAssignToVar1OwnedArg(_ x: FinalKlass, _ x2: __owned FinalKlass) { // expected-error {{'x2' consumed more than once}}
591591
// expected-error @-1 {{'x' has guaranteed ownership but was consumed}}
592592
var x3 = x2 // expected-note {{consuming use}}
593593
x3 = x2 // expected-note {{consuming use}}
594594
x3 = x // expected-note {{consuming use}}
595-
print(x3) // expected-note {{consuming use}}
595+
print(x3)
596596
}
597597

598598
public func finalClassAssignToVar2(_ x: FinalKlass) { // expected-error {{'x' has guaranteed ownership but was consumed}}
@@ -619,20 +619,20 @@ public func finalClassAssignToVar3(_ x: FinalKlass) { // expected-error {{'x' ha
619619
let x2 = x // expected-note {{consuming use}}
620620
var x3 = x2
621621
x3 = x // expected-note {{consuming use}}
622-
print(x3) // expected-note {{consuming use}}
622+
print(x3)
623623
}
624624

625625
public func finalClassAssignToVar3Arg(_ x: FinalKlass, _ x2: FinalKlass) { // expected-error {{'x2' has guaranteed ownership but was consumed}}
626626
// expected-error @-1 {{'x' has guaranteed ownership but was consumed}}
627627
var x3 = x2 // expected-note {{consuming use}}
628628
x3 = x // expected-note {{consuming use}}
629-
print(x3) // expected-note {{consuming use}}
629+
print(x3)
630630
}
631631

632632
public func finalClassAssignToVar3OwnedArg(_ x: FinalKlass, _ x2: __owned FinalKlass) { // expected-error {{'x' has guaranteed ownership but was consumed}}
633633
var x3 = x2
634634
x3 = x // expected-note {{consuming use}}
635-
print(x3) // expected-note {{consuming use}}
635+
print(x3)
636636
}
637637

638638
public func finalClassAssignToVar4(_ x: FinalKlass) { // expected-error {{'x' has guaranteed ownership but was consumed}}
@@ -663,7 +663,7 @@ public func finalClassAssignToVar5(_ x: FinalKlass) { // expected-error {{'x' ha
663663
// appropriately though.
664664
finalClassUseMoveOnlyWithoutEscaping(x2)
665665
x3 = x // expected-note {{consuming use}}
666-
print(x3) // expected-note {{consuming use}}
666+
print(x3)
667667
}
668668

669669
public func finalClassAssignToVar5Arg(_ x: FinalKlass, _ x2: FinalKlass) { // expected-error {{'x2' has guaranteed ownership but was consumed}}
@@ -673,7 +673,7 @@ public func finalClassAssignToVar5Arg(_ x: FinalKlass, _ x2: FinalKlass) { // ex
673673
// appropriately though.
674674
finalClassUseMoveOnlyWithoutEscaping(x2)
675675
x3 = x // expected-note {{consuming use}}
676-
print(x3) // expected-note {{consuming use}}
676+
print(x3)
677677
}
678678

679679
public func finalClassAssignToVar5OwnedArg(_ x: FinalKlass, _ x2: __owned FinalKlass) { // expected-error {{'x2' consumed more than once}}
@@ -683,7 +683,7 @@ public func finalClassAssignToVar5OwnedArg(_ x: FinalKlass, _ x2: __owned FinalK
683683
// appropriately though.
684684
finalClassUseMoveOnlyWithoutEscaping(x2)
685685
x3 = x // expected-note {{consuming use}}
686-
print(x3) // expected-note {{consuming use}}
686+
print(x3)
687687
}
688688

689689
public func finalClassAccessField(_ x: FinalKlass) { // expected-error {{'x' has guaranteed ownership but was consumed}}
@@ -1734,23 +1734,23 @@ public func enumAssignToVar1(_ x: EnumTy) { // expected-error {{'x' has guarante
17341734
var x3 = x2 // expected-note {{consuming use}}
17351735
x3 = x2 // expected-note {{consuming use}}
17361736
x3 = x // expected-note {{consuming use}}
1737-
print(x3) // expected-note {{consuming use}}
1737+
print(x3)
17381738
}
17391739

17401740
public func enumAssignToVar1Arg(_ x: EnumTy, _ x2: EnumTy) { // expected-error {{'x2' has guaranteed ownership but was consumed}}
17411741
// expected-error @-1 {{'x' has guaranteed ownership but was consumed}}
17421742
var x3 = x2 // expected-note {{consuming use}}
17431743
x3 = x2 // expected-note {{consuming use}}
17441744
x3 = x // expected-note {{consuming use}}
1745-
print(x3) // expected-note {{consuming use}}
1745+
print(x3)
17461746
}
17471747

17481748
public func enumAssignToVar1OwnedArg(_ x: EnumTy, _ x2: __owned EnumTy) { // expected-error {{'x2' consumed more than once}}
17491749
// expected-error @-1 {{'x' has guaranteed ownership but was consumed}}
17501750
var x3 = x2 // expected-note {{consuming use}}
17511751
x3 = x2 // expected-note {{consuming use}}
17521752
x3 = x // expected-note {{consuming use}}
1753-
print(x3) // expected-note {{consuming use}}
1753+
print(x3)
17541754
}
17551755

17561756
public func enumAssignToVar2(_ x: EnumTy) { // expected-error {{'x' has guaranteed ownership but was consumed}}
@@ -1777,20 +1777,20 @@ public func enumAssignToVar3(_ x: EnumTy) { // expected-error {{'x' has guarante
17771777
let x2 = x // expected-note {{consuming use}}
17781778
var x3 = x2
17791779
x3 = x // expected-note {{consuming use}}
1780-
print(x3) // expected-note {{consuming use}}
1780+
print(x3)
17811781
}
17821782

17831783
public func enumAssignToVar3Arg(_ x: EnumTy, _ x2: EnumTy) { // expected-error {{'x2' has guaranteed ownership but was consumed}}
17841784
// expected-error @-1 {{'x' has guaranteed ownership but was consumed}}
17851785
var x3 = x2 // expected-note {{consuming use}}
17861786
x3 = x // expected-note {{consuming use}}
1787-
print(x3) // expected-note {{consuming use}}
1787+
print(x3)
17881788
}
17891789

17901790
public func enumAssignToVar3OwnedArg(_ x: EnumTy, _ x2: __owned EnumTy) { // expected-error {{'x' has guaranteed ownership but was consumed}}
17911791
var x3 = x2
17921792
x3 = x // expected-note {{consuming use}}
1793-
print(x3) // expected-note {{consuming use}}
1793+
print(x3)
17941794
}
17951795

17961796
public func enumAssignToVar4(_ x: EnumTy) { // expected-error {{'x' has guaranteed ownership but was consumed}}
@@ -1821,7 +1821,7 @@ public func enumAssignToVar5(_ x: EnumTy) { // expected-error {{'x' has guarante
18211821
// appropriately though.
18221822
enumUseMoveOnlyWithoutEscaping(x2)
18231823
x3 = x // expected-note {{consuming use}}
1824-
print(x3) // expected-note {{consuming use}}
1824+
print(x3)
18251825
}
18261826

18271827
public func enumAssignToVar5Arg(_ x: EnumTy, _ x2: EnumTy) { // expected-error {{'x2' has guaranteed ownership but was consumed}}
@@ -1831,7 +1831,7 @@ public func enumAssignToVar5Arg(_ x: EnumTy, _ x2: EnumTy) { // expected-error {
18311831
// appropriately though.
18321832
enumUseMoveOnlyWithoutEscaping(x2)
18331833
x3 = x // expected-note {{consuming use}}
1834-
print(x3) // expected-note {{consuming use}}
1834+
print(x3)
18351835
}
18361836

18371837
public func enumAssignToVar5OwnedArg(_ x: EnumTy, _ x2: __owned EnumTy) { // expected-error {{'x2' consumed more than once}}
@@ -1841,7 +1841,7 @@ public func enumAssignToVar5OwnedArg(_ x: EnumTy, _ x2: __owned EnumTy) { // exp
18411841
// appropriately though.
18421842
enumUseMoveOnlyWithoutEscaping(x2)
18431843
x3 = x // expected-note {{consuming use}}
1844-
print(x3) // expected-note {{consuming use}}
1844+
print(x3)
18451845
}
18461846

18471847
public func enumPatternMatchIfLet1(_ x: EnumTy) { // expected-error {{'x' has guaranteed ownership but was consumed}}

0 commit comments

Comments
 (0)