@@ -52,8 +52,8 @@ class AArch64ABIInfo : public ABIInfo {
5252
5353 bool isIllegalVectorType (QualType Ty) const ;
5454
55- bool isPureScalableType (QualType Ty, unsigned &NV, unsigned &NP,
56- SmallVectorImpl<llvm::Type *> &CoerceToSeq) const ;
55+ bool passAsPureScalableType (QualType Ty, unsigned &NV, unsigned &NP,
56+ SmallVectorImpl<llvm::Type *> &CoerceToSeq) const ;
5757
5858 void flattenType (llvm::Type *Ty,
5959 SmallVectorImpl<llvm::Type *> &Flattened) const ;
@@ -432,7 +432,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadic,
432432 if (Kind == AArch64ABIKind::AAPCS && !IsVariadic) {
433433 unsigned NVec = 0 , NPred = 0 ;
434434 SmallVector<llvm::Type *> UnpaddedCoerceToSeq;
435- if (isPureScalableType (Ty, NVec, NPred, UnpaddedCoerceToSeq) &&
435+ if (passAsPureScalableType (Ty, NVec, NPred, UnpaddedCoerceToSeq) &&
436436 (NVec + NPred) > 0 )
437437 return coerceAndExpandPureScalableAggregate (
438438 Ty, NVec, NPred, UnpaddedCoerceToSeq, NSRN, NPRN);
@@ -510,14 +510,14 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
510510 // Homogeneous Floating-point Aggregates (HFAs) are returned directly.
511511 return ABIArgInfo::getDirect ();
512512
513- // In AAPCS return values of a Pure Scalable type are treated is a first named
514- // argument and passed expanded in registers, or indirectly if there are not
515- // enough registers.
513+ // In AAPCS return values of a Pure Scalable type are treated as a single
514+ // named argument and passed expanded in registers, or indirectly if there are
515+ // not enough registers.
516516 if (Kind == AArch64ABIKind::AAPCS) {
517517 unsigned NSRN = 0 , NPRN = 0 ;
518518 unsigned NVec = 0 , NPred = 0 ;
519519 SmallVector<llvm::Type *> UnpaddedCoerceToSeq;
520- if (isPureScalableType (RetTy, NVec, NPred, UnpaddedCoerceToSeq) &&
520+ if (passAsPureScalableType (RetTy, NVec, NPred, UnpaddedCoerceToSeq) &&
521521 (NVec + NPred) > 0 )
522522 return coerceAndExpandPureScalableAggregate (
523523 RetTy, NVec, NPred, UnpaddedCoerceToSeq, NSRN, NPRN);
@@ -638,13 +638,15 @@ bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
638638 return true ;
639639}
640640
641- // Check if a type is a Pure Scalable Type as defined by AAPCS64. Return the
642- // number of data vectors and the number of predicate vectors in the types, into
643- // `NVec` and `NPred`, respectively. Upon return `CoerceToSeq` contains an
644- // expanded sequence of LLVM IR types, one element for each non-composite
645- // member. For practical purposes, limit the length of `CoerceToSeq` to about
646- // 12, the maximum size that could possibly fit in registers.
647- bool AArch64ABIInfo::isPureScalableType (
641+ // Check if a type needs to be passed in registers as a Pure Scalable Type (as
642+ // defined by AAPCS64). Return the number of data vectors and the number of
643+ // predicate vectors in the type, into `NVec` and `NPred`, respectively. Upon
644+ // return `CoerceToSeq` contains an expanded sequence of LLVM IR types, one
645+ // element for each non-composite member. For practical purposes, limit the
646+ // length of `CoerceToSeq` to about 12 (the maximum that could possibly fit
647+ // in registers) and return false, the effect of which will be to pass the
648+ // argument under the rules for a large (> 128 bytes) composite.
649+ bool AArch64ABIInfo::passAsPureScalableType (
648650 QualType Ty, unsigned &NVec, unsigned &NPred,
649651 SmallVectorImpl<llvm::Type *> &CoerceToSeq) const {
650652 if (const ConstantArrayType *AT = getContext ().getAsConstantArrayType (Ty)) {
@@ -654,10 +656,13 @@ bool AArch64ABIInfo::isPureScalableType(
654656
655657 unsigned NV = 0 , NP = 0 ;
656658 SmallVector<llvm::Type *> EltCoerceToSeq;
657- if (!isPureScalableType (AT->getElementType (), NV, NP, EltCoerceToSeq))
659+ if (!passAsPureScalableType (AT->getElementType (), NV, NP, EltCoerceToSeq))
658660 return false ;
659661
660- for (uint64_t I = 0 ; CoerceToSeq.size () < 12 && I < NElt; ++I)
662+ if (CoerceToSeq.size () + NElt * EltCoerceToSeq.size () > 12 )
663+ return false ;
664+
665+ for (uint64_t I = 0 ; I < NElt; ++I)
661666 llvm::copy (EltCoerceToSeq, std::back_inserter (CoerceToSeq));
662667
663668 NVec += NElt * NV;
@@ -676,22 +681,22 @@ bool AArch64ABIInfo::isPureScalableType(
676681 if (RD->isUnion ())
677682 return false ;
678683
679- // If this is a C++ record, check the bases bases .
684+ // If this is a C++ record, check the bases.
680685 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
681686 for (const auto &I : CXXRD->bases ()) {
682687 if (isEmptyRecord (getContext (), I.getType (), true ))
683688 continue ;
684- if (!isPureScalableType (I.getType (), NVec, NPred, CoerceToSeq))
689+ if (!passAsPureScalableType (I.getType (), NVec, NPred, CoerceToSeq))
685690 return false ;
686691 }
687692 }
688693
689694 // Check members.
690695 for (const auto *FD : RD->fields ()) {
691696 QualType FT = FD->getType ();
692- if (isEmptyRecord (getContext (), FT, true ))
697+ if (isEmptyField (getContext (), FD, /* AllowArrays */ true ))
693698 continue ;
694- if (!isPureScalableType (FT, NVec, NPred, CoerceToSeq))
699+ if (!passAsPureScalableType (FT, NVec, NPred, CoerceToSeq))
695700 return false ;
696701 }
697702
@@ -704,15 +709,17 @@ bool AArch64ABIInfo::isPureScalableType(
704709
705710 if (VT->getVectorKind () == VectorKind::SveFixedLengthPredicate) {
706711 ++NPred;
707- if (CoerceToSeq.size () < 12 )
708- CoerceToSeq.push_back (convertFixedToScalableVectorType (VT));
712+ if (CoerceToSeq.size () + 1 > 12 )
713+ return false ;
714+ CoerceToSeq.push_back (convertFixedToScalableVectorType (VT));
709715 return true ;
710716 }
711717
712718 if (VT->getVectorKind () == VectorKind::SveFixedLengthData) {
713719 ++NVec;
714- if (CoerceToSeq.size () < 12 )
715- CoerceToSeq.push_back (convertFixedToScalableVectorType (VT));
720+ if (CoerceToSeq.size () + 1 > 12 )
721+ return false ;
722+ CoerceToSeq.push_back (convertFixedToScalableVectorType (VT));
716723 return true ;
717724 }
718725
@@ -741,8 +748,9 @@ bool AArch64ABIInfo::isPureScalableType(
741748 auto VTy = llvm::ScalableVectorType::get (CGT.ConvertType (Info.ElementType ),
742749 Info.EC .getKnownMinValue ());
743750
744- if (CoerceToSeq.size () < 12 )
745- std::fill_n (std::back_inserter (CoerceToSeq), Info.NumVectors , VTy);
751+ if (CoerceToSeq.size () + Info.NumVectors > 12 )
752+ return false ;
753+ std::fill_n (std::back_inserter (CoerceToSeq), Info.NumVectors , VTy);
746754
747755 return true ;
748756}
@@ -784,7 +792,7 @@ RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
784792 CodeGenFunction &CGF, AArch64ABIKind Kind,
785793 AggValueSlot Slot) const {
786794 // These numbers are not used for variadic arguments, hence it doesn't matter
787- // they don't retain their values accross multiple calls to
795+ // they don't retain their values across multiple calls to
788796 // `classifyArgumentType` here.
789797 unsigned NSRN = 0 , NPRN = 0 ;
790798 ABIArgInfo AI =
0 commit comments