[flang-commits] [flang] [flang] correctly deal with bind(c) derived type result ABI (PR #111678)

via flang-commits flang-commits at lists.llvm.org
Thu Oct 10 04:22:56 PDT 2024


================
@@ -641,17 +649,69 @@ struct TargetX86_64 : public GenericTarget<TargetX86_64> {
     return marshal;
   }
 
+  CodeGenSpecifics::Marshalling
+  structReturnType(mlir::Location loc, fir::RecordType recTy) const override {
+    std::uint64_t byteOffset = 0;
+    ArgClass Lo, Hi;
+    Lo = Hi = ArgClass::NoClass;
+    byteOffset = classifyStruct(loc, recTy, byteOffset, Lo, Hi);
+    mlir::MLIRContext *context = recTy.getContext();
+    postMerge(byteOffset, Lo, Hi);
+    if (Lo == ArgClass::Memory)
+      return passOnTheStack(loc, recTy, /*isResult=*/true);
+
+    // Note that X87/ComplexX87 are passed in memory, but returned via %st0
+    // %st1 registers. Here, they are returned as fp80 or {fp80, fp80} by
+    // passAsFieldIfOneFieldStruct, and LLVM will use the expected registers.
+
+    // Note that {_Complex long double} is not 100% clear from an ABI
+    // perspective because the aggregate post merger rules say it should be
+    // passed in memory because it is bigger than 2 eight bytes. This has the
+    // funny effect of
+    // {_Complex long double} return to be dealt with differently than
+    // _Complex long double. ICC, NVC, and Clang return the struct in memory,
+    // GCC does not. The code here follows ICC and Clang because that seems to
+    // be in line with the standard (nothing in the section about return says
+    // that the step 5. of the aggregate classification should not be done for
+    // the classification of the result).
----------------
jeanPerier wrote:

```suggestion
    // _Complex long double.
```

https://github.com/llvm/llvm-project/pull/111678


More information about the flang-commits mailing list