Skip to content

Commit b30fd77

Browse files
committed
Remove all trivial extend_lifetime instructions
during the MoveOnlyWrappedTypeEliminator pass. Such instructions are only valid in RAW SIL. This pass generally removes marker instructions that are only used for ownership diagnostics. Fixes rdar://139450982 ([GH:#77451] Assert failure on `extend_lifetime` verify with `onone-simplification` pass disabled)
1 parent c5ab128 commit b30fd77

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyWrappedTypeEliminator.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -311,19 +311,6 @@ bool SILMoveOnlyWrappedTypeEliminator::process() {
311311
// - record its users for later visitation
312312
auto visitValue = [&touchedInsts, fn = fn,
313313
trivialOnly = trivialOnly](SILValue value) -> bool {
314-
// Trivial move_value instructions are relevant. After they are stripped,
315-
// any extend_lifetime uses are also stripped.
316-
if (isa<MoveValueInst>(value)
317-
&& value->getOwnershipKind() == OwnershipKind::None) {
318-
for (auto *use : value->getNonTypeDependentUses()) {
319-
auto *user = use->getUser();
320-
if (isa<ExtendLifetimeInst>(user)) {
321-
touchedInsts.insert(user);
322-
}
323-
}
324-
return true;
325-
}
326-
327314
if (!value->getType().hasAnyMoveOnlyWrapping(fn))
328315
return false;
329316

@@ -366,6 +353,10 @@ bool SILMoveOnlyWrappedTypeEliminator::process() {
366353

367354
touched = true;
368355
}
356+
// delete trivial move_value and extend_lifetime instructions.
357+
if (isa<MoveValueInst>(ii) || isa<ExtendLifetimeInst>(ii)) {
358+
touched = true;
359+
}
369360
if (!touched)
370361
continue;
371362
touchedInsts.insert(&ii);

test/SILOptimizer/moveonly_type_eliminator.sil

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,3 +637,40 @@ bb0:
637637
%13 = tuple ()
638638
return %13 : $()
639639
}
640+
641+
// Remove trivial move_value + extend_lifetime
642+
//
643+
// CHECK-LABEL: sil [ossa] @move_extend_lifetime : $@convention(thin) (@thin Trivial.Type) -> () {
644+
// CHECK: bb0(%0 : $@thin Trivial.Type):
645+
// CHECK-NOT: move_value
646+
// CHECK-NOT: extend_lifetime
647+
// CHECK-LABEL: } // end sil function 'move_extend_lifetime'
648+
sil [ossa] @move_extend_lifetime : $@convention(thin) (@thin Trivial.Type) -> () {
649+
bb0(%0 : $@thin Trivial.Type):
650+
%mv = move_value [var_decl] %0 : $@thin Trivial.Type
651+
extend_lifetime %mv : $@thin Trivial.Type
652+
%13 = tuple ()
653+
return %13 : $()
654+
}
655+
656+
sil @captureType : $@convention(thin) (@thin Trivial.Type) -> ()
657+
sil @takeClosure : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
658+
659+
// SILGen pattern binding can (incorrectly) create a local variable to hold the value a function argument. This results
660+
// in an extend_lifetime that directly uses the argument value. Ensure that MoveOnlyTypeEliminator erases the
661+
// extend_lifetime.
662+
//
663+
// CHECK-LABEL: sil [ossa] @arg_extend_lifetime : $@convention(thin) (@thin Trivial.Type) -> () {
664+
// CHECK-NOT: extend_lifetime
665+
// CHECK-LABEL: } // end sil function 'arg_extend_lifetime'
666+
sil [ossa] @arg_extend_lifetime : $@convention(thin) (@thin Trivial.Type) -> () {
667+
bb0(%0 : $@thin Trivial.Type):
668+
%cf = function_ref @captureType : $@convention(thin) (@thin Trivial.Type) -> ()
669+
%closure = partial_apply [callee_guaranteed] [on_stack] %cf(%0) : $@convention(thin) (@thin Trivial.Type) -> ()
670+
%f = function_ref @takeClosure : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
671+
%6 = apply %f(%closure) : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
672+
destroy_value %closure : $@noescape @callee_guaranteed () -> ()
673+
extend_lifetime %0 : $@thin Trivial.Type
674+
%13 = tuple ()
675+
return %13 : $()
676+
}

0 commit comments

Comments
 (0)