================
@@ -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

Reply via email to