diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp index e2f8fb9d239a1..f023be49cc053 100644 --- a/flang/lib/Optimizer/CodeGen/Target.cpp +++ b/flang/lib/Optimizer/CodeGen/Target.cpp @@ -199,10 +199,8 @@ struct TargetI386 : public GenericTarget { //===----------------------------------------------------------------------===// namespace { -struct TargetI386Win : public GenericTarget { - using GenericTarget::GenericTarget; - - static constexpr int defaultWidth = 32; +struct TargetI386Win : public TargetI386 { + using TargetI386::TargetI386; CodeGenSpecifics::Marshalling complexArgumentType(mlir::Location loc, mlir::Type eleTy) const override { @@ -718,10 +716,8 @@ struct TargetX86_64 : public GenericTarget { //===----------------------------------------------------------------------===// namespace { -struct TargetX86_64Win : public GenericTarget { - using GenericTarget::GenericTarget; - - static constexpr int defaultWidth = 64; +struct TargetX86_64Win : public TargetX86_64 { + using TargetX86_64::TargetX86_64; CodeGenSpecifics::Marshalling complexArgumentType(mlir::Location loc, mlir::Type eleTy) const override { @@ -780,6 +776,45 @@ struct TargetX86_64Win : public GenericTarget { } return marshal; } + + CodeGenSpecifics::Marshalling + structArgumentType(mlir::Location loc, fir::RecordType type, + const Marshalling &) const override { + std::uint64_t size = + fir::getTypeSizeAndAlignmentOrCrash(loc, type, getDataLayout(), kindMap) + .first; + CodeGenSpecifics::Marshalling marshal; + if (size <= 8) + marshal.emplace_back(mlir::IntegerType::get(type.getContext(), size * 8), + AT{}); + else + // TODO: investigate: clang is not setting the byval attribute, it is not + // clear why. Currently, this needs to be set here for flang so that the + // target-rewrite pass allocate memory as expected. Is it OK to set byval + // when clang does not? + marshal.emplace_back(fir::ReferenceType::get(type), + AT{16, /*byval=*/true, /*sret=*/false}); + return marshal; + } + + CodeGenSpecifics::Marshalling + structReturnType(mlir::Location loc, fir::RecordType type) const override { + std::uint64_t size = + fir::getTypeSizeAndAlignmentOrCrash(loc, type, getDataLayout(), kindMap) + .first; + CodeGenSpecifics::Marshalling marshal; + if (size <= 8) + marshal.emplace_back(mlir::IntegerType::get(type.getContext(), size * 8), + AT{}); + else + // TODO: investigate: the ABI is not very clear about the alignment for + // the return in memory (while it was explicit about 16 for the argument + // passing case). Should it be the default alignment for that type + // instead? + marshal.emplace_back(fir::ReferenceType::get(type), + AT{16, /*byval=*/false, /*sret=*/true}); + return marshal; + } }; } // namespace diff --git a/flang/test/Fir/struct-passing-x86-64-several-fields-inreg.fir b/flang/test/Fir/struct-passing-x86-64-several-fields-inreg.fir index 9a0a41e1da542..bd9f5fff44934 100644 --- a/flang/test/Fir/struct-passing-x86-64-several-fields-inreg.fir +++ b/flang/test/Fir/struct-passing-x86-64-several-fields-inreg.fir @@ -2,6 +2,7 @@ // struct has more than one field. // REQUIRES: x86-registered-target // RUN: fir-opt -target-rewrite="target=x86_64-unknown-linux-gnu" %s -o - | FileCheck %s +// RUN: fir-opt -target-rewrite="target=x86_64-w64-windows-gnu" %s -o - | FileCheck %s module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} { diff --git a/flang/test/Fir/target-rewrite-boxchar.fir b/flang/test/Fir/target-rewrite-boxchar.fir index 681536cde6a05..6583cde8820aa 100644 --- a/flang/test/Fir/target-rewrite-boxchar.fir +++ b/flang/test/Fir/target-rewrite-boxchar.fir @@ -1,5 +1,6 @@ // RUN: fir-opt --target-rewrite="target=i386-unknown-linux-gnu" %s | FileCheck %s --check-prefix=INT32 // RUN: fir-opt --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=INT64 +// RUN: fir-opt --target-rewrite="target=x86_64-w64-windows-gnu" %s | FileCheck %s --check-prefix=INT64 // RUN: fir-opt --target-rewrite="target=aarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=INT64 // RUN: fir-opt --target-rewrite="target=powerpc64le-unknown-linux-gnu" %s | FileCheck %s --check-prefix=INT64 // RUN: fir-opt --target-rewrite="target=amdgcn-amd-amdhsa" %s | FileCheck %s --check-prefix=INT64