================
@@ -2860,74 +2861,116 @@ X86_64ABIInfo::classifyArgumentType(QualType Ty, 
unsigned freeIntRegs,
   return ABIArgInfo::getDirect(ResType);
 }
 
-ABIArgInfo
-X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt,
-                                             unsigned &NeededSSE,
-                                             unsigned &MaxVectorWidth) const {
+// Returns true if the struct can be passed directly in registers. If so, the
+// number of registers required will be returned in `NeededInt` and 
`NeededSSE`,
+// and `CoerceElts` will contain an expanded sequence of LLVM IR types that 
each
+// field should coerce to.
+bool X86_64ABIInfo::passRegCallStructTypeDirectly(
+    QualType Ty, SmallVectorImpl<llvm::Type *> &CoerceElts, unsigned 
&NeededInt,
+    unsigned &NeededSSE, unsigned &MaxVectorWidth) const {
+
   auto *RD =
       
cast<RecordType>(Ty.getCanonicalType())->getDecl()->getDefinitionOrSelf();
-
   if (RD->hasFlexibleArrayMember())
-    return getIndirectReturnResult(Ty);
+    return false;
 
-  // Sum up bases
+  // Classify the bases.
   if (auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
-    if (CXXRD->isDynamicClass()) {
-      NeededInt = NeededSSE = 0;
-      return getIndirectReturnResult(Ty);
-    }
+    if (CXXRD->isDynamicClass())
+      return false;
 
-    for (const auto &I : CXXRD->bases())
-      if (classifyRegCallStructTypeImpl(I.getType(), NeededInt, NeededSSE,
-                                        MaxVectorWidth)
-              .isIndirect()) {
-        NeededInt = NeededSSE = 0;
-        return getIndirectReturnResult(Ty);
-      }
+    for (const auto &I : CXXRD->bases()) {
+      QualType BaseTy = I.getType();
+      if (isEmptyRecord(getContext(), BaseTy, true))
+        continue;
+      if (!passRegCallStructTypeDirectly(BaseTy, CoerceElts, NeededInt,
+                                         NeededSSE, MaxVectorWidth))
+        return false;
+    }
   }
 
-  // Sum up members
+  // Classify the members.
   for (const auto *FD : RD->fields()) {
     QualType MTy = FD->getType();
     if (MTy->isRecordType() && !MTy->isUnionType()) {
-      if (classifyRegCallStructTypeImpl(MTy, NeededInt, NeededSSE,
-                                        MaxVectorWidth)
-              .isIndirect()) {
-        NeededInt = NeededSSE = 0;
-        return getIndirectReturnResult(Ty);
+      if (isEmptyRecord(getContext(), MTy, true))
+        continue;
+      if (!passRegCallStructTypeDirectly(MTy, CoerceElts, NeededInt, NeededSSE,
+                                         MaxVectorWidth))
+        return false;
+      continue;
+    }
+
+    const auto *AT = getContext().getAsConstantArrayType(MTy);
+    if (AT)
+      MTy = AT->getElementType();
+
+    unsigned LocalNeededInt, LocalNeededSSE;
+    ABIArgInfo AI = classifyArgumentType(MTy, UINT_MAX, LocalNeededInt,
+                                         LocalNeededSSE, true, true);
+    if (AI.isIgnore())
+      continue;
+    if (AI.isIndirect())
+      return false;
+
+    llvm::Type *CoerceTy = AI.getCoerceToType();
+    if (!CoerceTy) {
+      // We need to explicitly construct the coerce type for x87 long double
+      // arguments because X86_64ABIInfo::classifyArgumentType classifies them
+      // as direct without specifying a coerce type.
----------------
efriedma-quic wrote:

This is ugly; we should fix the API contract here somehow.

https://github.com/llvm/llvm-project/pull/187134
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to