@@ -2125,40 +2125,10 @@ void SignatureExpansion::expandAsyncReturnType() {
21252125 }
21262126 };
21272127
2128- auto fnConv = getSILFuncConventions ();
2129-
2130- auto resultType =
2131- fnConv.getSILResultType (IGM.getMaximalTypeExpansionContext ());
2128+ auto resultType = getSILFuncConventions ().getSILResultType (
2129+ IGM.getMaximalTypeExpansionContext ());
21322130 auto &ti = IGM.getTypeInfo (resultType);
21332131 auto &native = ti.nativeReturnValueSchema (IGM);
2134-
2135- if (!fnConv.hasIndirectSILResults () && !fnConv.hasIndirectSILErrorResults () &&
2136- !native.requiresIndirect () && fnConv.funcTy ->hasErrorResult () &&
2137- fnConv.isTypedError ()) {
2138- auto errorType = getSILFuncConventions ().getSILErrorType (
2139- IGM.getMaximalTypeExpansionContext ());
2140- auto &errorTi = IGM.getTypeInfo (errorType);
2141- auto &nativeError = errorTi.nativeReturnValueSchema (IGM);
2142- if (!nativeError.shouldReturnTypedErrorIndirectly ()) {
2143- auto combined = combineResultAndTypedErrorType (IGM, native, nativeError);
2144-
2145- if (combined.combinedTy ->isVoidTy ()) {
2146- addErrorResult ();
2147- return ;
2148- }
2149-
2150- if (auto *structTy = dyn_cast<llvm::StructType>(combined.combinedTy )) {
2151- for (auto *elem : structTy->elements ()) {
2152- ParamIRTypes.push_back (elem);
2153- }
2154- } else {
2155- ParamIRTypes.push_back (combined.combinedTy );
2156- }
2157- }
2158- addErrorResult ();
2159- return ;
2160- }
2161-
21622132 if (native.requiresIndirect () || native.empty ()) {
21632133 addErrorResult ();
21642134 return ;
@@ -2176,23 +2146,11 @@ void SignatureExpansion::expandAsyncReturnType() {
21762146void SignatureExpansion::addIndirectThrowingResult () {
21772147 if (getSILFuncConventions ().funcTy ->hasErrorResult () &&
21782148 getSILFuncConventions ().isTypedError ()) {
2179- auto resultType = getSILFuncConventions ().getSILResultType (
2180- IGM.getMaximalTypeExpansionContext ());
2181- auto &ti = IGM.getTypeInfo (resultType);
2182- auto &native = ti.nativeReturnValueSchema (IGM);
2183-
2184- auto errorType = getSILFuncConventions ().getSILErrorType (
2185- IGM.getMaximalTypeExpansionContext ());
2186- const TypeInfo &errorTI = IGM.getTypeInfo (errorType);
2187- auto &nativeError = errorTI.nativeReturnValueSchema (IGM);
2188-
2189- if (getSILFuncConventions ().hasIndirectSILResults () ||
2190- getSILFuncConventions ().hasIndirectSILErrorResults () ||
2191- native.requiresIndirect () ||
2192- nativeError.shouldReturnTypedErrorIndirectly ()) {
2193- auto errorStorageTy = errorTI.getStorageType ();
2194- ParamIRTypes.push_back (errorStorageTy->getPointerTo ());
2195- }
2149+ auto resultType = getSILFuncConventions ().getSILErrorType (
2150+ IGM.getMaximalTypeExpansionContext ());
2151+ const TypeInfo &resultTI = IGM.getTypeInfo (resultType);
2152+ auto storageTy = resultTI.getStorageType ();
2153+ ParamIRTypes.push_back (storageTy->getPointerTo ());
21962154 }
21972155
21982156}
@@ -2318,36 +2276,6 @@ void SignatureExpansion::expandAsyncAwaitType() {
23182276 IGM.getMaximalTypeExpansionContext ());
23192277 auto &ti = IGM.getTypeInfo (resultType);
23202278 auto &native = ti.nativeReturnValueSchema (IGM);
2321-
2322- if (!getSILFuncConventions ().hasIndirectSILResults () &&
2323- !getSILFuncConventions ().hasIndirectSILErrorResults () &&
2324- getSILFuncConventions ().funcTy ->hasErrorResult () &&
2325- !native.requiresIndirect () && getSILFuncConventions ().isTypedError ()) {
2326- auto errorType = getSILFuncConventions ().getSILErrorType (
2327- IGM.getMaximalTypeExpansionContext ());
2328- auto &errorTi = IGM.getTypeInfo (errorType);
2329- auto &nativeError = errorTi.nativeReturnValueSchema (IGM);
2330- if (!nativeError.shouldReturnTypedErrorIndirectly ()) {
2331- auto combined = combineResultAndTypedErrorType (IGM, native, nativeError);
2332-
2333- if (combined.combinedTy ->isVoidTy ()) {
2334- addErrorResult ();
2335- return ;
2336- }
2337-
2338- if (auto *structTy = dyn_cast<llvm::StructType>(combined.combinedTy )) {
2339- for (auto *elem : structTy->elements ()) {
2340- components.push_back (elem);
2341- }
2342- } else {
2343- components.push_back (combined.combinedTy );
2344- }
2345- addErrorResult ();
2346- ResultIRType = llvm::StructType::get (IGM.getLLVMContext (), components);
2347- return ;
2348- }
2349- }
2350-
23512279 if (native.requiresIndirect () || native.empty ()) {
23522280 addErrorResult ();
23532281 ResultIRType = llvm::StructType::get (IGM.getLLVMContext (), components);
@@ -2361,6 +2289,7 @@ void SignatureExpansion::expandAsyncAwaitType() {
23612289 });
23622290
23632291 addErrorResult ();
2292+
23642293 ResultIRType = llvm::StructType::get (IGM.getLLVMContext (), components);
23652294}
23662295
@@ -3022,22 +2951,9 @@ class AsyncCallEmission final : public CallEmission {
30222951 setIndirectTypedErrorResultSlotArgsIndex (--LastArgWritten);
30232952 Args[LastArgWritten] = nullptr ;
30242953 } else {
3025- auto silResultTy =
3026- fnConv.getSILResultType (IGF.IGM .getMaximalTypeExpansionContext ());
3027- auto silErrorTy =
3028- fnConv.getSILErrorType (IGF.IGM .getMaximalTypeExpansionContext ());
3029-
3030- auto &nativeSchema =
3031- IGF.IGM .getTypeInfo (silResultTy).nativeReturnValueSchema (IGF.IGM );
3032- auto &errorSchema =
3033- IGF.IGM .getTypeInfo (silErrorTy).nativeReturnValueSchema (IGF.IGM );
3034-
3035- if (nativeSchema.requiresIndirect () ||
3036- errorSchema.shouldReturnTypedErrorIndirectly ()) {
3037- // Return the error indirectly.
3038- auto buf = IGF.getCalleeTypedErrorResultSlot (silErrorTy);
3039- Args[--LastArgWritten] = buf.getAddress ();
3040- }
2954+ auto buf = IGF.getCalleeTypedErrorResultSlot (
2955+ fnConv.getSILErrorType (IGF.IGM .getMaximalTypeExpansionContext ()));
2956+ Args[--LastArgWritten] = buf.getAddress ();
30412957 }
30422958 }
30432959
@@ -3219,22 +3135,7 @@ class AsyncCallEmission final : public CallEmission {
32193135 errorType =
32203136 substConv.getSILErrorType (IGM.getMaximalTypeExpansionContext ());
32213137
3222- SILFunctionConventions fnConv (getCallee ().getOrigFunctionType (),
3223- IGF.getSILModule ());
3224-
3225- // Get the natural IR type in the body of the function that makes
3226- // the call. This may be different than the IR type returned by the
3227- // call itself due to ABI type coercion.
3228- auto resultType =
3229- fnConv.getSILResultType (IGF.IGM .getMaximalTypeExpansionContext ());
3230- auto &nativeSchema =
3231- IGF.IGM .getTypeInfo (resultType).nativeReturnValueSchema (IGF.IGM );
3232-
3233- bool mayReturnErrorDirectly = mayReturnTypedErrorDirectly ();
3234- if (mayReturnErrorDirectly && !nativeSchema.requiresIndirect ()) {
3235- return emitToUnmappedExplosionWithDirectTypedError (resultType, result,
3236- out);
3237- } else if (resultTys.size () == 1 ) {
3138+ if (resultTys.size () == 1 ) {
32383139 result = Builder.CreateExtractValue (result, numAsyncContextParams);
32393140 if (hasError) {
32403141 Address errorAddr = IGF.getCalleeErrorResultSlot (errorType,
@@ -3266,6 +3167,17 @@ class AsyncCallEmission final : public CallEmission {
32663167 result = resultAgg;
32673168 }
32683169
3170+ SILFunctionConventions fnConv (getCallee ().getOrigFunctionType (),
3171+ IGF.getSILModule ());
3172+
3173+ // Get the natural IR type in the body of the function that makes
3174+ // the call. This may be different than the IR type returned by the
3175+ // call itself due to ABI type coercion.
3176+ auto resultType =
3177+ fnConv.getSILResultType (IGF.IGM .getMaximalTypeExpansionContext ());
3178+ auto &nativeSchema =
3179+ IGF.IGM .getTypeInfo (resultType).nativeReturnValueSchema (IGF.IGM );
3180+
32693181 // For ABI reasons the result type of the call might not actually match the
32703182 // expected result type.
32713183 //
@@ -3404,7 +3316,7 @@ void CallEmission::emitToUnmappedMemory(Address result) {
34043316#ifndef NDEBUG
34053317 LastArgWritten = 0 ; // appease an assert
34063318#endif
3407-
3319+
34083320 auto call = emitCallSite ();
34093321
34103322 // Async calls need to store the error result that is passed as a parameter.
@@ -4492,21 +4404,32 @@ void CallEmission::emitToUnmappedExplosionWithDirectTypedError(
44924404 extractScalarResults (IGF, result->getType (), result, nativeExplosion);
44934405 auto values = nativeExplosion.claimAll ();
44944406
4407+ auto convertIfNecessary = [&](llvm::Type *nativeTy,
4408+ llvm::Value *elt) -> llvm::Value * {
4409+ auto *eltTy = elt->getType ();
4410+ if (nativeTy->isIntOrPtrTy () && eltTy->isIntOrPtrTy () &&
4411+ nativeTy->getPrimitiveSizeInBits () != eltTy->getPrimitiveSizeInBits ()) {
4412+ if (nativeTy->isPointerTy () && eltTy == IGF.IGM .IntPtrTy ) {
4413+ return IGF.Builder .CreateIntToPtr (elt, nativeTy);
4414+ }
4415+ return IGF.Builder .CreateTruncOrBitCast (elt, nativeTy);
4416+ }
4417+ return elt;
4418+ };
4419+
44954420 Explosion errorExplosion;
44964421 if (!errorSchema.empty ()) {
44974422 if (auto *structTy =
44984423 dyn_cast<llvm::StructType>(errorSchema.getExpandedType (IGF.IGM ))) {
44994424 for (unsigned i = 0 , e = structTy->getNumElements (); i < e; ++i) {
45004425 llvm::Value *elt = values[combined.errorValueMapping [i]];
45014426 auto *nativeTy = structTy->getElementType (i);
4502- elt = convertForAsyncDirect (IGF, elt, nativeTy, /* forExtraction */ true );
4427+ elt = convertIfNecessary ( nativeTy, elt );
45034428 errorExplosion.add (elt);
45044429 }
45054430 } else {
4506- auto *converted =
4507- convertForAsyncDirect (IGF, values[combined.errorValueMapping [0 ]],
4508- combined.combinedTy , /* forExtraction*/ true );
4509- errorExplosion.add (converted);
4431+ errorExplosion.add (convertIfNecessary (
4432+ combined.combinedTy , values[combined.errorValueMapping [0 ]]));
45104433 }
45114434
45124435 typedErrorExplosion =
@@ -4522,14 +4445,10 @@ void CallEmission::emitToUnmappedExplosionWithDirectTypedError(
45224445 dyn_cast<llvm::StructType>(nativeSchema.getExpandedType (IGF.IGM ))) {
45234446 for (unsigned i = 0 , e = structTy->getNumElements (); i < e; ++i) {
45244447 auto *nativeTy = structTy->getElementType (i);
4525- auto *converted = convertForAsyncDirect (IGF, values[i], nativeTy,
4526- /* forExtraction*/ true );
4527- resultExplosion.add (converted);
4448+ resultExplosion.add (convertIfNecessary (nativeTy, values[i]));
45284449 }
45294450 } else {
4530- auto *converted = convertForAsyncDirect (
4531- IGF, values[0 ], combined.combinedTy , /* forExtraction*/ true );
4532- resultExplosion.add (converted);
4451+ resultExplosion.add (convertIfNecessary (combined.combinedTy , values[0 ]));
45334452 }
45344453 out = nativeSchema.mapFromNative (IGF.IGM , IGF, resultExplosion, resultType);
45354454 }
@@ -5395,33 +5314,6 @@ llvm::Value* IRGenFunction::coerceValue(llvm::Value *value, llvm::Type *toTy,
53955314 return loaded;
53965315}
53975316
5398- llvm::Value *irgen::convertForAsyncDirect (IRGenFunction &IGF,
5399- llvm::Value *value, llvm::Type *toTy,
5400- bool forExtraction) {
5401- auto &Builder = IGF.Builder ;
5402- auto *fromTy = value->getType ();
5403- if (toTy->isIntOrPtrTy () && fromTy->isIntOrPtrTy () && toTy != fromTy) {
5404-
5405- if (toTy->isPointerTy ()) {
5406- if (fromTy->isPointerTy ())
5407- return Builder.CreateBitCast (value, toTy);
5408- if (fromTy == IGF.IGM .IntPtrTy )
5409- return Builder.CreateIntToPtr (value, toTy);
5410- } else if (fromTy->isPointerTy ()) {
5411- if (toTy == IGF.IGM .IntPtrTy ) {
5412- return Builder.CreatePtrToInt (value, toTy);
5413- }
5414- }
5415-
5416- if (forExtraction) {
5417- return Builder.CreateTruncOrBitCast (value, toTy);
5418- } else {
5419- return Builder.CreateZExtOrBitCast (value, toTy);
5420- }
5421- }
5422- return value;
5423- }
5424-
54255317void IRGenFunction::emitScalarReturn (llvm::Type *resultType,
54265318 Explosion &result) {
54275319 if (result.empty ()) {
@@ -5863,18 +5755,32 @@ void IRGenFunction::emitScalarReturn(SILType returnResultType,
58635755 return ;
58645756 }
58655757
5758+ auto convertIfNecessary = [&](llvm::Type *nativeTy,
5759+ llvm::Value *elt) -> llvm::Value * {
5760+ auto *eltTy = elt->getType ();
5761+ if (nativeTy->isIntOrPtrTy () && eltTy->isIntOrPtrTy () &&
5762+ nativeTy->getPrimitiveSizeInBits () !=
5763+ eltTy->getPrimitiveSizeInBits ()) {
5764+ assert (nativeTy->getPrimitiveSizeInBits () >
5765+ eltTy->getPrimitiveSizeInBits ());
5766+ if (eltTy->isPointerTy ()) {
5767+ return Builder.CreatePtrToInt (elt, nativeTy);
5768+ }
5769+ return Builder.CreateZExt (elt, nativeTy);
5770+ }
5771+ return elt;
5772+ };
5773+
58665774 if (auto *structTy = dyn_cast<llvm::StructType>(combinedTy)) {
58675775 nativeAgg = llvm::UndefValue::get (combinedTy);
58685776 for (unsigned i = 0 , e = native.size (); i != e; ++i) {
58695777 llvm::Value *elt = native.claimNext ();
58705778 auto *nativeTy = structTy->getElementType (i);
5871- elt = convertForAsyncDirect (*this , elt, nativeTy,
5872- /* forExtraction*/ false );
5779+ elt = convertIfNecessary (nativeTy, elt);
58735780 nativeAgg = Builder.CreateInsertValue (nativeAgg, elt, i);
58745781 }
58755782 } else {
5876- nativeAgg = convertForAsyncDirect (*this , native.claimNext (), combinedTy,
5877- /* forExtraction*/ false );
5783+ nativeAgg = convertIfNecessary (combinedTy, native.claimNext ());
58785784 }
58795785 }
58805786
@@ -6184,51 +6090,6 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout,
61846090 SILFunctionConventions conv (fnType, IGF.getSILModule ());
61856091 auto &nativeSchema =
61866092 IGM.getTypeInfo (funcResultTypeInContext).nativeReturnValueSchema (IGM);
6187-
6188- if (fnType->hasErrorResult () && !conv.hasIndirectSILResults () &&
6189- !conv.hasIndirectSILErrorResults () && !nativeSchema.requiresIndirect () &&
6190- conv.isTypedError ()) {
6191- auto errorType = conv.getSILErrorType (IGM.getMaximalTypeExpansionContext ());
6192- auto &errorTI = IGM.getTypeInfo (errorType);
6193- auto &nativeError = errorTI.nativeReturnValueSchema (IGM);
6194- if (!nativeError.shouldReturnTypedErrorIndirectly ()) {
6195- assert (!error.empty () && " Direct error return must have error value" );
6196- auto *combinedTy =
6197- combineResultAndTypedErrorType (IGM, nativeSchema, nativeError)
6198- .combinedTy ;
6199-
6200- if (combinedTy->isVoidTy ()) {
6201- assert (result.empty () && " Unexpected result values" );
6202- } else {
6203- if (auto *structTy = dyn_cast<llvm::StructType>(combinedTy)) {
6204- llvm::Value *nativeAgg = llvm::UndefValue::get (structTy);
6205- for (unsigned i = 0 , e = result.size (); i != e; ++i) {
6206- llvm::Value *elt = result.claimNext ();
6207- auto *nativeTy = structTy->getElementType (i);
6208- elt = convertForAsyncDirect (IGF, elt, nativeTy,
6209- /* forExtraction*/ false );
6210- nativeAgg = IGF.Builder .CreateInsertValue (nativeAgg, elt, i);
6211- }
6212- Explosion out;
6213- IGF.emitAllExtractValues (nativeAgg, structTy, out);
6214- while (!out.empty ()) {
6215- nativeResultsStorage.push_back (out.claimNext ());
6216- }
6217- } else {
6218- auto *converted = convertForAsyncDirect (
6219- IGF, result.claimNext (), combinedTy, /* forExtraction*/ false );
6220- nativeResultsStorage.push_back (converted);
6221- }
6222- }
6223-
6224- nativeResultsStorage.push_back (error.claimNext ());
6225- nativeResults = nativeResultsStorage;
6226-
6227- emitAsyncReturn (IGF, asyncLayout, fnType, nativeResults);
6228- return ;
6229- }
6230- }
6231-
62326093 if (result.empty () && !nativeSchema.empty ()) {
62336094 if (!nativeSchema.requiresIndirect ())
62346095 // When we throw, we set the return values to undef.
0 commit comments