Skip to content

Commit 810880c

Browse files
committed
MoveOnlyAddressChecker: Relax more checks to accommodate borrowing switch codegen.
`unchecked_take_enum_data_addr` should not be considered a write when it's non- destructive; this should eventually be an inherent property of the instruction, but there are other passes which miscompile currently if we change that now. Meanwhile, wrapping a copyable value should always be considered an initialization too.
1 parent 81dbc53 commit 810880c

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,14 @@ void UseState::initializeLiveness(
11361136
recordInitUse(address, address, liveness.getTopLevelSpan());
11371137
liveness.initializeDef(SILValue(address), liveness.getTopLevelSpan());
11381138
}
1139+
1140+
// Assume a value wrapped in a MoveOnlyWrapper is initialized.
1141+
if (auto *m2c = dyn_cast<CopyableToMoveOnlyWrapperAddrInst>(address->getOperand())) {
1142+
LLVM_DEBUG(llvm::dbgs()
1143+
<< "Adding copyable_to_move_only_wrapper as init!\n");
1144+
recordInitUse(address, address, liveness.getTopLevelSpan());
1145+
liveness.initializeDef(SILValue(address), liveness.getTopLevelSpan());
1146+
}
11391147

11401148
// Now that we have finished initialization of defs, change our multi-maps
11411149
// from their array form to their map form.
@@ -2570,9 +2578,14 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
25702578

25712579
#ifndef NDEBUG
25722580
if (user->mayWriteToMemory()) {
2573-
llvm::errs() << "Found a write classified as a liveness use?!\n";
2574-
llvm::errs() << "Use: " << *user;
2575-
llvm_unreachable("standard failure");
2581+
// TODO: `unchecked_take_enum_addr` should inherently be understood as
2582+
// non-side-effecting when it's nondestructive.
2583+
auto ue = dyn_cast<UncheckedTakeEnumDataAddrInst>(user);
2584+
if (!ue || ue->isDestructive()) {
2585+
llvm::errs() << "Found a write classified as a liveness use?!\n";
2586+
llvm::errs() << "Use: " << *user;
2587+
llvm_unreachable("standard failure");
2588+
}
25762589
}
25772590
#endif
25782591
useState.recordLivenessUse(user, *leafRange);

test/SILOptimizer/moveonly_borrowing_switch.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,24 @@ func testOuterAO(consuming bas: consuming AOBas) { // expected-error{{'bas' used
242242
}
243243
}
244244

245+
enum E<T>: ~Copyable {
246+
case a(T)
247+
}
248+
249+
extension E {
250+
func f() {
251+
switch self {
252+
case .a:
253+
print("a")
254+
}
255+
}
256+
257+
func g() {
258+
switch self {
259+
case .a(_borrowing t): // expected-warning{{}}
260+
print("a")
261+
}
262+
}
263+
}
264+
265+
E.a(1).f()

0 commit comments

Comments
 (0)