From 65fd488ee6dd4e0c5c35fd9a73007541b440186b Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Mon, 9 Jan 2023 14:23:02 -0800 Subject: [PATCH 1/3] [field-pruned-liveness] Enable an assert when computing boundaries with the correct condition. --- lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp b/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp index ffdad057774d1..cca78813f8db1 100644 --- a/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp +++ b/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp @@ -781,7 +781,7 @@ void FieldSensitiveMultiDefPrunedLiveRange::findBoundariesInBlock( LLVM_DEBUG(llvm::dbgs() << "Has multiple defs!\n"); // Handle a live-out or live-within block with potentially multiple defs - // unsigned prevCount = boundary.getNumLastUsersAndDeadDefs(bitNo); + unsigned prevCount = boundary.getNumLastUsersAndDeadDefs(bitNo); bool isLive = isLiveOut; for (auto &inst : llvm::reverse(*block)) { LLVM_DEBUG(llvm::dbgs() << "Visiting: " << inst); @@ -861,6 +861,7 @@ void FieldSensitiveMultiDefPrunedLiveRange::findBoundariesInBlock( << " Live at beginning of block! No dead args!\n"); } - // assert(prevCount < boundary.getNumLastUsersAndDeadDefs(bitNo) && - // "findBoundariesInBlock must be called on a live block"); + assert((isLiveOut || + prevCount < boundary.getNumLastUsersAndDeadDefs(bitNo)) && + "findBoundariesInBlock must be called on a live block"); } From 1f389d7d9700da7c05dea2b8dfc110d2dd6e5953 Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Mon, 9 Jan 2023 14:23:13 -0800 Subject: [PATCH 2/3] Enable some tests I forgot to un-ifdef out. --- test/SILOptimizer/moveonly_addresschecker_diagnostics.swift | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift b/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift index 92cb1bc823325..0982c55a49a75 100644 --- a/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift +++ b/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift @@ -2307,7 +2307,6 @@ func fieldSensitiveTestReinitField () { classUseMoveOnlyWithoutEscaping(a.k) } -#if false func fieldSensitiveTestReinitFieldMultiBlock1 () { var a = NonTrivialStruct() a = NonTrivialStruct() @@ -2318,7 +2317,6 @@ func fieldSensitiveTestReinitFieldMultiBlock1 () { classUseMoveOnlyWithoutEscaping(a.k) } } -#endif func fieldSensitiveTestReinitFieldMultiBlock2 () { var a = NonTrivialStruct() // expected-error {{'a' used after consume. Lifetime extension of variable requires a copy}} @@ -2332,7 +2330,6 @@ func fieldSensitiveTestReinitFieldMultiBlock2 () { classUseMoveOnlyWithoutEscaping(a.k) // expected-note {{non-consuming use}} } -#if false func fieldSensitiveTestReinitFieldMultiBlock3 () { var a = NonTrivialStruct() a = NonTrivialStruct() @@ -2346,9 +2343,7 @@ func fieldSensitiveTestReinitFieldMultiBlock3 () { classUseMoveOnlyWithoutEscaping(a.k) } -#endif -#if false func fieldSensitiveTestReinitFieldMultiBlock4 () { var a = NonTrivialStruct() a = NonTrivialStruct() @@ -2362,4 +2357,3 @@ func fieldSensitiveTestReinitFieldMultiBlock4 () { classUseMoveOnlyWithoutEscaping(a.k) } -#endif From 8356a1d061152fcb68a594175ae4c9462062fef7 Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Mon, 9 Jan 2023 14:32:44 -0800 Subject: [PATCH 3/3] [move-only-addr] Add some more enum switch tests that test reiniting. --- .../moveonly_addresschecker_diagnostics.swift | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift b/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift index 0982c55a49a75..d943ab243ce2c 100644 --- a/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift +++ b/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift @@ -2299,7 +2299,7 @@ func copyableStructsInMoveOnlyStructNonConsuming() { // Field Sensitive Tests // /////////////////////////// -func fieldSensitiveTestReinitField () { +func fieldSensitiveTestReinitField() { var a = NonTrivialStruct() a = NonTrivialStruct() classConsume(a.k) @@ -2307,7 +2307,7 @@ func fieldSensitiveTestReinitField () { classUseMoveOnlyWithoutEscaping(a.k) } -func fieldSensitiveTestReinitFieldMultiBlock1 () { +func fieldSensitiveTestReinitFieldMultiBlock1() { var a = NonTrivialStruct() a = NonTrivialStruct() classConsume(a.k) @@ -2318,7 +2318,7 @@ func fieldSensitiveTestReinitFieldMultiBlock1 () { } } -func fieldSensitiveTestReinitFieldMultiBlock2 () { +func fieldSensitiveTestReinitFieldMultiBlock2() { var a = NonTrivialStruct() // expected-error {{'a' used after consume. Lifetime extension of variable requires a copy}} a = NonTrivialStruct() classConsume(a.k) // expected-note {{consuming use}} @@ -2330,7 +2330,7 @@ func fieldSensitiveTestReinitFieldMultiBlock2 () { classUseMoveOnlyWithoutEscaping(a.k) // expected-note {{non-consuming use}} } -func fieldSensitiveTestReinitFieldMultiBlock3 () { +func fieldSensitiveTestReinitFieldMultiBlock3() { var a = NonTrivialStruct() a = NonTrivialStruct() classConsume(a.k) @@ -2344,7 +2344,9 @@ func fieldSensitiveTestReinitFieldMultiBlock3 () { classUseMoveOnlyWithoutEscaping(a.k) } -func fieldSensitiveTestReinitFieldMultiBlock4 () { +// This test sees what happens if we partially reinit along one path and do a +// full reinit along another path. +func fieldSensitiveTestReinitFieldMultiBlock4() { var a = NonTrivialStruct() a = NonTrivialStruct() classConsume(a.k) @@ -2357,3 +2359,43 @@ func fieldSensitiveTestReinitFieldMultiBlock4 () { classUseMoveOnlyWithoutEscaping(a.k) } + +func fieldSensitiveTestReinitEnumMultiBlock() { + var e = NonTrivialEnum.first // expected-error {{'e' used after consume. Lifetime extension of variable requires a copy}} + e = NonTrivialEnum.second(Klass()) + switch e { // expected-note {{consuming use}} + case .second: + e = NonTrivialEnum.third(NonTrivialStruct()) + default: + break + } + nonConsumingUseNonTrivialEnum(e) // expected-note {{non-consuming use}} +} + +func fieldSensitiveTestReinitEnumMultiBlock1() { + var e = NonTrivialEnum.first + e = NonTrivialEnum.second(Klass()) + switch e { + case .second: + e = NonTrivialEnum.third(NonTrivialStruct()) + default: + e = NonTrivialEnum.fourth(CopyableKlass()) + } + nonConsumingUseNonTrivialEnum(e) +} + +func fieldSensitiveTestReinitEnumMultiBlock2() { + var e = NonTrivialEnum.first + e = NonTrivialEnum.second(Klass()) + if boolValue { + switch e { + case .second: + e = NonTrivialEnum.third(NonTrivialStruct()) + default: + e = NonTrivialEnum.fourth(CopyableKlass()) + } + } else { + e = NonTrivialEnum.third(NonTrivialStruct()) + } + nonConsumingUseNonTrivialEnum(e) +}