@@ -52,8 +52,8 @@ class AArch64ABIInfo : public ABIInfo {
52
52
53
53
bool isIllegalVectorType (QualType Ty) const ;
54
54
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 ;
57
57
58
58
void flattenType (llvm::Type *Ty,
59
59
SmallVectorImpl<llvm::Type *> &Flattened) const ;
@@ -432,7 +432,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadic,
432
432
if (Kind == AArch64ABIKind::AAPCS && !IsVariadic) {
433
433
unsigned NVec = 0 , NPred = 0 ;
434
434
SmallVector<llvm::Type *> UnpaddedCoerceToSeq;
435
- if (isPureScalableType (Ty, NVec, NPred, UnpaddedCoerceToSeq) &&
435
+ if (passAsPureScalableType (Ty, NVec, NPred, UnpaddedCoerceToSeq) &&
436
436
(NVec + NPred) > 0 )
437
437
return coerceAndExpandPureScalableAggregate (
438
438
Ty, NVec, NPred, UnpaddedCoerceToSeq, NSRN, NPRN);
@@ -510,14 +510,14 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
510
510
// Homogeneous Floating-point Aggregates (HFAs) are returned directly.
511
511
return ABIArgInfo::getDirect ();
512
512
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.
516
516
if (Kind == AArch64ABIKind::AAPCS) {
517
517
unsigned NSRN = 0 , NPRN = 0 ;
518
518
unsigned NVec = 0 , NPred = 0 ;
519
519
SmallVector<llvm::Type *> UnpaddedCoerceToSeq;
520
- if (isPureScalableType (RetTy, NVec, NPred, UnpaddedCoerceToSeq) &&
520
+ if (passAsPureScalableType (RetTy, NVec, NPred, UnpaddedCoerceToSeq) &&
521
521
(NVec + NPred) > 0 )
522
522
return coerceAndExpandPureScalableAggregate (
523
523
RetTy, NVec, NPred, UnpaddedCoerceToSeq, NSRN, NPRN);
@@ -638,13 +638,15 @@ bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
638
638
return true ;
639
639
}
640
640
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 (
648
650
QualType Ty, unsigned &NVec, unsigned &NPred,
649
651
SmallVectorImpl<llvm::Type *> &CoerceToSeq) const {
650
652
if (const ConstantArrayType *AT = getContext ().getAsConstantArrayType (Ty)) {
@@ -654,10 +656,13 @@ bool AArch64ABIInfo::isPureScalableType(
654
656
655
657
unsigned NV = 0 , NP = 0 ;
656
658
SmallVector<llvm::Type *> EltCoerceToSeq;
657
- if (!isPureScalableType (AT->getElementType (), NV, NP, EltCoerceToSeq))
659
+ if (!passAsPureScalableType (AT->getElementType (), NV, NP, EltCoerceToSeq))
658
660
return false ;
659
661
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)
661
666
llvm::copy (EltCoerceToSeq, std::back_inserter (CoerceToSeq));
662
667
663
668
NVec += NElt * NV;
@@ -676,22 +681,22 @@ bool AArch64ABIInfo::isPureScalableType(
676
681
if (RD->isUnion ())
677
682
return false ;
678
683
679
- // If this is a C++ record, check the bases bases .
684
+ // If this is a C++ record, check the bases.
680
685
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
681
686
for (const auto &I : CXXRD->bases ()) {
682
687
if (isEmptyRecord (getContext (), I.getType (), true ))
683
688
continue ;
684
- if (!isPureScalableType (I.getType (), NVec, NPred, CoerceToSeq))
689
+ if (!passAsPureScalableType (I.getType (), NVec, NPred, CoerceToSeq))
685
690
return false ;
686
691
}
687
692
}
688
693
689
694
// Check members.
690
695
for (const auto *FD : RD->fields ()) {
691
696
QualType FT = FD->getType ();
692
- if (isEmptyRecord (getContext (), FT, true ))
697
+ if (isEmptyField (getContext (), FD, /* AllowArrays */ true ))
693
698
continue ;
694
- if (!isPureScalableType (FT, NVec, NPred, CoerceToSeq))
699
+ if (!passAsPureScalableType (FT, NVec, NPred, CoerceToSeq))
695
700
return false ;
696
701
}
697
702
@@ -704,15 +709,17 @@ bool AArch64ABIInfo::isPureScalableType(
704
709
705
710
if (VT->getVectorKind () == VectorKind::SveFixedLengthPredicate) {
706
711
++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));
709
715
return true ;
710
716
}
711
717
712
718
if (VT->getVectorKind () == VectorKind::SveFixedLengthData) {
713
719
++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));
716
723
return true ;
717
724
}
718
725
@@ -741,8 +748,9 @@ bool AArch64ABIInfo::isPureScalableType(
741
748
auto VTy = llvm::ScalableVectorType::get (CGT.ConvertType (Info.ElementType ),
742
749
Info.EC .getKnownMinValue ());
743
750
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);
746
754
747
755
return true ;
748
756
}
@@ -784,7 +792,7 @@ RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
784
792
CodeGenFunction &CGF, AArch64ABIKind Kind,
785
793
AggValueSlot Slot) const {
786
794
// 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
788
796
// `classifyArgumentType` here.
789
797
unsigned NSRN = 0 , NPRN = 0 ;
790
798
ABIArgInfo AI =
0 commit comments