@@ -1672,10 +1672,8 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
16721672
16731673 // Add type for sret argument.
16741674 if (IRFunctionArgs.hasSRetArg ()) {
1675- QualType Ret = FI.getReturnType ();
1676- unsigned AddressSpace = CGM.getTypes ().getTargetAddressSpace (Ret);
1677- ArgTypes[IRFunctionArgs.getSRetArgNo ()] =
1678- llvm::PointerType::get (getLLVMContext (), AddressSpace);
1675+ ArgTypes[IRFunctionArgs.getSRetArgNo ()] = llvm::PointerType::get (
1676+ getLLVMContext (), FI.getReturnInfo ().getIndirectAddrSpace ());
16791677 }
16801678
16811679 // Add type for inalloca argument.
@@ -5159,7 +5157,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
51595157 // If the call returns a temporary with struct return, create a temporary
51605158 // alloca to hold the result, unless one is given to us.
51615159 Address SRetPtr = Address::invalid ();
5162- RawAddress SRetAlloca = RawAddress::invalid ();
51635160 llvm::Value *UnusedReturnSizePtr = nullptr ;
51645161 if (RetAI.isIndirect () || RetAI.isInAlloca () || RetAI.isCoerceAndExpand ()) {
51655162 // For virtual function pointer thunks and musttail calls, we must always
@@ -5173,14 +5170,29 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
51735170 } else if (!ReturnValue.isNull ()) {
51745171 SRetPtr = ReturnValue.getAddress ();
51755172 } else {
5176- SRetPtr = CreateMemTemp (RetTy, " tmp" , &SRetAlloca );
5173+ SRetPtr = CreateMemTempWithoutCast (RetTy, " tmp" );
51775174 if (HaveInsertPoint () && ReturnValue.isUnused ()) {
51785175 llvm::TypeSize size =
51795176 CGM.getDataLayout ().getTypeAllocSize (ConvertTypeForMem (RetTy));
5180- UnusedReturnSizePtr = EmitLifetimeStart (size, SRetAlloca. getPointer ());
5177+ UnusedReturnSizePtr = EmitLifetimeStart (size, SRetPtr. getBasePointer ());
51815178 }
51825179 }
51835180 if (IRFunctionArgs.hasSRetArg ()) {
5181+ // A mismatch between the allocated return value's AS and the target's
5182+ // chosen IndirectAS can happen e.g. when passing the this pointer through
5183+ // a chain involving stores to / loads from the DefaultAS; we address this
5184+ // here, symmetrically with the handling we have for normal pointer args.
5185+ if (SRetPtr.getAddressSpace () != RetAI.getIndirectAddrSpace ()) {
5186+ llvm::Value *V = SRetPtr.getBasePointer ();
5187+ LangAS SAS = getLangASFromTargetAS (SRetPtr.getAddressSpace ());
5188+ LangAS DAS = getLangASFromTargetAS (RetAI.getIndirectAddrSpace ());
5189+ llvm::Type *Ty = llvm::PointerType::get (getLLVMContext (),
5190+ RetAI.getIndirectAddrSpace ());
5191+
5192+ SRetPtr = SRetPtr.withPointer (
5193+ getTargetHooks ().performAddrSpaceCast (*this , V, SAS, DAS, Ty, true ),
5194+ SRetPtr.isKnownNonNull ());
5195+ }
51845196 IRCallArgs[IRFunctionArgs.getSRetArgNo ()] =
51855197 getAsNaturalPointerTo (SRetPtr, RetTy);
51865198 } else if (RetAI.isInAlloca ()) {
@@ -5412,11 +5424,20 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
54125424 V->getType ()->isIntegerTy ())
54135425 V = Builder.CreateZExt (V, ArgInfo.getCoerceToType ());
54145426
5415- // If the argument doesn't match, perform a bitcast to coerce it. This
5416- // can happen due to trivial type mismatches.
5427+ // The only plausible mismatch here would be for pointer address spaces.
5428+ // We assume that the target has a reasonable mapping for the DefaultAS
5429+ // (it can be casted to from incoming specific ASes), and insert an AS
5430+ // cast to address the mismatch.
54175431 if (FirstIRArg < IRFuncTy->getNumParams () &&
5418- V->getType () != IRFuncTy->getParamType (FirstIRArg))
5419- V = Builder.CreateBitCast (V, IRFuncTy->getParamType (FirstIRArg));
5432+ V->getType () != IRFuncTy->getParamType (FirstIRArg)) {
5433+ assert (V->getType ()->isPointerTy () && " Only pointers can mismatch!" );
5434+ auto FormalAS = CallInfo.arguments ()[ArgNo]
5435+ .type .getQualifiers ()
5436+ .getAddressSpace ();
5437+ auto ActualAS = I->Ty .getAddressSpace ();
5438+ V = getTargetHooks ().performAddrSpaceCast (
5439+ *this , V, ActualAS, FormalAS, IRFuncTy->getParamType (FirstIRArg));
5440+ }
54205441
54215442 if (ArgHasMaybeUndefAttr)
54225443 V = Builder.CreateFreeze (V);
@@ -5736,7 +5757,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
57365757 // pop this cleanup later on. Being eager about this is OK, since this
57375758 // temporary is 'invisible' outside of the callee.
57385759 if (UnusedReturnSizePtr)
5739- pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetAlloca ,
5760+ pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetPtr ,
57405761 UnusedReturnSizePtr);
57415762
57425763 llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr : getInvokeDest ();
0 commit comments