diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h index 32d1389d4d990..f56a62293009f 100644 --- a/include/swift/SIL/SILBuilder.h +++ b/include/swift/SIL/SILBuilder.h @@ -2102,13 +2102,20 @@ class SILBuilder { SingleValueInstruction * createUncheckedReinterpretCast(SILLocation Loc, SILValue Op, SILType Ty); - /// Create an appropriate cast instruction based on result type. + /// Create an appropriate cast instruction based on result type. This cast + /// forwards ownership from the operand to the result. /// - /// NOTE: This assumes that the input and the result cast are layout - /// compatible. Reduces to createUncheckedReinterpretCast when ownership is - /// disabled. - SingleValueInstruction *createUncheckedBitCast(SILLocation Loc, SILValue Op, - SILType Ty); + /// WARNING: Because it forwards ownership, this cast is only valid with the + /// source and destination types are layout equivalent. The destination type + /// must include all the same references in the same positions. + /// + /// Note: Forwarding casts do not exist outside of OSSA. When ownership is + /// disabled, this reduces to createUncheckedReinterpretCast, which may + /// fall-back to unchecked_bitwise_cast. It is the caller's responsibility to + /// emit the correct retains and releases. + SingleValueInstruction *createUncheckedForwardingCast(SILLocation Loc, + SILValue Op, + SILType Ty); //===--------------------------------------------------------------------===// // Runtime failure diff --git a/lib/SIL/IR/SILBuilder.cpp b/lib/SIL/IR/SILBuilder.cpp index d8782af1158d2..05e4ed2baf1ad 100644 --- a/lib/SIL/IR/SILBuilder.cpp +++ b/lib/SIL/IR/SILBuilder.cpp @@ -174,7 +174,8 @@ SILBuilder::createUncheckedReinterpretCast(SILLocation Loc, SILValue Op, // Create the appropriate cast instruction based on result type. SingleValueInstruction * -SILBuilder::createUncheckedBitCast(SILLocation Loc, SILValue Op, SILType Ty) { +SILBuilder::createUncheckedForwardingCast(SILLocation Loc, SILValue Op, + SILType Ty) { // Without ownership, delegate to unchecked reinterpret cast. if (!hasOwnership()) return createUncheckedReinterpretCast(Loc, Op, Ty); diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp index e52a4df73b347..655678e7840c0 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp @@ -169,7 +169,7 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI, Args.push_back(UAC); } else if (OldOpType.getASTType() != NewOpType.getASTType()) { auto URC = - Builder.createUncheckedBitCast(AI.getLoc(), Op, NewOpType); + Builder.createUncheckedForwardingCast(AI.getLoc(), Op, NewOpType); Args.push_back(URC); } else { Args.push_back(Op); @@ -221,8 +221,8 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI, for (auto e = newOpResultTypes.end(); newRetI != e; ++oldRetI, ++newRetI, ++origArgI) { auto arg = normalBB->createPhiArgument(*newRetI, (*origArgI)->getOwnershipKind()); - auto converted = Builder.createUncheckedBitCast(AI.getLoc(), - arg, *oldRetI); + auto converted = + Builder.createUncheckedForwardingCast(AI.getLoc(), arg, *oldRetI); branchArgs.push_back(converted); } @@ -246,7 +246,8 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI, SILInstruction *result = NAI; if (oldResultTy != newResultTy) { - result = Builder.createUncheckedBitCast(AI.getLoc(), NAI, oldResultTy); + result = + Builder.createUncheckedForwardingCast(AI.getLoc(), NAI, oldResultTy); } return result; diff --git a/lib/SILOptimizer/Transforms/EagerSpecializer.cpp b/lib/SILOptimizer/Transforms/EagerSpecializer.cpp index 0793facbd0a15..dd9ef9af2c373 100644 --- a/lib/SILOptimizer/Transforms/EagerSpecializer.cpp +++ b/lib/SILOptimizer/Transforms/EagerSpecializer.cpp @@ -438,7 +438,7 @@ void EagerDispatch::emitDispatchTo(SILFunction *NewFunc) { auto GenResultTy = GenericFunc->mapTypeIntoContext(resultTy); SILValue CastResult = - Builder.createUncheckedBitCast(Loc, Result, GenResultTy); + Builder.createUncheckedForwardingCast(Loc, Result, GenResultTy); addReturnValue(Builder.getInsertionBB(), OldReturnBB, CastResult); } @@ -640,7 +640,7 @@ SILValue EagerDispatch::emitArgumentCast(CanSILFunctionType CalleeSubstFnTy, if (CastTy.isAddress()) return Builder.createUncheckedAddrCast(Loc, OrigArg, CastTy); - return Builder.createUncheckedBitCast(Loc, OrigArg, CastTy); + return Builder.createUncheckedForwardingCast(Loc, OrigArg, CastTy); } /// Converts each generic function argument into a SILValue that can be passed