Skip to content

Commit 79b6498

Browse files
committed
Fix operand ownership of mark_dependence [nonescaping] of address values
1 parent 2e92644 commit 79b6498

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

include/swift/SIL/OwnershipUtils.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,7 @@ class InteriorPointerOperandKind {
823823
RefTailAddr,
824824
OpenExistentialBox,
825825
ProjectBox,
826+
MarkDependenceNonEscaping,
826827
};
827828

828829
private:
@@ -851,6 +852,12 @@ class InteriorPointerOperandKind {
851852
return Kind::OpenExistentialBox;
852853
case SILInstructionKind::ProjectBoxInst:
853854
return Kind::ProjectBox;
855+
case SILInstructionKind::MarkDependenceInst: {
856+
auto *mdi = cast<MarkDependenceInst>(use->getUser());
857+
return mdi->isNonEscaping() && mdi->getType().isAddress()
858+
? Kind::MarkDependenceNonEscaping
859+
: Kind::Invalid;
860+
}
854861
}
855862
}
856863

@@ -869,6 +876,12 @@ class InteriorPointerOperandKind {
869876
return Kind::OpenExistentialBox;
870877
case ValueKind::ProjectBoxInst:
871878
return Kind::ProjectBox;
879+
case ValueKind::MarkDependenceInst: {
880+
auto *mdi = cast<MarkDependenceInst>(value->getDefiningInstruction());
881+
return mdi->isNonEscaping() && mdi->getType().isAddress()
882+
? Kind::MarkDependenceNonEscaping
883+
: Kind::Invalid;
884+
}
872885
}
873886
}
874887

@@ -931,6 +944,13 @@ struct InteriorPointerOperand {
931944
&cast<SingleValueInstruction>(resultValue)->getAllOperands()[0];
932945
return InteriorPointerOperand(op, kind);
933946
}
947+
case InteriorPointerOperandKind::MarkDependenceNonEscaping: {
948+
auto *mdi =
949+
cast<MarkDependenceInst>(resultValue->getDefiningInstruction());
950+
assert(mdi->isNonEscaping() && mdi->getType().isAddress());
951+
return InteriorPointerOperand(
952+
&mdi->getAllOperands()[MarkDependenceInst::Base], kind);
953+
}
934954
}
935955
llvm_unreachable("covered switch");
936956
}
@@ -968,6 +988,8 @@ struct InteriorPointerOperand {
968988
return cast<OpenExistentialBoxInst>(operand->getUser());
969989
case InteriorPointerOperandKind::ProjectBox:
970990
return cast<ProjectBoxInst>(operand->getUser());
991+
case InteriorPointerOperandKind::MarkDependenceNonEscaping:
992+
return cast<MarkDependenceInst>(operand->getUser());
971993
}
972994
llvm_unreachable("Covered switch isn't covered?!");
973995
}

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -672,9 +672,12 @@ OperandOwnershipClassifier::visitMarkDependenceInst(MarkDependenceInst *mdi) {
672672
/*allowUnowned*/true);
673673
}
674674
if (mdi->isNonEscaping()) {
675-
// This creates a "dependent value", just like on-stack partial_apply, which
676-
// we treat like a borrow.
677-
return OperandOwnership::Borrow;
675+
if (!mdi->getType().isAddress()) {
676+
// This creates a "dependent value", just like on-stack partial_apply,
677+
// which we treat like a borrow.
678+
return OperandOwnership::Borrow;
679+
}
680+
return OperandOwnership::InteriorPointer;
678681
}
679682
if (mdi->hasUnresolvedEscape()) {
680683
// This creates a dependent value that may extend beyond the parent's

lib/SILOptimizer/SILCombiner/SILCombinerBuiltinVisitors.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ SILCombiner::optimizeBuiltinCOWBufferForReadingOSSA(BuiltinInst *bi) {
163163
return;
164164
case InteriorPointerOperandKind::OpenExistentialBox:
165165
case InteriorPointerOperandKind::ProjectBox:
166+
case InteriorPointerOperandKind::MarkDependenceNonEscaping:
166167
// Can not mark this immutable.
167168
return;
168169
}

test/SILOptimizer/ossa_lifetime_completion.sil

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,3 +956,25 @@ exit:
956956
die:
957957
unreachable
958958
}
959+
960+
class Klass {}
961+
962+
struct Wrapper {
963+
var c: Klass
964+
}
965+
966+
// CHECK-LABEL: begin running test {{.*}} on testInteriorMarkDepNonEscAddressValue: ossa_lifetime_completion
967+
// CHECK-LABEL: sil [ossa] @testInteriorMarkDepNonEscAddressValue : {{.*}} {
968+
// CHECK: mark_dependence
969+
// CHECK: end_borrow
970+
// CHECK-LABEL: } // end sil function 'testInteriorMarkDepNonEscAddressValue'
971+
// CHECK-LABEL: end running test {{.*}} on testInteriorMarkDepNonEscAddressValue: ossa_lifetime_completion
972+
sil [ossa] @testInteriorMarkDepNonEscAddressValue : $@convention(thin) (@owned Wrapper, @inout Klass) -> () {
973+
bb0(%0 : @owned $Wrapper, %1 : $*Klass):
974+
specify_test "ossa_lifetime_completion %2 liveness"
975+
%2 = begin_borrow %0 : $Wrapper
976+
%3 = struct_extract %2 : $Wrapper, #Wrapper.c
977+
%4 = mark_dependence [nonescaping] %1 : $*Klass on %3 : $Klass
978+
end_borrow %2 : $Wrapper
979+
unreachable
980+
}

0 commit comments

Comments
 (0)