[flang-commits] [flang] [flang][CodeGen] Add initial SystemZ ABI support (PR #208618)

Ulrich Weigand via flang-commits flang-commits at lists.llvm.org
Mon Jul 27 05:20:42 PDT 2026


================
@@ -1893,6 +1893,111 @@ struct TargetLoongArch64 : public GenericTarget<TargetLoongArch64> {
 };
 } // namespace
 
+//===----------------------------------------------------------------------===//
+// SystemZ target specifics.
+//===----------------------------------------------------------------------===//
+
+namespace {
+struct TargetSystemZ : public GenericTarget<TargetSystemZ> {
+  using GenericTarget::GenericTarget;
+
+  static constexpr int defaultWidth = 64;
+
+  auto complexType(mlir::Type eleTy, bool isResult) const {
+    assert(fir::isa_real(eleTy));
+    CodeGenSpecifics::Marshalling marshal;
+    unsigned short align{std::max(
+        static_cast<unsigned short>(getDataLayout().getTypeABIAlignment(eleTy)),
+        static_cast<unsigned short>(8))};
+    marshal.emplace_back(
+        fir::ReferenceType::get(mlir::TupleType::get(
+            eleTy.getContext(), mlir::TypeRange{eleTy, eleTy})),
+        AT{/*align=*/align, /*byval=*/!isResult, /*sret=*/isResult});
+    return marshal;
+  }
+
+  CodeGenSpecifics::Marshalling
+  complexArgumentType(mlir::Location /*loc*/, mlir::Type eleTy) const override {
+    return complexType(eleTy, false);
+  }
+
+  CodeGenSpecifics::Marshalling
+  complexReturnType(mlir::Location /*loc*/, mlir::Type eleTy) const override {
+    return complexType(eleTy, true);
+  }
+
+  CodeGenSpecifics::Marshalling
+  integerArgumentType(mlir::Location loc,
+                      mlir::IntegerType argTy) const override {
+    // SystemZ ABI requires all integers < 64 bits to be sign/zero extended.
+    // Handle widths 32 to 63 explicitly; GenericTarget handles widths < 32
+    // including the i1 zero-extension special case.
+    if (argTy.getWidth() >= 32 && argTy.getWidth() < defaultWidth) {
+      AT::IntegerExtension intExt = argTy.isUnsigned()
+                                        ? AT::IntegerExtension::Zero
+                                        : AT::IntegerExtension::Sign;
+      CodeGenSpecifics::Marshalling marshal;
+      marshal.emplace_back(argTy, AT{/*alignment=*/0, /*byval=*/false,
+                                     /*sret=*/false, /*append=*/false,
+                                     /*intExt=*/intExt});
+      return marshal;
+    }
+    return GenericTarget::integerArgumentType(loc, argTy);
+  }
+
+  // Check for a single floating-point member recursively.
+  static mlir::Type getSingleFPMember(fir::RecordType recTy) {
+    auto typeList = recTy.getTypeList();
+    if (typeList.size() != 1)
+      return {};
+    mlir::Type fieldTy = typeList[0].second;
+    if (auto nestedRec = mlir::dyn_cast<fir::RecordType>(fieldTy))
+      return getSingleFPMember(nestedRec);
+    if (auto floatTy = mlir::dyn_cast<mlir::FloatType>(fieldTy))
+      if (floatTy.getWidth() <= 64)
+        return floatTy;
+    return {};
+  }
+
+  CodeGenSpecifics::Marshalling
+  structArgumentType(mlir::Location loc, fir::RecordType ty,
+                     const Marshalling &previousArguments) const override {
+    CodeGenSpecifics::Marshalling marshal;
+    // Single FP member <= 8 bytes passed in FPR.
+    if (mlir::Type fpTy = getSingleFPMember(ty)) {
+      marshal.emplace_back(fpTy, AT{});
+      return marshal;
+    }
+    // Small structs passed in GPR (1, 2, 4, 8 bytes).
+    auto sizeAndAlign{
+        fir::getTypeSizeAndAlignmentOrCrash(loc, ty, getDataLayout(), kindMap)};
+    uint64_t byteSize = sizeAndAlign.first;
+    if (byteSize == 1 || byteSize == 2 || byteSize == 4 || byteSize == 8) {
+      marshal.emplace_back(mlir::IntegerType::get(ty.getContext(), 64), AT{});
----------------
uweigand wrote:

Is 64 correct here, or does it have to be something like `byteSize * 8`?  What happens if the struct size is smaller than 8 byte - we need to ensure that the struct is passed using the proper padding to the left (both in registers and on the stack, as appropriate).

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


More information about the flang-commits mailing list