[cfe-commits] [patch][pr13436] Fix some uses of regparm on X86

Eli Friedman eli.friedman at gmail.com
Tue Jul 24 15:01:19 PDT 2012


On Tue, Jul 24, 2012 at 2:24 PM, Rafael EspĂ­ndola
<rafael.espindola at gmail.com> wrote:
> I found that clang's implementation of regparm doesn't match gcc's
> when the argument is a struct. Clang just skips the struct, gcc splits
> it in 32 bit chunks that are passed in registers. Not too different
> from the x86-64 abi.
>
> In a bit more detail, it looks like gcc does the following:
>
> * Arguments of type float, double, {float} and {double} are classified as
> Float, and every other argument type is classified as Integer.
> * Float arguments are passed on the stack and don't consume registers.
> * If an integer argument fits completely in the remaining registers, it is
> passed in registers, otherwise it goes to the stack.
> * Integer arguments consume registers even if they don't fit, so once an
> argument goes to the stack every other argument goes to the stack.
> * A struct return is still done indirectly, but the pointer is passed
> as the first argument in registers.
>
> This patch implements this. Note that it depends on the patch I just
> posted to the llvm list.

+  if (const RecordType *RT = Ty->getAs<RecordType>()) {
+    const RecordDecl *RD = RT->getDecl();
+    RecordDecl::field_iterator I = RD->field_begin();
+    RecordDecl::field_iterator E = RD->field_end();
+    if (I == E)
+      return Integer;
+    QualType FieldType = I->getType();
+    ++I;
+    if (I != E)
+      return Integer;
+    if (const BuiltinType *BT = FieldType->getAs<BuiltinType>()) {
+      BuiltinType::Kind K = BT->getKind();
+      if (K == BuiltinType::Float || K == BuiltinType::Double)
+        return Float;
+    }
+  }

I think you want isSingleElementStruct() here.

Have you tried randomized ABI testing?  (Either the one in the gcc
testsuite or the one in clang/utils/ABITest.)

-Eli




More information about the cfe-commits mailing list