@@ -1719,8 +1719,12 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
1719
1719
1720
1720
// Add type for sret argument.
1721
1721
if (IRFunctionArgs.hasSRetArg ()) {
1722
- ArgTypes[IRFunctionArgs.getSRetArgNo ()] = llvm::PointerType::get (
1723
- getLLVMContext (), FI.getReturnInfo ().getIndirectAddrSpace ());
1722
+ QualType Ret = FI.getReturnType ();
1723
+ unsigned AddressSpace = CGM.getCodeGenOpts ().UseAllocaASForSrets
1724
+ ? FI.getReturnInfo ().getIndirectAddrSpace ()
1725
+ : CGM.getTypes ().getTargetAddressSpace (Ret);
1726
+ ArgTypes[IRFunctionArgs.getSRetArgNo ()] =
1727
+ llvm::PointerType::get (getLLVMContext (), AddressSpace);
1724
1728
}
1725
1729
1726
1730
// Add type for inalloca argument.
@@ -5309,6 +5313,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5309
5313
// If the call returns a temporary with struct return, create a temporary
5310
5314
// alloca to hold the result, unless one is given to us.
5311
5315
Address SRetPtr = Address::invalid ();
5316
+ RawAddress SRetAlloca = RawAddress::invalid ();
5312
5317
llvm::Value *UnusedReturnSizePtr = nullptr ;
5313
5318
if (RetAI.isIndirect () || RetAI.isInAlloca () || RetAI.isCoerceAndExpand ()) {
5314
5319
// For virtual function pointer thunks and musttail calls, we must always
@@ -5322,19 +5327,27 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5322
5327
} else if (!ReturnValue.isNull ()) {
5323
5328
SRetPtr = ReturnValue.getAddress ();
5324
5329
} else {
5325
- SRetPtr = CreateMemTempWithoutCast (RetTy, " tmp" );
5330
+ SRetPtr = CGM.getCodeGenOpts ().UseAllocaASForSrets
5331
+ ? CreateMemTempWithoutCast (RetTy, " tmp" )
5332
+ : CreateMemTemp (RetTy, " tmp" , &SRetAlloca);
5326
5333
if (HaveInsertPoint () && ReturnValue.isUnused ()) {
5327
5334
llvm::TypeSize size =
5328
5335
CGM.getDataLayout ().getTypeAllocSize (ConvertTypeForMem (RetTy));
5329
- UnusedReturnSizePtr = EmitLifetimeStart (size, SRetPtr.getBasePointer ());
5336
+ if (CGM.getCodeGenOpts ().UseAllocaASForSrets )
5337
+ UnusedReturnSizePtr =
5338
+ EmitLifetimeStart (size, SRetPtr.getBasePointer ());
5339
+ else
5340
+ UnusedReturnSizePtr =
5341
+ EmitLifetimeStart (size, SRetAlloca.getPointer ());
5330
5342
}
5331
5343
}
5332
5344
if (IRFunctionArgs.hasSRetArg ()) {
5333
5345
// A mismatch between the allocated return value's AS and the target's
5334
5346
// chosen IndirectAS can happen e.g. when passing the this pointer through
5335
5347
// a chain involving stores to / loads from the DefaultAS; we address this
5336
5348
// here, symmetrically with the handling we have for normal pointer args.
5337
- if (SRetPtr.getAddressSpace () != RetAI.getIndirectAddrSpace ()) {
5349
+ if (CGM.getCodeGenOpts ().UseAllocaASForSrets &&
5350
+ (SRetPtr.getAddressSpace () != RetAI.getIndirectAddrSpace ())) {
5338
5351
llvm::Value *V = SRetPtr.getBasePointer ();
5339
5352
LangAS SAS = getLangASFromTargetAS (SRetPtr.getAddressSpace ());
5340
5353
LangAS DAS = getLangASFromTargetAS (RetAI.getIndirectAddrSpace ());
@@ -5916,9 +5929,14 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5916
5929
// can't depend on being inside of an ExprWithCleanups, so we need to manually
5917
5930
// pop this cleanup later on. Being eager about this is OK, since this
5918
5931
// temporary is 'invisible' outside of the callee.
5919
- if (UnusedReturnSizePtr)
5920
- pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetPtr,
5921
- UnusedReturnSizePtr);
5932
+ if (UnusedReturnSizePtr) {
5933
+ if (CGM.getCodeGenOpts ().UseAllocaASForSrets )
5934
+ pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetPtr,
5935
+ UnusedReturnSizePtr);
5936
+ else
5937
+ pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetAlloca,
5938
+ UnusedReturnSizePtr);
5939
+ }
5922
5940
5923
5941
llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr : getInvokeDest ();
5924
5942
0 commit comments