@@ -602,10 +602,10 @@ bool ReabstractionInfo::canBeSpecialized(ApplySite Apply, SILFunction *Callee,
602602ReabstractionInfo::ReabstractionInfo (
603603 ModuleDecl *targetModule, bool isWholeModule, ApplySite Apply,
604604 SILFunction *Callee, SubstitutionMap ParamSubs, SerializedKind_t Serialized,
605- bool ConvertIndirectToDirect, bool dropMetatypeArgs ,
605+ bool ConvertIndirectToDirect, bool dropUnusedArguments ,
606606 OptRemark::Emitter *ORE)
607607 : ConvertIndirectToDirect(ConvertIndirectToDirect),
608- dropMetatypeArgs(dropMetatypeArgs ), M(&Callee->getModule ()),
608+ dropUnusedArguments(dropUnusedArguments ), M(&Callee->getModule ()),
609609 TargetModule(targetModule), isWholeModule(isWholeModule),
610610 Serialized(Serialized) {
611611 if (!prepareAndCheck (Apply, Callee, ParamSubs, ORE))
@@ -737,7 +737,7 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() {
737737 SubstitutedType->getParameters ().size ();
738738 Conversions.resize (NumArgs);
739739 TrivialArgs.resize (NumArgs);
740- droppedMetatypeArgs .resize (NumArgs);
740+ droppedArguments .resize (NumArgs);
741741
742742 if (SubstitutedType->getNumDirectFormalResults () == 0 ) {
743743 // The original function has no direct result yet. Try to convert the first
@@ -763,9 +763,11 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() {
763763 }
764764
765765 // Try to convert indirect incoming parameters to direct parameters.
766+ unsigned i = 0 ;
766767 for (SILParameterInfo PI : SubstitutedType->getParameters ()) {
767768 auto IdxToInsert = IdxForParam;
768769 ++IdxForParam;
770+ unsigned argIdx = i++;
769771
770772 SILFunctionConventions substConv (SubstitutedType, getModule ());
771773 TypeCategory tc = getParamTypeCategory (PI, substConv, getResilienceExpansion ());
@@ -776,6 +778,23 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() {
776778 case ParameterConvention::Indirect_In_CXX:
777779 case ParameterConvention::Indirect_In:
778780 case ParameterConvention::Indirect_In_Guaranteed: {
781+ if (Callee && Apply && dropUnusedArguments) {
782+ // If there is no read from an indirect argument, this argument has to
783+ // be dropped. At the call site the store to the argument's memory location
784+ // could have been removed (based on the callee's memory effects).
785+ // Therefore, converting such an unused indirect argument to a direct
786+ // argument, would load an uninitialized value at the call site.
787+ // This would lead to verifier errors and in worst case to a miscompile
788+ // because IRGen can implicitly use dead arguments, e.g. for getting the
789+ // type of a class reference.
790+ if (FullApplySite fas = Apply.asFullApplySite ()) {
791+ Operand &op = fas.getOperandsWithoutIndirectResults ()[argIdx];
792+ if (!Callee->argumentMayRead (&op, op.get ())) {
793+ droppedArguments.set (IdxToInsert);
794+ break ;
795+ }
796+ }
797+ }
779798 Conversions.set (IdxToInsert);
780799 if (tc == LoadableAndTrivial)
781800 TrivialArgs.set (IdxToInsert);
@@ -799,8 +818,8 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() {
799818 case ParameterConvention::Direct_Unowned:
800819 case ParameterConvention::Direct_Guaranteed: {
801820 CanType ty = PI.getInterfaceType ();
802- if (dropMetatypeArgs && isa<MetatypeType>(ty) && !ty->hasArchetype ())
803- droppedMetatypeArgs .set (IdxToInsert);
821+ if (dropUnusedArguments && isa<MetatypeType>(ty) && !ty->hasArchetype ())
822+ droppedArguments .set (IdxToInsert);
804823 break ;
805824 }
806825 }
@@ -887,15 +906,15 @@ ReabstractionInfo::createSubstitutedType(SILFunction *OrigF,
887906}
888907
889908CanSILFunctionType ReabstractionInfo::createThunkType (PartialApplyInst *forPAI) const {
890- if (!droppedMetatypeArgs .any ())
909+ if (!droppedArguments .any ())
891910 return SubstitutedType;
892911
893912 llvm::SmallVector<SILParameterInfo, 8 > newParams;
894913 auto params = SubstitutedType->getParameters ();
895914 unsigned firstAppliedParamIdx = params.size () - forPAI->getArguments ().size ();
896915
897916 for (unsigned paramIdx = 0 ; paramIdx < params.size (); ++paramIdx) {
898- if (paramIdx >= firstAppliedParamIdx && isDroppedMetatypeArg (param2ArgIndex (paramIdx)))
917+ if (paramIdx >= firstAppliedParamIdx && isDroppedArgument (param2ArgIndex (paramIdx)))
899918 continue ;
900919 newParams.push_back (params[paramIdx]);
901920 }
@@ -968,7 +987,7 @@ createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const {
968987 unsigned paramIdx = idx++;
969988 PI = PI.getUnsubstituted (M, SubstFTy, context);
970989
971- if (isDroppedMetatypeArg (param2ArgIndex (paramIdx))) {
990+ if (isDroppedArgument (param2ArgIndex (paramIdx))) {
972991 if (SubstFTy->hasSelfParam () && paramIdx == SubstFTy->getParameters ().size () - 1 )
973992 removedSelfParam = true ;
974993 continue ;
@@ -2216,7 +2235,7 @@ prepareCallArguments(ApplySite AI, SILBuilder &Builder,
22162235 return true ;
22172236 }
22182237
2219- if (ReInfo.isDroppedMetatypeArg (ArgIdx))
2238+ if (ReInfo.isDroppedArgument (ArgIdx))
22202239 return true ;
22212240
22222241 // Handle arguments for formal parameters.
@@ -2738,7 +2757,7 @@ ReabstractionThunkGenerator::convertReabstractionThunkArguments(
27382757 unsigned numParams = OrigF->getLoweredFunctionType ()->getNumParameters ();
27392758 for (unsigned origParamIdx = 0 , specArgIdx = 0 ; origParamIdx < numParams; ++origParamIdx) {
27402759 unsigned origArgIdx = ReInfo.param2ArgIndex (origParamIdx);
2741- if (ReInfo.isDroppedMetatypeArg (origArgIdx)) {
2760+ if (ReInfo.isDroppedArgument (origArgIdx)) {
27422761 assert (origArgIdx >= ApplySite (OrigPAI).getCalleeArgIndexOfFirstAppliedArg () &&
27432762 " cannot drop metatype argument of not applied argument" );
27442763 continue ;
@@ -2862,14 +2881,22 @@ lookupOrCreatePrespecialization(SILOptFunctionBuilder &funcBuilder,
28622881 return declaration;
28632882}
28642883
2865- bool usePrespecialized (
2884+ static bool usePrespecialized (
28662885 SILOptFunctionBuilder &funcBuilder, ApplySite apply, SILFunction *refF,
2867- const ReabstractionInfo &specializedReInfo,
28682886 ReabstractionInfo &prespecializedReInfo, SpecializedFunction &result) {
28692887
2888+ if (refF->getSpecializeAttrs ().empty ())
2889+ return false ;
2890+
28702891 SmallVector<std::tuple<unsigned , ReabstractionInfo, AvailabilityContext>, 4 >
28712892 layoutMatches;
28722893
2894+ ReabstractionInfo specializedReInfo (funcBuilder.getModule ().getSwiftModule (),
2895+ funcBuilder.getModule ().isWholeModule (), apply, refF,
2896+ apply.getSubstitutionMap (), IsNotSerialized,
2897+ /* ConvertIndirectToDirect=*/ true ,
2898+ /* dropMetatypeArgs=*/ false );
2899+
28732900 for (auto *SA : refF->getSpecializeAttrs ()) {
28742901 if (!SA->isExported ())
28752902 continue ;
@@ -3185,7 +3212,7 @@ void swift::trySpecializeApplyOfGeneric(
31853212 ReabstractionInfo prespecializedReInfo (FuncBuilder.getModule ());
31863213 bool replacePartialApplyWithoutReabstraction = false ;
31873214
3188- if (usePrespecialized (FuncBuilder, Apply, RefF, ReInfo, prespecializedReInfo,
3215+ if (usePrespecialized (FuncBuilder, Apply, RefF, prespecializedReInfo,
31893216 prespecializedF)) {
31903217 ReInfo = prespecializedReInfo;
31913218 }
@@ -3343,7 +3370,7 @@ void swift::trySpecializeApplyOfGeneric(
33433370 SmallVector<SILValue, 4 > Arguments;
33443371 for (auto &Op : PAI->getArgumentOperands ()) {
33453372 unsigned calleeArgIdx = ApplySite (PAI).getCalleeArgIndex (Op);
3346- if (ReInfo.isDroppedMetatypeArg (calleeArgIdx))
3373+ if (ReInfo.isDroppedArgument (calleeArgIdx))
33473374 continue ;
33483375 Arguments.push_back (Op.get ());
33493376 }
0 commit comments