Skip to content

Commit 5baf2af

Browse files
committed
[sil] Add a new instruction called explicit_copy_addr.
This is exactly like copy_addr except that it is not viewed from the verifiers perspective as an "invalid" copy of a move only value. It is intended to be used in two contexts: 1. When the move checker emits a diagnostic since it could not eliminate a copy, we still need to produce valid SIL without copy_addr on move only types since we will hit canonical SIL eventually even if we don't actually codegen the SIL. The pass can just convert said copy_addr to explicit_copy_addr and everyone is happy. 2. To implement the explicit copy function for address only types.
1 parent 82ae1d1 commit 5baf2af

File tree

19 files changed

+249
-1
lines changed

19 files changed

+249
-1
lines changed

docs/SIL.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4245,6 +4245,25 @@ operations::
42454245
If ``T`` is a trivial type, then ``copy_addr`` is always equivalent to its
42464246
take-initialization form.
42474247

4248+
It is illegal in non-Raw SIL to apply ``copy_addr [init]`` to a value that is
4249+
move only.
4250+
4251+
explicit_copy_addr
4252+
``````````````````
4253+
::
4254+
4255+
sil-instruction ::= 'explicit_copy_addr' '[take]'? sil-value
4256+
'to' '[initialization]'? sil-operand
4257+
4258+
explicit_copy_addr [take] %0 to [initialization] %1 : $*T
4259+
// %0 and %1 must be of the same $*T address type
4260+
4261+
This instruction is exactly the same as `copy_addr`_ except that it has special
4262+
behavior for move only types. Specifically, an `explicit_copy_addr`_ is viewed
4263+
as a copy_addr that is allowed on values that are move only. This is only used
4264+
by a move checker after it has emitted an error diagnostic to preserve the
4265+
general ``copy_addr [init]`` ban in Canonical SIL on move only types.
4266+
42484267
destroy_addr
42494268
````````````
42504269
::

include/swift/SIL/SILBuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,14 @@ class SILBuilder {
10371037
getSILDebugLocation(Loc), srcAddr, destAddr, isTake, isInitialize));
10381038
}
10391039

1040+
ExplicitCopyAddrInst *
1041+
createExplicitCopyAddr(SILLocation Loc, SILValue srcAddr, SILValue destAddr,
1042+
IsTake_t isTake, IsInitialization_t isInitialize) {
1043+
assert(srcAddr->getType() == destAddr->getType());
1044+
return insert(new (getModule()) ExplicitCopyAddrInst(
1045+
getSILDebugLocation(Loc), srcAddr, destAddr, isTake, isInitialize));
1046+
}
1047+
10401048
BindMemoryInst *createBindMemory(SILLocation Loc, SILValue base,
10411049
SILValue index, SILType boundType) {
10421050
return insert(BindMemoryInst::create(getSILDebugLocation(Loc), base, index,

include/swift/SIL/SILCloner.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,17 @@ SILCloner<ImplClass>::visitCopyAddrInst(CopyAddrInst *Inst) {
13831383
Inst->isInitializationOfDest()));
13841384
}
13851385

1386+
template <typename ImplClass>
1387+
void SILCloner<ImplClass>::visitExplicitCopyAddrInst(
1388+
ExplicitCopyAddrInst *Inst) {
1389+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1390+
recordClonedInstruction(
1391+
Inst, getBuilder().createExplicitCopyAddr(
1392+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()),
1393+
getOpValue(Inst->getDest()), Inst->isTakeOfSrc(),
1394+
Inst->isInitializationOfDest()));
1395+
}
1396+
13861397
template <typename ImplClass>
13871398
void SILCloner<ImplClass>::visitMarkUnresolvedMoveAddrInst(
13881399
MarkUnresolvedMoveAddrInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5000,6 +5000,48 @@ class CopyAddrInst
50005000
MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
50015001
};
50025002

5003+
/// ExplicitCopyAddrInst - A copy_addr that should not be optimized and should
5004+
/// be viewed
5005+
class ExplicitCopyAddrInst
5006+
: public InstructionBase<SILInstructionKind::ExplicitCopyAddrInst,
5007+
NonValueInstruction>,
5008+
public CopyLikeInstruction {
5009+
friend SILBuilder;
5010+
5011+
private:
5012+
FixedOperandList<2> Operands;
5013+
USE_SHARED_UINT8;
5014+
5015+
ExplicitCopyAddrInst(SILDebugLocation DebugLoc, SILValue Src, SILValue Dest,
5016+
IsTake_t isTakeOfSrc,
5017+
IsInitialization_t isInitializationOfDest);
5018+
5019+
public:
5020+
SILValue getSrc() const { return Operands[Src].get(); }
5021+
SILValue getDest() const { return Operands[Dest].get(); }
5022+
5023+
void setSrc(SILValue V) { Operands[Src].set(V); }
5024+
void setDest(SILValue V) { Operands[Dest].set(V); }
5025+
5026+
IsTake_t isTakeOfSrc() const {
5027+
return IsTake_t(sharedUInt8().ExplicitCopyAddrInst.isTakeOfSrc);
5028+
}
5029+
IsInitialization_t isInitializationOfDest() const {
5030+
return IsInitialization_t(
5031+
sharedUInt8().ExplicitCopyAddrInst.isInitializationOfDest);
5032+
}
5033+
5034+
void setIsTakeOfSrc(IsTake_t T) {
5035+
sharedUInt8().ExplicitCopyAddrInst.isTakeOfSrc = (bool)T;
5036+
}
5037+
void setIsInitializationOfDest(IsInitialization_t I) {
5038+
sharedUInt8().ExplicitCopyAddrInst.isInitializationOfDest = (bool)I;
5039+
}
5040+
5041+
ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
5042+
MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
5043+
};
5044+
50035045
/// "%token = bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $T"
50045046
///
50055047
/// Binds memory at the raw pointer %0 to type $T with enough capacity

include/swift/SIL/SILNode.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ class alignas(8) SILNode :
219219
isTakeOfSrc : 1,
220220
isInitializationOfDest : 1);
221221

222+
SHARED_FIELD(ExplicitCopyAddrInst, uint8_t
223+
isTakeOfSrc : 1,
224+
isInitializationOfDest : 1);
225+
222226
SHARED_FIELD(PointerToAddressInst, uint8_t
223227
isStrict : 1,
224228
isInvariant : 1);

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,8 @@ BRIDGED_NON_VALUE_INST(DebugValueInst, debug_value,
781781
#include "swift/AST/ReferenceStorage.def"
782782
BRIDGED_NON_VALUE_INST(CopyAddrInst, copy_addr,
783783
SILInstruction, MayHaveSideEffects, MayRelease)
784+
BRIDGED_NON_VALUE_INST(ExplicitCopyAddrInst, explicit_copy_addr,
785+
SILInstruction, MayHaveSideEffects, MayRelease)
784786
BRIDGED_NON_VALUE_INST(DestroyAddrInst, destroy_addr,
785787
SILInstruction, MayHaveSideEffects, MayRelease)
786788
NON_VALUE_INST(EndLifetimeInst, end_lifetime,

lib/IRGen/IRGenSIL.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,7 @@ class IRGenSILFunction :
13101310
void visitDeallocPartialRefInst(DeallocPartialRefInst *i);
13111311

13121312
void visitCopyAddrInst(CopyAddrInst *i);
1313+
void visitExplicitCopyAddrInst(ExplicitCopyAddrInst *i);
13131314
void visitMarkUnresolvedMoveAddrInst(MarkUnresolvedMoveAddrInst *mai) {
13141315
llvm_unreachable("Valid only when ownership is enabled");
13151316
}
@@ -6884,6 +6885,30 @@ void IRGenSILFunction::visitCopyAddrInst(swift::CopyAddrInst *i) {
68846885
}
68856886
}
68866887

6888+
void IRGenSILFunction::visitExplicitCopyAddrInst(
6889+
swift::ExplicitCopyAddrInst *i) {
6890+
SILType addrTy = i->getSrc()->getType();
6891+
const TypeInfo &addrTI = getTypeInfo(addrTy);
6892+
Address src = getLoweredAddress(i->getSrc());
6893+
// See whether we have a deferred fixed-size buffer initialization.
6894+
auto &loweredDest = getLoweredValue(i->getDest());
6895+
assert(!loweredDest.isUnallocatedAddressInBuffer());
6896+
Address dest = loweredDest.getAnyAddress();
6897+
if (i->isInitializationOfDest()) {
6898+
if (i->isTakeOfSrc()) {
6899+
addrTI.initializeWithTake(*this, dest, src, addrTy, false);
6900+
} else {
6901+
addrTI.initializeWithCopy(*this, dest, src, addrTy, false);
6902+
}
6903+
} else {
6904+
if (i->isTakeOfSrc()) {
6905+
addrTI.assignWithTake(*this, dest, src, addrTy, false);
6906+
} else {
6907+
addrTI.assignWithCopy(*this, dest, src, addrTy, false);
6908+
}
6909+
}
6910+
}
6911+
68876912
// bind_memory and rebind_memory are no-ops because Swift TBAA info is not
68886913
// lowered to LLVM IR TBAA, and the output token is ignored except for
68896914
// verification.

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ OPERAND_OWNERSHIP(TrivialUse, CheckedCastAddrBranch)
147147
OPERAND_OWNERSHIP(TrivialUse, CondBranch)
148148
OPERAND_OWNERSHIP(TrivialUse, CondFail)
149149
OPERAND_OWNERSHIP(TrivialUse, CopyAddr)
150+
OPERAND_OWNERSHIP(TrivialUse, ExplicitCopyAddr)
150151
OPERAND_OWNERSHIP(TrivialUse, MarkUnresolvedMoveAddr)
151152
OPERAND_OWNERSHIP(TrivialUse, DeallocStack)
152153
OPERAND_OWNERSHIP(TrivialUse, DeinitExistentialAddr)

lib/SIL/IR/SILInstructions.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,15 @@ CopyAddrInst::CopyAddrInst(SILDebugLocation Loc, SILValue SrcLValue,
11721172
bool(isInitializationOfDest);
11731173
}
11741174

1175+
ExplicitCopyAddrInst::ExplicitCopyAddrInst(
1176+
SILDebugLocation Loc, SILValue SrcLValue, SILValue DestLValue,
1177+
IsTake_t isTakeOfSrc, IsInitialization_t isInitializationOfDest)
1178+
: InstructionBase(Loc), Operands(this, SrcLValue, DestLValue) {
1179+
sharedUInt8().ExplicitCopyAddrInst.isTakeOfSrc = bool(isTakeOfSrc);
1180+
sharedUInt8().ExplicitCopyAddrInst.isInitializationOfDest =
1181+
bool(isInitializationOfDest);
1182+
}
1183+
11751184
BindMemoryInst *
11761185
BindMemoryInst::create(SILDebugLocation Loc, SILValue Base, SILValue Index,
11771186
SILType BoundType, SILFunction &F) {

lib/SIL/IR/SILPrinter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,6 +1749,15 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
17491749
*this << getIDAndType(CI->getDest());
17501750
}
17511751

1752+
void visitExplicitCopyAddrInst(ExplicitCopyAddrInst *CI) {
1753+
if (CI->isTakeOfSrc())
1754+
*this << "[take] ";
1755+
*this << Ctx.getID(CI->getSrc()) << " to ";
1756+
if (CI->isInitializationOfDest())
1757+
*this << "[initialization] ";
1758+
*this << getIDAndType(CI->getDest());
1759+
}
1760+
17521761
void visitMarkUnresolvedMoveAddrInst(MarkUnresolvedMoveAddrInst *CI) {
17531762
*this << Ctx.getID(CI->getSrc()) << " to ";
17541763
*this << getIDAndType(CI->getDest());

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4920,6 +4920,37 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
49204920
IsInitialization_t(IsInit));
49214921
break;
49224922
}
4923+
case SILInstructionKind::ExplicitCopyAddrInst: {
4924+
bool IsTake = false, IsInit = false;
4925+
UnresolvedValueName SrcLName;
4926+
SILValue DestLVal;
4927+
SourceLoc ToLoc, DestLoc;
4928+
Identifier ToToken;
4929+
if (parseSILOptional(IsTake, *this, "take") || parseValueName(SrcLName) ||
4930+
parseSILIdentifier(ToToken, ToLoc, diag::expected_tok_in_sil_instr,
4931+
"to") ||
4932+
parseSILOptional(IsInit, *this, "initialization") ||
4933+
parseTypedValueRef(DestLVal, DestLoc, B) ||
4934+
parseSILDebugLocation(InstLoc, B))
4935+
return true;
4936+
4937+
if (ToToken.str() != "to") {
4938+
P.diagnose(ToLoc, diag::expected_tok_in_sil_instr, "to");
4939+
return true;
4940+
}
4941+
4942+
if (!DestLVal->getType().isAddress()) {
4943+
P.diagnose(DestLoc, diag::sil_invalid_instr_operands);
4944+
return true;
4945+
}
4946+
4947+
SILValue SrcLVal =
4948+
getLocalValue(SrcLName, DestLVal->getType(), InstLoc, B);
4949+
ResultVal =
4950+
B.createExplicitCopyAddr(InstLoc, SrcLVal, DestLVal, IsTake_t(IsTake),
4951+
IsInitialization_t(IsInit));
4952+
break;
4953+
}
49234954
case SILInstructionKind::MarkUnresolvedMoveAddrInst: {
49244955
UnresolvedValueName SrcLName;
49254956
SILValue DestLVal;

lib/SIL/Utils/InstructionUtils.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,15 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType)
630630
return RuntimeEffect::MetaData | RuntimeEffect::RefCounting;
631631
return RuntimeEffect::MetaData;
632632
}
633+
case SILInstructionKind::ExplicitCopyAddrInst: {
634+
auto *ca = cast<ExplicitCopyAddrInst>(inst);
635+
impactType = ca->getSrc()->getType();
636+
if (!ca->isInitializationOfDest())
637+
return RuntimeEffect::MetaData | RuntimeEffect::Releasing;
638+
if (!ca->isTakeOfSrc())
639+
return RuntimeEffect::MetaData | RuntimeEffect::RefCounting;
640+
return RuntimeEffect::MetaData;
641+
}
633642
// Equivalent to a copy_addr [init]
634643
case SILInstructionKind::MarkUnresolvedMoveAddrInst: {
635644
return RuntimeEffect::MetaData | RuntimeEffect::RefCounting;

lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ static bool hasOpaqueArchetype(TypeExpansionContext context,
314314
case SILInstructionKind::Store##Name##Inst:
315315
#include "swift/AST/ReferenceStorage.def"
316316
case SILInstructionKind::CopyAddrInst:
317+
case SILInstructionKind::ExplicitCopyAddrInst:
317318
case SILInstructionKind::MarkUnresolvedMoveAddrInst:
318319
case SILInstructionKind::DestroyAddrInst:
319320
case SILInstructionKind::EndLifetimeInst:

lib/SILOptimizer/Utils/SILInliner.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,7 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
884884
case SILInstructionKind::CopyBlockInst:
885885
case SILInstructionKind::CopyBlockWithoutEscapingInst:
886886
case SILInstructionKind::CopyAddrInst:
887+
case SILInstructionKind::ExplicitCopyAddrInst:
887888
case SILInstructionKind::MarkUnresolvedMoveAddrInst:
888889
case SILInstructionKind::RetainValueInst:
889890
case SILInstructionKind::RetainValueAddrInst:

lib/Serialization/DeserializeSIL.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2171,6 +2171,16 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
21712171
IsTake_t(isTake), IsInitialization_t(isInit));
21722172
break;
21732173
}
2174+
case SILInstructionKind::ExplicitCopyAddrInst: {
2175+
auto Ty = MF->getType(TyID);
2176+
SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory, Fn);
2177+
bool isInit = (Attr & 0x2) > 0;
2178+
bool isTake = (Attr & 0x1) > 0;
2179+
ResultInst = Builder.createExplicitCopyAddr(
2180+
Loc, getLocalValue(ValID, addrType), getLocalValue(ValID2, addrType),
2181+
IsTake_t(isTake), IsInitialization_t(isInit));
2182+
break;
2183+
}
21742184

21752185
case SILInstructionKind::MarkUnresolvedMoveAddrInst: {
21762186
auto Ty = MF->getType(TyID);

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 699; // @_alwaysEmitConformanceMetadata
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 700; // explicit_copy_addr
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///

lib/Serialization/SerializeSIL.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,6 +1921,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
19211921
#include "swift/AST/ReferenceStorage.def"
19221922
case SILInstructionKind::AssignInst:
19231923
case SILInstructionKind::CopyAddrInst:
1924+
case SILInstructionKind::ExplicitCopyAddrInst:
19241925
case SILInstructionKind::MarkUnresolvedMoveAddrInst:
19251926
case SILInstructionKind::StoreInst:
19261927
case SILInstructionKind::StoreBorrowInst: {
@@ -1945,6 +1946,11 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
19451946
Attr = (CAI->isInitializationOfDest() << 1) | CAI->isTakeOfSrc();
19461947
operand = cast<CopyAddrInst>(&SI)->getDest();
19471948
value = cast<CopyAddrInst>(&SI)->getSrc();
1949+
} else if (SI.getKind() == SILInstructionKind::ExplicitCopyAddrInst) {
1950+
const auto *CAI = cast<ExplicitCopyAddrInst>(&SI);
1951+
Attr = (CAI->isInitializationOfDest() << 1) | CAI->isTakeOfSrc();
1952+
operand = cast<ExplicitCopyAddrInst>(&SI)->getDest();
1953+
value = cast<ExplicitCopyAddrInst>(&SI)->getSrc();
19481954
} else if (SI.getKind() == SILInstructionKind::MarkUnresolvedMoveAddrInst) {
19491955
auto *mai = cast<MarkUnresolvedMoveAddrInst>(&SI);
19501956
operand = mai->getDest();

test/SIL/Parser/basic2.sil

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,33 @@ bb0(%0 : @owned $@moveOnly Builtin.NativeObject):
113113
%9999 = tuple()
114114
return %9999 : $()
115115
}
116+
117+
// CHECK-LABEL: sil [ossa] @test_explicit_copy_addr : $@convention(thin) (@owned Builtin.NativeObject) -> () {
118+
// CHECK: explicit_copy_addr %{{[0-9]+}} to [initialization] %{{[0-9]+}} :
119+
// CHECK: explicit_copy_addr [take] %{{[0-9]+}} to [initialization] %{{[0-9]+}} :
120+
// CHECK: explicit_copy_addr [take] %{{[0-9]+}} to %{{[0-9]+}} :
121+
// CHECK: explicit_copy_addr %{{[0-9]+}} to %{{[0-9]+}} :
122+
// CHECK: } // end sil function 'test_explicit_copy_addr'
123+
sil [ossa] @test_explicit_copy_addr : $@convention(thin) (@owned Builtin.NativeObject) -> () {
124+
bb0(%0 : @owned $Builtin.NativeObject):
125+
%1 = alloc_stack $Builtin.NativeObject
126+
%2 = alloc_stack $Builtin.NativeObject
127+
%3 = alloc_stack $Builtin.NativeObject
128+
129+
%0a = copy_value %0 : $Builtin.NativeObject
130+
store %0a to [init] %1 : $*Builtin.NativeObject
131+
explicit_copy_addr %1 to [initialization] %2 : $*Builtin.NativeObject
132+
explicit_copy_addr [take] %2 to [initialization] %3 : $*Builtin.NativeObject
133+
explicit_copy_addr [take] %3 to %1 : $*Builtin.NativeObject
134+
135+
store %0 to [init] %2 : $*Builtin.NativeObject
136+
explicit_copy_addr %1 to %2 : $*Builtin.NativeObject
137+
138+
destroy_addr %2 : $*Builtin.NativeObject
139+
destroy_addr %1 : $*Builtin.NativeObject
140+
dealloc_stack %3 : $*Builtin.NativeObject
141+
dealloc_stack %2 : $*Builtin.NativeObject
142+
dealloc_stack %1 : $*Builtin.NativeObject
143+
%9999 = tuple()
144+
return %9999 : $()
145+
}

test/SIL/Serialization/basic2.sil

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,33 @@ bb0(%0 : @owned $Builtin.NativeObject):
2525
%9999 = tuple()
2626
return %9999 : $()
2727
}
28+
29+
// CHECK-LABEL: sil [ossa] @test_explicit_copy_addr : $@convention(thin) (@owned Builtin.NativeObject) -> () {
30+
// CHECK: explicit_copy_addr %{{[0-9]+}} to [initialization] %{{[0-9]+}} :
31+
// CHECK: explicit_copy_addr [take] %{{[0-9]+}} to [initialization] %{{[0-9]+}} :
32+
// CHECK: explicit_copy_addr [take] %{{[0-9]+}} to %{{[0-9]+}} :
33+
// CHECK: explicit_copy_addr %{{[0-9]+}} to %{{[0-9]+}} :
34+
// CHECK: } // end sil function 'test_explicit_copy_addr'
35+
sil [ossa] @test_explicit_copy_addr : $@convention(thin) (@owned Builtin.NativeObject) -> () {
36+
bb0(%0 : @owned $Builtin.NativeObject):
37+
%1 = alloc_stack $Builtin.NativeObject
38+
%2 = alloc_stack $Builtin.NativeObject
39+
%3 = alloc_stack $Builtin.NativeObject
40+
41+
%0a = copy_value %0 : $Builtin.NativeObject
42+
store %0a to [init] %1 : $*Builtin.NativeObject
43+
explicit_copy_addr %1 to [initialization] %2 : $*Builtin.NativeObject
44+
explicit_copy_addr [take] %2 to [initialization] %3 : $*Builtin.NativeObject
45+
explicit_copy_addr [take] %3 to %1 : $*Builtin.NativeObject
46+
47+
store %0 to [init] %2 : $*Builtin.NativeObject
48+
explicit_copy_addr %1 to %2 : $*Builtin.NativeObject
49+
50+
destroy_addr %2 : $*Builtin.NativeObject
51+
destroy_addr %1 : $*Builtin.NativeObject
52+
dealloc_stack %3 : $*Builtin.NativeObject
53+
dealloc_stack %2 : $*Builtin.NativeObject
54+
dealloc_stack %1 : $*Builtin.NativeObject
55+
%9999 = tuple()
56+
return %9999 : $()
57+
}

0 commit comments

Comments
 (0)