@@ -52,6 +52,7 @@ class AArch64ABIInfo : public ABIInfo {
52
52
53
53
bool isIllegalVectorType (QualType Ty) const ;
54
54
55
+ bool passAsAggregateType (QualType Ty) const ;
55
56
bool passAsPureScalableType (QualType Ty, unsigned &NV, unsigned &NP,
56
57
SmallVectorImpl<llvm::Type *> &CoerceToSeq) const ;
57
58
@@ -337,6 +338,10 @@ ABIArgInfo AArch64ABIInfo::coerceAndExpandPureScalableAggregate(
337
338
NSRN += NVec;
338
339
NPRN += NPred;
339
340
341
+ // Handle SVE vector tuples.
342
+ if (Ty->isSVESizelessBuiltinType ())
343
+ return ABIArgInfo::getDirect ();
344
+
340
345
llvm::Type *UnpaddedCoerceToType =
341
346
UnpaddedCoerceToSeq.size () == 1
342
347
? UnpaddedCoerceToSeq[0 ]
@@ -362,7 +367,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn,
362
367
if (isIllegalVectorType (Ty))
363
368
return coerceIllegalVector (Ty, NSRN, NPRN);
364
369
365
- if (!isAggregateTypeForABI (Ty)) {
370
+ if (!passAsAggregateType (Ty)) {
366
371
// Treat an enum type as its underlying type.
367
372
if (const EnumType *EnumTy = Ty->getAs <EnumType>())
368
373
Ty = EnumTy->getDecl ()->getIntegerType ();
@@ -417,7 +422,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn,
417
422
// elsewhere for GNU compatibility.
418
423
uint64_t Size = getContext ().getTypeSize (Ty);
419
424
bool IsEmpty = isEmptyRecord (getContext (), Ty, true );
420
- if (IsEmpty || Size == 0 ) {
425
+ if (!Ty-> isSVESizelessBuiltinType () && ( IsEmpty || Size == 0 ) ) {
421
426
if (!getContext ().getLangOpts ().CPlusPlus || isDarwinPCS ())
422
427
return ABIArgInfo::getIgnore ();
423
428
@@ -504,7 +509,7 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
504
509
if (RetTy->isVectorType () && getContext ().getTypeSize (RetTy) > 128 )
505
510
return getNaturalAlignIndirect (RetTy);
506
511
507
- if (!isAggregateTypeForABI (RetTy)) {
512
+ if (!passAsAggregateType (RetTy)) {
508
513
// Treat an enum type as its underlying type.
509
514
if (const EnumType *EnumTy = RetTy->getAs <EnumType>())
510
515
RetTy = EnumTy->getDecl ()->getIntegerType ();
@@ -519,7 +524,8 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
519
524
}
520
525
521
526
uint64_t Size = getContext ().getTypeSize (RetTy);
522
- if (isEmptyRecord (getContext (), RetTy, true ) || Size == 0 )
527
+ if (!RetTy->isSVESizelessBuiltinType () &&
528
+ (isEmptyRecord (getContext (), RetTy, true ) || Size == 0 ))
523
529
return ABIArgInfo::getIgnore ();
524
530
525
531
const Type *Base = nullptr ;
@@ -654,6 +660,15 @@ bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
654
660
return true ;
655
661
}
656
662
663
+ bool AArch64ABIInfo::passAsAggregateType (QualType Ty) const {
664
+ if (Kind == AArch64ABIKind::AAPCS && Ty->isSVESizelessBuiltinType ()) {
665
+ const auto *BT = Ty->getAs <BuiltinType>();
666
+ return !BT->isSVECount () &&
667
+ getContext ().getBuiltinVectorTypeInfo (BT).NumVectors > 1 ;
668
+ }
669
+ return isAggregateTypeForABI (Ty);
670
+ }
671
+
657
672
// Check if a type needs to be passed in registers as a Pure Scalable Type (as
658
673
// defined by AAPCS64). Return the number of data vectors and the number of
659
674
// predicate vectors in the type, into `NVec` and `NPred`, respectively. Upon
@@ -719,37 +734,38 @@ bool AArch64ABIInfo::passAsPureScalableType(
719
734
return true ;
720
735
}
721
736
722
- const auto *VT = Ty->getAs <VectorType>();
723
- if (!VT)
724
- return false ;
737
+ if (const auto *VT = Ty->getAs <VectorType>()) {
738
+ if (VT->getVectorKind () == VectorKind::SveFixedLengthPredicate) {
739
+ ++NPred;
740
+ if (CoerceToSeq.size () + 1 > 12 )
741
+ return false ;
742
+ CoerceToSeq.push_back (convertFixedToScalableVectorType (VT));
743
+ return true ;
744
+ }
725
745
726
- if (VT->getVectorKind () == VectorKind::SveFixedLengthPredicate ) {
727
- ++NPred ;
728
- if (CoerceToSeq.size () + 1 > 12 )
729
- return false ;
730
- CoerceToSeq.push_back (convertFixedToScalableVectorType (VT));
731
- return true ;
732
- }
746
+ if (VT->getVectorKind () == VectorKind::SveFixedLengthData ) {
747
+ ++NVec ;
748
+ if (CoerceToSeq.size () + 1 > 12 )
749
+ return false ;
750
+ CoerceToSeq.push_back (convertFixedToScalableVectorType (VT));
751
+ return true ;
752
+ }
733
753
734
- if (VT->getVectorKind () == VectorKind::SveFixedLengthData) {
735
- ++NVec;
736
- if (CoerceToSeq.size () + 1 > 12 )
737
- return false ;
738
- CoerceToSeq.push_back (convertFixedToScalableVectorType (VT));
739
- return true ;
754
+ return false ;
740
755
}
741
756
742
- if (!VT ->isBuiltinType ())
757
+ if (!Ty ->isBuiltinType ())
743
758
return false ;
744
759
745
- switch (cast<BuiltinType>(VT)->getKind ()) {
760
+ bool isPredicate;
761
+ switch (Ty->getAs <BuiltinType>()->getKind ()) {
746
762
#define SVE_VECTOR_TYPE (Name, MangledName, Id, SingletonId ) \
747
763
case BuiltinType::Id: \
748
- ++NVec; \
764
+ isPredicate = false ; \
749
765
break ;
750
766
#define SVE_PREDICATE_TYPE (Name, MangledName, Id, SingletonId ) \
751
767
case BuiltinType::Id: \
752
- ++NPred; \
768
+ isPredicate = true ; \
753
769
break ;
754
770
#define SVE_TYPE (Name, Id, SingletonId )
755
771
#include " clang/Basic/AArch64SVEACLETypes.def"
@@ -761,6 +777,10 @@ bool AArch64ABIInfo::passAsPureScalableType(
761
777
getContext ().getBuiltinVectorTypeInfo (cast<BuiltinType>(Ty));
762
778
assert (Info.NumVectors > 0 && Info.NumVectors <= 4 &&
763
779
" Expected 1, 2, 3 or 4 vectors!" );
780
+ if (isPredicate)
781
+ NPred += Info.NumVectors ;
782
+ else
783
+ NVec += Info.NumVectors ;
764
784
auto VTy = llvm::ScalableVectorType::get (CGT.ConvertType (Info.ElementType ),
765
785
Info.EC .getKnownMinValue ());
766
786
0 commit comments