@@ -1336,75 +1336,50 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
1336
1336
return CGF.Builder .CreateLoad (Tmp);
1337
1337
}
1338
1338
1339
- // Function to store a first-class aggregate into memory. We prefer to
1340
- // store the elements rather than the aggregate to be more friendly to
1341
- // fast-isel.
1342
- // FIXME: Do we need to recurse here?
1343
- void CodeGenFunction::EmitAggregateStore (llvm::Value *Val, Address Dest,
1344
- bool DestIsVolatile) {
1345
- // Prefer scalar stores to first-class aggregate stores.
1346
- if (llvm::StructType *STy = dyn_cast<llvm::StructType>(Val->getType ())) {
1347
- for (unsigned i = 0 , e = STy->getNumElements (); i != e; ++i) {
1348
- Address EltPtr = Builder.CreateStructGEP (Dest, i);
1349
- llvm::Value *Elt = Builder.CreateExtractValue (Val, i);
1350
- Builder.CreateStore (Elt, EltPtr, DestIsVolatile);
1351
- }
1352
- } else {
1353
- Builder.CreateStore (Val, Dest, DestIsVolatile);
1354
- }
1355
- }
1356
-
1357
- // / CreateCoercedStore - Create a store to \arg DstPtr from \arg Src,
1358
- // / where the source and destination may have different types. The
1359
- // / destination is known to be aligned to \arg DstAlign bytes.
1360
- // /
1361
- // / This safely handles the case when the src type is larger than the
1362
- // / destination type; the upper bits of the src will be lost.
1363
- static void CreateCoercedStore (llvm::Value *Src,
1364
- Address Dst,
1365
- bool DstIsVolatile,
1366
- CodeGenFunction &CGF) {
1367
- llvm::Type *SrcTy = Src->getType ();
1368
- llvm::Type *DstTy = Dst.getElementType ();
1369
- if (SrcTy == DstTy) {
1370
- CGF.Builder .CreateStore (Src, Dst, DstIsVolatile);
1371
- return ;
1372
- }
1373
-
1374
- llvm::TypeSize SrcSize = CGF.CGM .getDataLayout ().getTypeAllocSize (SrcTy);
1375
-
1376
- if (llvm::StructType *DstSTy = dyn_cast<llvm::StructType>(DstTy)) {
1377
- Dst = EnterStructPointerForCoercedAccess (Dst, DstSTy,
1378
- SrcSize.getFixedValue (), CGF);
1379
- DstTy = Dst.getElementType ();
1380
- }
1381
-
1382
- llvm::PointerType *SrcPtrTy = llvm::dyn_cast<llvm::PointerType>(SrcTy);
1383
- llvm::PointerType *DstPtrTy = llvm::dyn_cast<llvm::PointerType>(DstTy);
1384
- if (SrcPtrTy && DstPtrTy &&
1385
- SrcPtrTy->getAddressSpace () != DstPtrTy->getAddressSpace ()) {
1386
- Src = CGF.Builder .CreateAddrSpaceCast (Src, DstTy);
1387
- CGF.Builder .CreateStore (Src, Dst, DstIsVolatile);
1339
+ void CodeGenFunction::CreateCoercedStore (llvm::Value *Src, Address Dst,
1340
+ llvm::TypeSize DstSize,
1341
+ bool DstIsVolatile) {
1342
+ if (!DstSize)
1388
1343
return ;
1389
- }
1390
1344
1391
- // If the source and destination are integer or pointer types, just do an
1392
- // extension or truncation to the desired type.
1393
- if ((isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy)) &&
1394
- (isa<llvm::IntegerType>(DstTy) || isa<llvm::PointerType>(DstTy))) {
1395
- Src = CoerceIntOrPtrToIntOrPtr (Src, DstTy, CGF);
1396
- CGF.Builder .CreateStore (Src, Dst, DstIsVolatile);
1397
- return ;
1345
+ llvm::Type *SrcTy = Src->getType ();
1346
+ llvm::TypeSize SrcSize = CGM.getDataLayout ().getTypeAllocSize (SrcTy);
1347
+
1348
+ // GEP into structs to try to make types match.
1349
+ // FIXME: This isn't really that useful with opaque types, but it impacts a
1350
+ // lot of regression tests.
1351
+ if (SrcTy != Dst.getElementType ()) {
1352
+ if (llvm::StructType *DstSTy =
1353
+ dyn_cast<llvm::StructType>(Dst.getElementType ())) {
1354
+ assert (!SrcSize.isScalable ());
1355
+ Dst = EnterStructPointerForCoercedAccess (Dst, DstSTy,
1356
+ SrcSize.getFixedValue (), *this );
1357
+ }
1398
1358
}
1399
1359
1400
- llvm::TypeSize DstSize = CGF.CGM .getDataLayout ().getTypeAllocSize (DstTy);
1401
-
1402
- // If store is legal, just bitcast the src pointer.
1403
- if (isa<llvm::ScalableVectorType>(SrcTy) ||
1404
- isa<llvm::ScalableVectorType>(DstTy) ||
1405
- SrcSize.getFixedValue () <= DstSize.getFixedValue ()) {
1406
- Dst = Dst.withElementType (SrcTy);
1407
- CGF.EmitAggregateStore (Src, Dst, DstIsVolatile);
1360
+ if (SrcSize.isScalable () || SrcSize <= DstSize) {
1361
+ if (SrcTy->isIntegerTy () && Dst.getElementType ()->isPointerTy () &&
1362
+ SrcSize == CGM.getDataLayout ().getTypeAllocSize (Dst.getElementType ())) {
1363
+ // If the value is supposed to be a pointer, convert it before storing it.
1364
+ Src = CoerceIntOrPtrToIntOrPtr (Src, Dst.getElementType (), *this );
1365
+ Builder.CreateStore (Src, Dst, DstIsVolatile);
1366
+ } else if (llvm::StructType *STy =
1367
+ dyn_cast<llvm::StructType>(Src->getType ())) {
1368
+ // Prefer scalar stores to first-class aggregate stores.
1369
+ Dst = Dst.withElementType (SrcTy);
1370
+ for (unsigned i = 0 , e = STy->getNumElements (); i != e; ++i) {
1371
+ Address EltPtr = Builder.CreateStructGEP (Dst, i);
1372
+ llvm::Value *Elt = Builder.CreateExtractValue (Src, i);
1373
+ Builder.CreateStore (Elt, EltPtr, DstIsVolatile);
1374
+ }
1375
+ } else {
1376
+ Builder.CreateStore (Src, Dst.withElementType (SrcTy), DstIsVolatile);
1377
+ }
1378
+ } else if (SrcTy->isIntegerTy ()) {
1379
+ // If the source is a simple integer, coerce it directly.
1380
+ llvm::Type *DstIntTy = Builder.getIntNTy (DstSize.getFixedValue () * 8 );
1381
+ Src = CoerceIntOrPtrToIntOrPtr (Src, DstIntTy, *this );
1382
+ Builder.CreateStore (Src, Dst.withElementType (DstIntTy), DstIsVolatile);
1408
1383
} else {
1409
1384
// Otherwise do coercion through memory. This is stupid, but
1410
1385
// simple.
@@ -1416,12 +1391,12 @@ static void CreateCoercedStore(llvm::Value *Src,
1416
1391
// FIXME: Assert that we aren't truncating non-padding bits when have access
1417
1392
// to that information.
1418
1393
RawAddress Tmp =
1419
- CreateTempAllocaForCoercion (CGF , SrcTy, Dst.getAlignment ());
1420
- CGF. Builder .CreateStore (Src, Tmp);
1421
- CGF. Builder .CreateMemCpy (
1422
- Dst. emitRawPointer (CGF), Dst.getAlignment ().getAsAlign (),
1423
- Tmp. getPointer (), Tmp.getAlignment ().getAsAlign (),
1424
- llvm::ConstantInt::get (CGF. IntPtrTy , DstSize. getFixedValue () ));
1394
+ CreateTempAllocaForCoercion (* this , SrcTy, Dst.getAlignment ());
1395
+ Builder.CreateStore (Src, Tmp);
1396
+ Builder.CreateMemCpy (Dst. emitRawPointer (* this ),
1397
+ Dst.getAlignment ().getAsAlign (), Tmp. getPointer (),
1398
+ Tmp.getAlignment ().getAsAlign (),
1399
+ Builder. CreateTypeSize ( IntPtrTy, DstSize));
1425
1400
}
1426
1401
}
1427
1402
@@ -3315,7 +3290,12 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
3315
3290
assert (NumIRArgs == 1 );
3316
3291
auto AI = Fn->getArg (FirstIRArg);
3317
3292
AI->setName (Arg->getName () + " .coerce" );
3318
- CreateCoercedStore (AI, Ptr, /* DstIsVolatile=*/ false , *this );
3293
+ CreateCoercedStore (
3294
+ AI, Ptr,
3295
+ llvm::TypeSize::getFixed (
3296
+ getContext ().getTypeSizeInChars (Ty).getQuantity () -
3297
+ ArgI.getDirectOffset ()),
3298
+ /* DstIsVolatile=*/ false );
3319
3299
}
3320
3300
3321
3301
// Match to what EmitParmDecl is expecting for this type.
@@ -5950,17 +5930,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5950
5930
llvm::Value *Imag = Builder.CreateExtractValue (CI, 1 );
5951
5931
return RValue::getComplex (std::make_pair (Real, Imag));
5952
5932
}
5953
- case TEK_Aggregate: {
5954
- Address DestPtr = ReturnValue.getAddress ();
5955
- bool DestIsVolatile = ReturnValue.isVolatile ();
5956
-
5957
- if (!DestPtr.isValid ()) {
5958
- DestPtr = CreateMemTemp (RetTy, " agg.tmp" );
5959
- DestIsVolatile = false ;
5960
- }
5961
- EmitAggregateStore (CI, DestPtr, DestIsVolatile);
5962
- return RValue::getAggregate (DestPtr);
5963
- }
5933
+ case TEK_Aggregate:
5934
+ break ;
5964
5935
case TEK_Scalar: {
5965
5936
// If the argument doesn't match, perform a bitcast to coerce it.
5966
5937
// This can happen due to trivial type mismatches.
@@ -5970,7 +5941,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5970
5941
return RValue::get (V);
5971
5942
}
5972
5943
}
5973
- llvm_unreachable (" bad evaluation kind" );
5974
5944
}
5975
5945
5976
5946
// If coercing a fixed vector from a scalable vector for ABI
@@ -5992,10 +5962,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5992
5962
5993
5963
Address DestPtr = ReturnValue.getValue ();
5994
5964
bool DestIsVolatile = ReturnValue.isVolatile ();
5965
+ uint64_t DestSize =
5966
+ getContext ().getTypeInfoDataSizeInChars (RetTy).Width .getQuantity ();
5995
5967
5996
5968
if (!DestPtr.isValid ()) {
5997
5969
DestPtr = CreateMemTemp (RetTy, " coerce" );
5998
5970
DestIsVolatile = false ;
5971
+ DestSize = getContext ().getTypeSizeInChars (RetTy).getQuantity ();
5999
5972
}
6000
5973
6001
5974
// An empty record can overlap other data (if declared with
@@ -6004,7 +5977,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
6004
5977
if (!isEmptyRecord (getContext (), RetTy, true )) {
6005
5978
// If the value is offset in memory, apply the offset now.
6006
5979
Address StorePtr = emitAddressAtOffset (*this , DestPtr, RetAI);
6007
- CreateCoercedStore (CI, StorePtr, DestIsVolatile, *this );
5980
+ CreateCoercedStore (
5981
+ CI, StorePtr,
5982
+ llvm::TypeSize::getFixed (DestSize - RetAI.getDirectOffset ()),
5983
+ DestIsVolatile);
6008
5984
}
6009
5985
6010
5986
return convertTempToRValue (DestPtr, RetTy, SourceLocation ());
0 commit comments