@@ -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
@@ -3309,7 +3284,12 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
3309
3284
assert (NumIRArgs == 1 );
3310
3285
auto AI = Fn->getArg (FirstIRArg);
3311
3286
AI->setName (Arg->getName () + " .coerce" );
3312
- CreateCoercedStore (AI, Ptr, /* DstIsVolatile=*/ false , *this );
3287
+ CreateCoercedStore (
3288
+ AI, Ptr,
3289
+ llvm::TypeSize::getFixed (
3290
+ getContext ().getTypeSizeInChars (Ty).getQuantity () -
3291
+ ArgI.getDirectOffset ()),
3292
+ /* DstIsVolatile=*/ false );
3313
3293
}
3314
3294
3315
3295
// Match to what EmitParmDecl is expecting for this type.
@@ -5939,17 +5919,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5939
5919
llvm::Value *Imag = Builder.CreateExtractValue (CI, 1 );
5940
5920
return RValue::getComplex (std::make_pair (Real, Imag));
5941
5921
}
5942
- case TEK_Aggregate: {
5943
- Address DestPtr = ReturnValue.getAddress ();
5944
- bool DestIsVolatile = ReturnValue.isVolatile ();
5945
-
5946
- if (!DestPtr.isValid ()) {
5947
- DestPtr = CreateMemTemp (RetTy, " agg.tmp" );
5948
- DestIsVolatile = false ;
5949
- }
5950
- EmitAggregateStore (CI, DestPtr, DestIsVolatile);
5951
- return RValue::getAggregate (DestPtr);
5952
- }
5922
+ case TEK_Aggregate:
5923
+ break ;
5953
5924
case TEK_Scalar: {
5954
5925
// If the argument doesn't match, perform a bitcast to coerce it.
5955
5926
// This can happen due to trivial type mismatches.
@@ -5959,7 +5930,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5959
5930
return RValue::get (V);
5960
5931
}
5961
5932
}
5962
- llvm_unreachable (" bad evaluation kind" );
5963
5933
}
5964
5934
5965
5935
// If coercing a fixed vector from a scalable vector for ABI
@@ -5981,10 +5951,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5981
5951
5982
5952
Address DestPtr = ReturnValue.getValue ();
5983
5953
bool DestIsVolatile = ReturnValue.isVolatile ();
5954
+ uint64_t DestSize =
5955
+ getContext ().getTypeInfoDataSizeInChars (RetTy).Width .getQuantity ();
5984
5956
5985
5957
if (!DestPtr.isValid ()) {
5986
5958
DestPtr = CreateMemTemp (RetTy, " coerce" );
5987
5959
DestIsVolatile = false ;
5960
+ DestSize = getContext ().getTypeSizeInChars (RetTy).getQuantity ();
5988
5961
}
5989
5962
5990
5963
// An empty record can overlap other data (if declared with
@@ -5993,7 +5966,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5993
5966
if (!isEmptyRecord (getContext (), RetTy, true )) {
5994
5967
// If the value is offset in memory, apply the offset now.
5995
5968
Address StorePtr = emitAddressAtOffset (*this , DestPtr, RetAI);
5996
- CreateCoercedStore (CI, StorePtr, DestIsVolatile, *this );
5969
+ CreateCoercedStore (
5970
+ CI, StorePtr,
5971
+ llvm::TypeSize::getFixed (DestSize - RetAI.getDirectOffset ()),
5972
+ DestIsVolatile);
5997
5973
}
5998
5974
5999
5975
return convertTempToRValue (DestPtr, RetTy, SourceLocation ());
0 commit comments