@@ -1410,6 +1410,30 @@ static Address emitAddressAtOffset(CodeGenFunction &CGF, Address addr,
1410
1410
return addr;
1411
1411
}
1412
1412
1413
+ static std::pair<llvm::Value *, bool >
1414
+ CoerceScalableToFixed (CodeGenFunction &CGF, llvm::FixedVectorType *ToTy,
1415
+ llvm::ScalableVectorType *FromTy, llvm::Value *V,
1416
+ StringRef Name = " " ) {
1417
+ // If we are casting a scalable i1 predicate vector to a fixed i8
1418
+ // vector, first bitcast the source.
1419
+ if (FromTy->getElementType ()->isIntegerTy (1 ) &&
1420
+ FromTy->getElementCount ().isKnownMultipleOf (8 ) &&
1421
+ ToTy->getElementType () == CGF.Builder .getInt8Ty ()) {
1422
+ FromTy = llvm::ScalableVectorType::get (
1423
+ ToTy->getElementType (),
1424
+ FromTy->getElementCount ().getKnownMinValue () / 8 );
1425
+ V = CGF.Builder .CreateBitCast (V, FromTy);
1426
+ }
1427
+ if (FromTy->getElementType () == ToTy->getElementType ()) {
1428
+ llvm::Value *Zero = llvm::Constant::getNullValue (CGF.CGM .Int64Ty );
1429
+
1430
+ V->setName (Name + " .coerce" );
1431
+ V = CGF.Builder .CreateExtractVector (ToTy, V, Zero, " cast.fixed" );
1432
+ return {V, true };
1433
+ }
1434
+ return {V, false };
1435
+ }
1436
+
1413
1437
namespace {
1414
1438
1415
1439
// / Encapsulates information about the way function arguments from
@@ -3196,26 +3220,14 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
3196
3220
// a VLAT at the function boundary and the types match up, use
3197
3221
// llvm.vector.extract to convert back to the original VLST.
3198
3222
if (auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(ConvertType (Ty))) {
3199
- llvm::Value *Coerced = Fn->getArg (FirstIRArg);
3223
+ llvm::Value *ArgVal = Fn->getArg (FirstIRArg);
3200
3224
if (auto *VecTyFrom =
3201
- dyn_cast<llvm::ScalableVectorType>(Coerced->getType ())) {
3202
- // If we are casting a scalable i1 predicate vector to a fixed i8
3203
- // vector, bitcast the source and use a vector extract.
3204
- if (VecTyFrom->getElementType ()->isIntegerTy (1 ) &&
3205
- VecTyFrom->getElementCount ().isKnownMultipleOf (8 ) &&
3206
- VecTyTo->getElementType () == Builder.getInt8Ty ()) {
3207
- VecTyFrom = llvm::ScalableVectorType::get (
3208
- VecTyTo->getElementType (),
3209
- VecTyFrom->getElementCount ().getKnownMinValue () / 8 );
3210
- Coerced = Builder.CreateBitCast (Coerced, VecTyFrom);
3211
- }
3212
- if (VecTyFrom->getElementType () == VecTyTo->getElementType ()) {
3213
- llvm::Value *Zero = llvm::Constant::getNullValue (CGM.Int64Ty );
3214
-
3225
+ dyn_cast<llvm::ScalableVectorType>(ArgVal->getType ())) {
3226
+ auto [Coerced, Extracted] = CoerceScalableToFixed (
3227
+ *this , VecTyTo, VecTyFrom, ArgVal, Arg->getName ());
3228
+ if (Extracted) {
3215
3229
assert (NumIRArgs == 1 );
3216
- Coerced->setName (Arg->getName () + " .coerce" );
3217
- ArgVals.push_back (ParamValue::forDirect (Builder.CreateExtractVector (
3218
- VecTyTo, Coerced, Zero, " cast.fixed" )));
3230
+ ArgVals.push_back (ParamValue::forDirect (Coerced));
3219
3231
break ;
3220
3232
}
3221
3233
}
@@ -3326,16 +3338,33 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
3326
3338
ArgVals.push_back (ParamValue::forIndirect (alloca ));
3327
3339
3328
3340
auto coercionType = ArgI.getCoerceAndExpandType ();
3341
+ auto unpaddedCoercionType = ArgI.getUnpaddedCoerceAndExpandType ();
3342
+ auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
3343
+
3329
3344
alloca = alloca .withElementType (coercionType);
3330
3345
3331
3346
unsigned argIndex = FirstIRArg;
3347
+ unsigned unpaddedIndex = 0 ;
3332
3348
for (unsigned i = 0 , e = coercionType->getNumElements (); i != e; ++i) {
3333
3349
llvm::Type *eltType = coercionType->getElementType (i);
3334
3350
if (ABIArgInfo::isPaddingForCoerceAndExpand (eltType))
3335
3351
continue ;
3336
3352
3337
3353
auto eltAddr = Builder.CreateStructGEP (alloca , i);
3338
- auto elt = Fn->getArg (argIndex++);
3354
+ llvm::Value *elt = Fn->getArg (argIndex++);
3355
+
3356
+ auto paramType = unpaddedStruct
3357
+ ? unpaddedStruct->getElementType (unpaddedIndex++)
3358
+ : unpaddedCoercionType;
3359
+
3360
+ if (auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(eltType)) {
3361
+ if (auto *VecTyFrom = dyn_cast<llvm::ScalableVectorType>(paramType)) {
3362
+ bool Extracted;
3363
+ std::tie (elt, Extracted) = CoerceScalableToFixed (
3364
+ *this , VecTyTo, VecTyFrom, elt, elt->getName ());
3365
+ assert (Extracted && " Unexpected scalable to fixed vector coercion" );
3366
+ }
3367
+ }
3339
3368
Builder.CreateStore (elt, eltAddr);
3340
3369
}
3341
3370
assert (argIndex == FirstIRArg + NumIRArgs);
@@ -3930,17 +3959,24 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
3930
3959
3931
3960
case ABIArgInfo::CoerceAndExpand: {
3932
3961
auto coercionType = RetAI.getCoerceAndExpandType ();
3962
+ auto unpaddedCoercionType = RetAI.getUnpaddedCoerceAndExpandType ();
3963
+ auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
3933
3964
3934
3965
// Load all of the coerced elements out into results.
3935
3966
llvm::SmallVector<llvm::Value*, 4 > results;
3936
3967
Address addr = ReturnValue.withElementType (coercionType);
3968
+ unsigned unpaddedIndex = 0 ;
3937
3969
for (unsigned i = 0 , e = coercionType->getNumElements (); i != e; ++i) {
3938
3970
auto coercedEltType = coercionType->getElementType (i);
3939
3971
if (ABIArgInfo::isPaddingForCoerceAndExpand (coercedEltType))
3940
3972
continue ;
3941
3973
3942
3974
auto eltAddr = Builder.CreateStructGEP (addr, i);
3943
- auto elt = Builder.CreateLoad (eltAddr);
3975
+ llvm::Value *elt = CreateCoercedLoad (
3976
+ eltAddr,
3977
+ unpaddedStruct ? unpaddedStruct->getElementType (unpaddedIndex++)
3978
+ : unpaddedCoercionType,
3979
+ *this );
3944
3980
results.push_back (elt);
3945
3981
}
3946
3982
@@ -5468,6 +5504,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5468
5504
case ABIArgInfo::CoerceAndExpand: {
5469
5505
auto coercionType = ArgInfo.getCoerceAndExpandType ();
5470
5506
auto layout = CGM.getDataLayout ().getStructLayout (coercionType);
5507
+ auto unpaddedCoercionType = ArgInfo.getUnpaddedCoerceAndExpandType ();
5508
+ auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
5471
5509
5472
5510
llvm::Value *tempSize = nullptr ;
5473
5511
Address addr = Address::invalid ();
@@ -5498,11 +5536,16 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5498
5536
addr = addr.withElementType (coercionType);
5499
5537
5500
5538
unsigned IRArgPos = FirstIRArg;
5539
+ unsigned unpaddedIndex = 0 ;
5501
5540
for (unsigned i = 0 , e = coercionType->getNumElements (); i != e; ++i) {
5502
5541
llvm::Type *eltType = coercionType->getElementType (i);
5503
5542
if (ABIArgInfo::isPaddingForCoerceAndExpand (eltType)) continue ;
5504
5543
Address eltAddr = Builder.CreateStructGEP (addr, i);
5505
- llvm::Value *elt = Builder.CreateLoad (eltAddr);
5544
+ llvm::Value *elt = CreateCoercedLoad (
5545
+ eltAddr,
5546
+ unpaddedStruct ? unpaddedStruct->getElementType (unpaddedIndex++)
5547
+ : unpaddedCoercionType,
5548
+ *this );
5506
5549
if (ArgHasMaybeUndefAttr)
5507
5550
elt = Builder.CreateFreeze (elt);
5508
5551
IRCallArgs[IRArgPos++] = elt;
0 commit comments