================ @@ -485,6 +485,39 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn, } Size = llvm::alignTo(Size, Alignment); + // If the Aggregate is made up of pointers, use an array of pointers for the + // coerced type. This prevents having to convert ptr2int->int2ptr through + // the call, allowing alias analysis to produce better code. + std::function<bool(QualType Ty)> ContainsOnlyPointers = [&](QualType Ty) { + if (isEmptyRecord(getContext(), Ty, true)) + return false; + const RecordType *RT = Ty->getAs<RecordType>(); + if (!RT) + return false; + const RecordDecl *RD = RT->getDecl(); + if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { + for (const auto &I : CXXRD->bases()) + if (!ContainsOnlyPointers(I.getType())) + return false; + } + return all_of(RD->fields(), [&](FieldDecl *FD) { + QualType FDTy = FD->getType(); + if (FDTy->isArrayType()) + FDTy = QualType(FDTy->getBaseElementTypeUnsafe(), 0); + return (FDTy->isPointerOrReferenceType() && + getContext().getTypeSize(FDTy) == 64) || + ContainsOnlyPointers(FDTy); + }); + }; + if (ContainsOnlyPointers(Ty)) { + assert((Size == 64 || Size == 128) && + "Expected a 64 or 128bit struct containing pointers"); + llvm::Type *PtrTy = llvm::PointerType::getUnqual(getVMContext()); + if (Size == 128) + PtrTy = llvm::ArrayType::get(PtrTy, 2); ---------------- davemgreen wrote:
Thanks - I had tested it with an align directive but not realized there was a difference between the "natural alignment" and after it was adjusted. https://github.com/llvm/llvm-project/pull/135064 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits