================ @@ -533,11 +638,158 @@ bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() return true; } +// Check if a type is a Pure Scalable Type as defined by AAPCS64. Return the +// number of data vectors and the number of predicate vectors in the types, into +// `NVec` and `NPred`, respectively. Upon return `CoerceToSeq` contains an +// expanded sequence of LLVM IR types, one element for each non-composite +// member. For practical purposes, limit the length of `CoerceToSeq` to about +// 12, the maximum size that could possibly fit in registers. +bool AArch64ABIInfo::isPureScalableType( + QualType Ty, unsigned &NVec, unsigned &NPred, + SmallVectorImpl<llvm::Type *> &CoerceToSeq) const { + if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) { + uint64_t NElt = AT->getZExtSize(); + if (NElt == 0) + return false; + + unsigned NV = 0, NP = 0; + SmallVector<llvm::Type *> EltCoerceToSeq; + if (!isPureScalableType(AT->getElementType(), NV, NP, EltCoerceToSeq)) + return false; + + for (uint64_t I = 0; CoerceToSeq.size() < 12 && I < NElt; ++I) + llvm::copy(EltCoerceToSeq, std::back_inserter(CoerceToSeq)); + + NVec += NElt * NV; + NPred += NElt * NP; + return true; + } + + if (const RecordType *RT = Ty->getAs<RecordType>()) { + // If the record cannot be passed in registers, then it's not a PST. + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI()); + RAA != CGCXXABI::RAA_Default) + return false; + + // Pure scalable types are never unions and never contain unions. + const RecordDecl *RD = RT->getDecl(); + if (RD->isUnion()) + return false; + + // If this is a C++ record, check the bases bases. + if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { + for (const auto &I : CXXRD->bases()) { + if (isEmptyRecord(getContext(), I.getType(), true)) + continue; + if (!isPureScalableType(I.getType(), NVec, NPred, CoerceToSeq)) + return false; + } + } + + // Check members. + for (const auto *FD : RD->fields()) { + QualType FT = FD->getType(); + if (isEmptyRecord(getContext(), FT, true)) + continue; + if (!isPureScalableType(FT, NVec, NPred, CoerceToSeq)) + return false; + } + + return true; + } + + const auto *VT = Ty->getAs<VectorType>(); + if (!VT) + return false; + + if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) { + ++NPred; + if (CoerceToSeq.size() < 12) ---------------- momchil-velikov wrote:
Done. https://github.com/llvm/llvm-project/pull/112747 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits