@@ -1410,6 +1410,30 @@ static Address emitAddressAtOffset(CodeGenFunction &CGF, Address addr,
14101410 return addr;
14111411}
14121412
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+
14131437namespace {
14141438
14151439// / Encapsulates information about the way function arguments from
@@ -3196,26 +3220,14 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
31963220 // a VLAT at the function boundary and the types match up, use
31973221 // llvm.vector.extract to convert back to the original VLST.
31983222 if (auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(ConvertType (Ty))) {
3199- llvm::Value *Coerced = Fn->getArg (FirstIRArg);
3223+ llvm::Value *ArgVal = Fn->getArg (FirstIRArg);
32003224 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) {
32153229 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));
32193231 break ;
32203232 }
32213233 }
@@ -3326,16 +3338,33 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
33263338 ArgVals.push_back (ParamValue::forIndirect (alloca));
33273339
33283340 auto coercionType = ArgI.getCoerceAndExpandType ();
3341+ auto unpaddedCoercionType = ArgI.getUnpaddedCoerceAndExpandType ();
3342+ auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
3343+
33293344 alloca = alloca.withElementType (coercionType);
33303345
33313346 unsigned argIndex = FirstIRArg;
3347+ unsigned unpaddedIndex = 0 ;
33323348 for (unsigned i = 0 , e = coercionType->getNumElements (); i != e; ++i) {
33333349 llvm::Type *eltType = coercionType->getElementType (i);
33343350 if (ABIArgInfo::isPaddingForCoerceAndExpand (eltType))
33353351 continue ;
33363352
33373353 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+ }
33393368 Builder.CreateStore (elt, eltAddr);
33403369 }
33413370 assert (argIndex == FirstIRArg + NumIRArgs);
@@ -3930,17 +3959,24 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
39303959
39313960 case ABIArgInfo::CoerceAndExpand: {
39323961 auto coercionType = RetAI.getCoerceAndExpandType ();
3962+ auto unpaddedCoercionType = RetAI.getUnpaddedCoerceAndExpandType ();
3963+ auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
39333964
39343965 // Load all of the coerced elements out into results.
39353966 llvm::SmallVector<llvm::Value*, 4 > results;
39363967 Address addr = ReturnValue.withElementType (coercionType);
3968+ unsigned unpaddedIndex = 0 ;
39373969 for (unsigned i = 0 , e = coercionType->getNumElements (); i != e; ++i) {
39383970 auto coercedEltType = coercionType->getElementType (i);
39393971 if (ABIArgInfo::isPaddingForCoerceAndExpand (coercedEltType))
39403972 continue ;
39413973
39423974 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 );
39443980 results.push_back (elt);
39453981 }
39463982
@@ -5472,6 +5508,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
54725508 case ABIArgInfo::CoerceAndExpand: {
54735509 auto coercionType = ArgInfo.getCoerceAndExpandType ();
54745510 auto layout = CGM.getDataLayout ().getStructLayout (coercionType);
5511+ auto unpaddedCoercionType = ArgInfo.getUnpaddedCoerceAndExpandType ();
5512+ auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
54755513
54765514 llvm::Value *tempSize = nullptr ;
54775515 Address addr = Address::invalid ();
@@ -5502,11 +5540,16 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
55025540 addr = addr.withElementType (coercionType);
55035541
55045542 unsigned IRArgPos = FirstIRArg;
5543+ unsigned unpaddedIndex = 0 ;
55055544 for (unsigned i = 0 , e = coercionType->getNumElements (); i != e; ++i) {
55065545 llvm::Type *eltType = coercionType->getElementType (i);
55075546 if (ABIArgInfo::isPaddingForCoerceAndExpand (eltType)) continue ;
55085547 Address eltAddr = Builder.CreateStructGEP (addr, i);
5509- llvm::Value *elt = Builder.CreateLoad (eltAddr);
5548+ llvm::Value *elt = CreateCoercedLoad (
5549+ eltAddr,
5550+ unpaddedStruct ? unpaddedStruct->getElementType (unpaddedIndex++)
5551+ : unpaddedCoercionType,
5552+ *this );
55105553 if (ArgHasMaybeUndefAttr)
55115554 elt = Builder.CreateFreeze (elt);
55125555 IRCallArgs[IRArgPos++] = elt;
0 commit comments