diff options
author | Markus Mützel <markus.muetzel@gmx.de> | 2023-04-17 09:15:54 -0700 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2023-04-18 17:50:48 -0700 |
commit | ef4c1777ee8007bfc2eab8aded9fa7d0bf37eed9 (patch) | |
tree | 426537afa2c65537bdbba1b3870fbc4dd1f460a5 | |
parent | 840ac8c52fd17cf5449f663674caf2064d95f6c4 (diff) | |
download | llvm-ef4c1777ee8007bfc2eab8aded9fa7d0bf37eed9.tar.gz |
[flang] Complex numbers in function arguments on Windows
Function arguments or return values that are complex floating point values
aren't correctly lowered for Windows x86 32-bit and 64-bit targets.
See: https://github.com/llvm/llvm-project/issues/61976
Add targets that are specific for these platforms and OS.
With thanks to @mstorsjo for pointing out the fix.
Reviewed By: vzakhari
Differential Revision: https://reviews.llvm.org/D147768
(cherry picked from commit 774703ec08f62d702d40e1f97cd35ae5f732c544)
-rw-r--r-- | flang/lib/Optimizer/CodeGen/Target.cpp | 145 | ||||
-rw-r--r-- | flang/test/Fir/target-rewrite-complex.fir | 221 |
2 files changed, 362 insertions, 4 deletions
diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp index 28191a372b40..43ed7cc5b835 100644 --- a/flang/lib/Optimizer/CodeGen/Target.cpp +++ b/flang/lib/Optimizer/CodeGen/Target.cpp @@ -118,6 +118,65 @@ struct TargetI386 : public GenericTarget<TargetI386> { } // namespace //===----------------------------------------------------------------------===// +// i386 (x86 32 bit) Windows target specifics. +//===----------------------------------------------------------------------===// + +namespace { +struct TargetI386Win : public GenericTarget<TargetI386Win> { + using GenericTarget::GenericTarget; + + static constexpr int defaultWidth = 32; + + CodeGenSpecifics::Marshalling + complexArgumentType(mlir::Location loc, mlir::Type eleTy) const override { + CodeGenSpecifics::Marshalling marshal; + // Use a type that will be translated into LLVM as: + // { t, t } struct of 2 eleTy, byval, align 4 + auto structTy = + mlir::TupleType::get(eleTy.getContext(), mlir::TypeRange{eleTy, eleTy}); + marshal.emplace_back(fir::ReferenceType::get(structTy), + AT{/*align=*/4, /*byval=*/true}); + return marshal; + } + + CodeGenSpecifics::Marshalling + complexReturnType(mlir::Location loc, mlir::Type eleTy) const override { + CodeGenSpecifics::Marshalling marshal; + const auto *sem = &floatToSemantics(kindMap, eleTy); + if (sem == &llvm::APFloat::IEEEsingle()) { + // i64 pack both floats in a 64-bit GPR + marshal.emplace_back(mlir::IntegerType::get(eleTy.getContext(), 64), + AT{}); + } else if (sem == &llvm::APFloat::IEEEdouble()) { + // Use a type that will be translated into LLVM as: + // { double, double } struct of 2 double, sret, align 8 + marshal.emplace_back( + fir::ReferenceType::get(mlir::TupleType::get( + eleTy.getContext(), mlir::TypeRange{eleTy, eleTy})), + AT{/*align=*/8, /*byval=*/false, /*sret=*/true}); + } else if (sem == &llvm::APFloat::IEEEquad()) { + // Use a type that will be translated into LLVM as: + // { fp128, fp128 } struct of 2 fp128, sret, align 16 + marshal.emplace_back( + fir::ReferenceType::get(mlir::TupleType::get( + eleTy.getContext(), mlir::TypeRange{eleTy, eleTy})), + AT{/*align=*/16, /*byval=*/false, /*sret=*/true}); + } else if (sem == &llvm::APFloat::x87DoubleExtended()) { + // Use a type that will be translated into LLVM as: + // { x86_fp80, x86_fp80 } struct of 2 x86_fp80, sret, align 4 + marshal.emplace_back( + fir::ReferenceType::get(mlir::TupleType::get( + eleTy.getContext(), mlir::TypeRange{eleTy, eleTy})), + AT{/*align=*/4, /*byval=*/false, /*sret=*/true}); + } else { + TODO(loc, "complex for this precision"); + } + return marshal; + } +}; +} // namespace + +//===----------------------------------------------------------------------===// // x86_64 (x86 64 bit) linux target specifics. //===----------------------------------------------------------------------===// @@ -180,6 +239,76 @@ struct TargetX86_64 : public GenericTarget<TargetX86_64> { } // namespace //===----------------------------------------------------------------------===// +// x86_64 (x86 64 bit) Windows target specifics. +//===----------------------------------------------------------------------===// + +namespace { +struct TargetX86_64Win : public GenericTarget<TargetX86_64Win> { + using GenericTarget::GenericTarget; + + static constexpr int defaultWidth = 64; + + CodeGenSpecifics::Marshalling + complexArgumentType(mlir::Location loc, mlir::Type eleTy) const override { + CodeGenSpecifics::Marshalling marshal; + const auto *sem = &floatToSemantics(kindMap, eleTy); + if (sem == &llvm::APFloat::IEEEsingle()) { + // i64 pack both floats in a 64-bit GPR + marshal.emplace_back(mlir::IntegerType::get(eleTy.getContext(), 64), + AT{}); + } else if (sem == &llvm::APFloat::IEEEdouble()) { + // Use a type that will be translated into LLVM as: + // { double, double } struct of 2 double, byval, align 8 + marshal.emplace_back( + fir::ReferenceType::get(mlir::TupleType::get( + eleTy.getContext(), mlir::TypeRange{eleTy, eleTy})), + AT{/*align=*/8, /*byval=*/true}); + } else if (sem == &llvm::APFloat::IEEEquad() || + sem == &llvm::APFloat::x87DoubleExtended()) { + // Use a type that will be translated into LLVM as: + // { t, t } struct of 2 eleTy, byval, align 16 + marshal.emplace_back( + fir::ReferenceType::get(mlir::TupleType::get( + eleTy.getContext(), mlir::TypeRange{eleTy, eleTy})), + AT{/*align=*/16, /*byval=*/true}); + } else { + TODO(loc, "complex for this precision"); + } + return marshal; + } + + CodeGenSpecifics::Marshalling + complexReturnType(mlir::Location loc, mlir::Type eleTy) const override { + CodeGenSpecifics::Marshalling marshal; + const auto *sem = &floatToSemantics(kindMap, eleTy); + if (sem == &llvm::APFloat::IEEEsingle()) { + // i64 pack both floats in a 64-bit GPR + marshal.emplace_back(mlir::IntegerType::get(eleTy.getContext(), 64), + AT{}); + } else if (sem == &llvm::APFloat::IEEEdouble()) { + // Use a type that will be translated into LLVM as: + // { double, double } struct of 2 double, sret, align 8 + marshal.emplace_back( + fir::ReferenceType::get(mlir::TupleType::get( + eleTy.getContext(), mlir::TypeRange{eleTy, eleTy})), + AT{/*align=*/8, /*byval=*/false, /*sret=*/true}); + } else if (sem == &llvm::APFloat::IEEEquad() || + sem == &llvm::APFloat::x87DoubleExtended()) { + // Use a type that will be translated into LLVM as: + // { t, t } struct of 2 eleTy, sret, align 16 + marshal.emplace_back( + fir::ReferenceType::get(mlir::TupleType::get( + eleTy.getContext(), mlir::TypeRange{eleTy, eleTy})), + AT{/*align=*/16, /*byval=*/false, /*sret=*/true}); + } else { + TODO(loc, "complex for this precision"); + } + return marshal; + } +}; +} // namespace + +//===----------------------------------------------------------------------===// // AArch64 linux target specifics. //===----------------------------------------------------------------------===// @@ -418,11 +547,19 @@ fir::CodeGenSpecifics::get(mlir::MLIRContext *ctx, llvm::Triple &&trp, default: break; case llvm::Triple::ArchType::x86: - return std::make_unique<TargetI386>(ctx, std::move(trp), - std::move(kindMap)); - case llvm::Triple::ArchType::x86_64: - return std::make_unique<TargetX86_64>(ctx, std::move(trp), + if (trp.isOSWindows()) + return std::make_unique<TargetI386Win>(ctx, std::move(trp), + std::move(kindMap)); + else + return std::make_unique<TargetI386>(ctx, std::move(trp), std::move(kindMap)); + case llvm::Triple::ArchType::x86_64: + if (trp.isOSWindows()) + return std::make_unique<TargetX86_64Win>(ctx, std::move(trp), + std::move(kindMap)); + else + return std::make_unique<TargetX86_64>(ctx, std::move(trp), + std::move(kindMap)); case llvm::Triple::ArchType::aarch64: return std::make_unique<TargetAArch64>(ctx, std::move(trp), std::move(kindMap)); diff --git a/flang/test/Fir/target-rewrite-complex.fir b/flang/test/Fir/target-rewrite-complex.fir index 82d5923a25cf..33c50fcc1e95 100644 --- a/flang/test/Fir/target-rewrite-complex.fir +++ b/flang/test/Fir/target-rewrite-complex.fir @@ -1,5 +1,7 @@ // RUN: fir-opt --target-rewrite="target=i386-unknown-linux-gnu" %s | FileCheck %s --check-prefix=I32 +// RUN: fir-opt --target-rewrite="target=i386-w64-windows-gnu" %s | FileCheck %s --check-prefix=I32_MINGW // RUN: fir-opt --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=X64 +// RUN: fir-opt --target-rewrite="target=x86_64-w64-windows-gnu" %s | FileCheck %s --check-prefix=X64_MINGW // RUN: fir-opt --target-rewrite="target=aarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=AARCH64 // RUN: fir-opt --target-rewrite="target=powerpc64le-unknown-linux-gnu" %s | FileCheck %s --check-prefix=PPC64le // RUN: fir-opt --target-rewrite="target=sparc64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=SPARCV9 @@ -10,7 +12,9 @@ // Test that we rewrite the signature and body of a function that returns a // complex<4>. // I32-LABEL: func @returncomplex4() -> i64 +// I32_MINGW-LABEL: func @returncomplex4() -> i64 // X64-LABEL: func @returncomplex4() -> !fir.vector<2:!fir.real<4>> +// X64_MINGW-LABEL: func @returncomplex4() -> i64 // AARCH64-LABEL: func @returncomplex4() -> tuple<!fir.real<4>, !fir.real<4>> // PPC64le-LABEL: func @returncomplex4() -> tuple<!fir.real<4>, !fir.real<4>> // SPARCV9-LABEL: func @returncomplex4() -> tuple<!fir.real<4>, !fir.real<4>> @@ -19,8 +23,12 @@ func.func @returncomplex4() -> !fir.complex<4> { // I32: fir.insert_value // I32: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value + // I32_MINGW: fir.insert_value + // I32_MINGW: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value // X64: fir.insert_value // X64: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value + // X64_MINGW: fir.insert_value + // X64_MINGW: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value // AARCH64: fir.insert_value // AARCH64: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value // PPC64le: fir.insert_value @@ -45,11 +53,21 @@ func.func @returncomplex4() -> !fir.complex<4> { // I32: fir.store [[VAL]] to [[ADDRC]] : !fir.ref<!fir.complex<4>> // I32: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRI64]] : !fir.ref<i64> // I32: return [[RES]] : i64 + // I32_MINGW: [[ADDRV:%[0-9A-Za-z]+]] = fir.alloca i64 + // I32_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRV]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // I32_MINGW: fir.store [[VAL]] to [[ADDRC]] : !fir.ref<!fir.complex<4>> + // I32_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRV]] : !fir.ref<i64> + // I32_MINGW: return [[RES]] : i64 // X64: [[ADDRV:%[0-9A-Za-z]+]] = fir.alloca !fir.vector<2:!fir.real<4>> // X64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRV]] : (!fir.ref<!fir.vector<2:!fir.real<4>>>) -> !fir.ref<!fir.complex<4>> // X64: fir.store [[VAL]] to [[ADDRC]] : !fir.ref<!fir.complex<4>> // X64: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRV]] : !fir.ref<!fir.vector<2:!fir.real<4>>> // X64: return [[RES]] : !fir.vector<2:!fir.real<4>> + // X64_MINGW: [[ADDRV:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRV]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // X64_MINGW: fir.store [[VAL]] to [[ADDRC]] : !fir.ref<!fir.complex<4>> + // X64_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRV]] : !fir.ref<i64> + // X64_MINGW: return [[RES]] : i64 // AARCH64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple<!fir.real<4>, !fir.real<4>> // AARCH64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> !fir.ref<!fir.complex<4>> // AARCH64: fir.store [[VAL]] to [[ADDRC]] : !fir.ref<!fir.complex<4>> @@ -79,7 +97,11 @@ func.func @returncomplex4() -> !fir.complex<4> { // complex<8>. // I32-LABEL:func @returncomplex8 // I32-SAME: ([[ARG0:%[0-9A-Za-z]+]]: !fir.ref<tuple<!fir.real<8>, !fir.real<8>>> {llvm.align = 4 : i32, llvm.sret = tuple<!fir.real<8>, !fir.real<8>>}) +// I32_MINGW-LABEL: func @returncomplex8 +// I32_MINGW-SAME: ([[ARG0:%[0-9A-Za-z]+]]: !fir.ref<tuple<!fir.real<8>, !fir.real<8>>> {llvm.align = 8 : i32, llvm.sret = tuple<!fir.real<8>, !fir.real<8>>}) // X64-LABEL: func @returncomplex8() -> tuple<!fir.real<8>, !fir.real<8>> +// X64_MINGW-LABEL: func @returncomplex8 +// X64_MINGW-SAME: ([[ARG0:%[0-9A-Za-z]+]]: !fir.ref<tuple<!fir.real<8>, !fir.real<8>>> {llvm.align = 8 : i32, llvm.sret = tuple<!fir.real<8>, !fir.real<8>>}) // AARCH64-LABEL: func @returncomplex8() -> tuple<!fir.real<8>, !fir.real<8>> // PPC64le-LABEL: func @returncomplex8() -> tuple<!fir.real<8>, !fir.real<8>> // SPARCV9-LABEL: func @returncomplex8() -> tuple<!fir.real<8>, !fir.real<8>> @@ -88,8 +110,12 @@ func.func @returncomplex4() -> !fir.complex<4> { func.func @returncomplex8() -> !fir.complex<8> { // I32: fir.insert_value // I32: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value {{.*}} + // I32_MINGW: fir.insert_value + // I32_MINGW: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value {{.*}} // X64: fir.insert_value // X64: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value {{.*}} + // X64_MINGW: fir.insert_value + // X64_MINGW: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value {{.*}} // AARCH64: fir.insert_value // AARCH64: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value {{.*}} // PPC64le: fir.insert_value @@ -111,11 +137,17 @@ func.func @returncomplex8() -> !fir.complex<8> { // I32: [[ADDR:%[0-9A-Za-z]+]] = fir.convert [[ARG0]] : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> !fir.ref<!fir.complex<8>> // I32: fir.store [[VAL]] to [[ADDR]] : !fir.ref<!fir.complex<8>> // I32: return{{ *$}} + // I32_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ARG0]] : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> !fir.ref<!fir.complex<8>> + // I32_MINGW: fir.store [[VAL]] to [[ADDRC]] : !fir.ref<!fir.complex<8>> + // I32_MINGW: return // X64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple<!fir.real<8>, !fir.real<8>> // X64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> !fir.ref<!fir.complex<8>> // X64: fir.store [[VAL]] to [[ADDRC]] : !fir.ref<!fir.complex<8>> // X64: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRT]] : !fir.ref<tuple<!fir.real<8>, !fir.real<8>>> // X64: return [[RES]] : tuple<!fir.real<8>, !fir.real<8>> + // X64_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ARG0]] : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> !fir.ref<!fir.complex<8>> + // X64_MINGW: fir.store [[VAL]] to [[ADDRC]] : !fir.ref<!fir.complex<8>> + // X64_MINGW: return // AARCH64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple<!fir.real<8>, !fir.real<8>> // AARCH64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> !fir.ref<!fir.complex<8>> // AARCH64: fir.store [[VAL]] to [[ADDRC]] : !fir.ref<!fir.complex<8>> @@ -146,7 +178,9 @@ func.func @returncomplex8() -> !fir.complex<8> { // Test that we rewrite the signature of a function that accepts a complex<4>. // I32-LABEL: func private @paramcomplex4(!fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}) +// I32_MINGW-LABEL: func private @paramcomplex4(!fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}) // X64-LABEL: func private @paramcomplex4(!fir.vector<2:!fir.real<4>>) +// X64_MINGW-LABEL: func private @paramcomplex4(i64) // AARCH64-LABEL: func private @paramcomplex4(!fir.array<2x!fir.real<4>>) // PPC64le-LABEL: func private @paramcomplex4(!fir.real<4>, !fir.real<4>) // SPARCV9-LABEL: func private @paramcomplex4(!fir.real<4>, !fir.real<4>) @@ -156,7 +190,9 @@ func.func private @paramcomplex4(!fir.complex<4>) -> () // Test that we rewrite calls to functions that return or accept complex<4>. // I32-LABEL: func @callcomplex4 +// I32_MINGW-LABEL: func @callcomplex4 // X64-LABEL: func @callcomplex4 +// X64_MINGW-LABEL: func @callcomplex4 // AARCH64-LABEL: func @callcomplex4 // PPC64le-LABEL: func @callcomplex4 // SPARCV9-LABEL: func @callcomplex4 @@ -165,7 +201,9 @@ func.func private @paramcomplex4(!fir.complex<4>) -> () func.func @callcomplex4(%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) { // I32: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> i64 + // I32_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> i64 // X64: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> !fir.vector<2:!fir.real<4>> + // X64_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> i64 // AARCH64: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> tuple<!fir.real<4>, !fir.real<4>> // PPC64le: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> tuple<!fir.real<4>, !fir.real<4>> // SPARCV9: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> tuple<!fir.real<4>, !fir.real<4>> @@ -182,6 +220,15 @@ func.func @callcomplex4(%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i3 // I32: [[T:%[0-9A-Za-z]+]] = fir.convert [[ADDRC2]] : (!fir.ref<!fir.complex<4>>) -> !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> // I32: fir.call @paramcomplex4([[T]]) : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> () + // I32_MINGW: [[ADDRI64:%[0-9A-Za-z]+]] = fir.alloca i64 + // I32_MINGW: fir.store [[RES]] to [[ADDRI64]] : !fir.ref<i64> + // I32_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRI64]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // I32_MINGW: [[C:%[0-9A-Za-z]+]] = fir.load [[ADDRC]] : !fir.ref<!fir.complex<4>> + // I32_MINGW: [[ADDRC2:%[0-9A-Za-z]+]] = fir.alloca !fir.complex<4> + // I32_MINGW: fir.store [[C]] to [[ADDRC2]] : !fir.ref<!fir.complex<4>> + // I32_MINGW: [[T:%[0-9A-Za-z]+]] = fir.convert [[ADDRC2]] : (!fir.ref<!fir.complex<4>>) -> !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> + // I32_MINGW: fir.call @paramcomplex4([[T]]) : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> () + // X64: [[ADDRV:%[0-9A-Za-z]+]] = fir.alloca !fir.vector<2:!fir.real<4>> // X64: fir.store [[RES]] to [[ADDRV]] : !fir.ref<!fir.vector<2:!fir.real<4>>> // X64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRV]] : (!fir.ref<!fir.vector<2:!fir.real<4>>>) -> !fir.ref<!fir.complex<4>> @@ -192,6 +239,16 @@ func.func @callcomplex4(%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i3 // X64: [[VRELOADED:%[0-9A-Za-z]+]] = fir.load [[ADDRV2]] : !fir.ref<!fir.vector<2:!fir.real<4>>> // X64: fir.call @paramcomplex4([[VRELOADED]]) : (!fir.vector<2:!fir.real<4>>) -> () + // X64_MINGW: [[ADDRV:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW: fir.store [[RES]] to [[ADDRV]] : !fir.ref<i64> + // X64_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRV]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // X64_MINGW: [[V:%[0-9A-Za-z]+]] = fir.load [[ADDRC]] : !fir.ref<!fir.complex<4>> + // X64_MINGW: [[ADDRV2:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW: [[ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[ADDRV2]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // X64_MINGW: fir.store [[V]] to [[ADDRC2]] : !fir.ref<!fir.complex<4>> + // X64_MINGW: [[VRELOADED:%[0-9A-Za-z]+]] = fir.load [[ADDRV2]] : !fir.ref<i64> + // X64_MINGW: fir.call @paramcomplex4([[VRELOADED]]) : (i64) -> () + // AARCH64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple<!fir.real<4>, !fir.real<4>> // AARCH64: fir.store [[RES]] to [[ADDRT]] : !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> // AARCH64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> !fir.ref<!fir.complex<4>> @@ -236,7 +293,9 @@ func.func @callcomplex4(%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i3 fir.call @paramcomplex4(%1) : (!fir.complex<4>) -> () // I32: [[RES:%[0-9A-Za-z]+]] = fir.dispatch "ret_complex"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> i64 {pass_arg_pos = 0 : i32} + // I32_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.dispatch "ret_complex"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> i64 {pass_arg_pos = 0 : i32} // X64: [[RES:%[0-9A-Za-z]+]] = fir.dispatch "ret_complex"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.vector<2:!fir.real<4>> {pass_arg_pos = 0 : i32} + // X64_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.dispatch "ret_complex"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> i64 {pass_arg_pos = 0 : i32} // AARCH64: [[RES:%[0-9A-Za-z]+]] = fir.dispatch "ret_complex"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> tuple<!fir.real<4>, !fir.real<4>> {pass_arg_pos = 0 : i32} // PPC64le: [[RES:%[0-9A-Za-z]+]] = fir.dispatch "ret_complex"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> tuple<!fir.real<4>, !fir.real<4>> {pass_arg_pos = 0 : i32} // SPARCV9: [[RES:%[0-9A-Za-z]+]] = fir.dispatch "ret_complex"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> tuple<!fir.real<4>, !fir.real<4>> {pass_arg_pos = 0 : i32} @@ -252,6 +311,15 @@ func.func @callcomplex4(%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i3 // I32: [[T:%[0-9A-Za-z]+]] = fir.convert [[ADDRC2]] : (!fir.ref<!fir.complex<4>>) -> !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> // I32: fir.dispatch "with_complex"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}}, [[T]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>, !fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) {pass_arg_pos = 0 : i32} + // I32_MINGW: [[ADDRI64:%[0-9A-Za-z]+]] = fir.alloca i64 + // I32_MINGW: fir.store [[RES]] to [[ADDRI64]] : !fir.ref<i64> + // I32_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRI64]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // I32_MINGW: [[C:%[0-9A-Za-z]+]] = fir.load [[ADDRC]] : !fir.ref<!fir.complex<4>> + // I32_MINGW: [[ADDRC2:%[0-9A-Za-z]+]] = fir.alloca !fir.complex<4> + // I32_MINGW: fir.store [[C]] to [[ADDRC2]] : !fir.ref<!fir.complex<4>> + // I32_MINGW: [[T:%[0-9A-Za-z]+]] = fir.convert [[ADDRC2]] : (!fir.ref<!fir.complex<4>>) -> !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> + // I32_MINGW: fir.dispatch "with_complex"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}}, [[T]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>, !fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) {pass_arg_pos = 0 : i32} + // X64: [[ADDRV:%[0-9A-Za-z]+]] = fir.alloca !fir.vector<2:!fir.real<4>> // X64: fir.store [[RES]] to [[ADDRV]] : !fir.ref<!fir.vector<2:!fir.real<4>>> // X64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRV]] : (!fir.ref<!fir.vector<2:!fir.real<4>>>) -> !fir.ref<!fir.complex<4>> @@ -262,6 +330,16 @@ func.func @callcomplex4(%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i3 // X64: [[VRELOADED:%[0-9A-Za-z]+]] = fir.load [[ADDRV2]] : !fir.ref<!fir.vector<2:!fir.real<4>>> // X64: fir.dispatch "with_complex"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}}, [[VRELOADED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>, !fir.vector<2:!fir.real<4>>) {pass_arg_pos = 0 : i32} + // X64_MINGW: [[ADDRV:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW: fir.store [[RES]] to [[ADDRV]] : !fir.ref<i64> + // X64_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRV]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // X64_MINGW: [[V:%[0-9A-Za-z]+]] = fir.load [[ADDRC]] : !fir.ref<!fir.complex<4>> + // X64_MINGW: [[ADDRV2:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW: [[ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[ADDRV2]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // X64_MINGW: fir.store [[V]] to [[ADDRC2]] : !fir.ref<!fir.complex<4>> + // X64_MINGW: [[VRELOADED:%[0-9A-Za-z]+]] = fir.load [[ADDRV2]] : !fir.ref<i64> + // X64_MINGW: fir.dispatch "with_complex"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}}, [[VRELOADED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>, i64) {pass_arg_pos = 0 : i32} + // AARCH64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple<!fir.real<4>, !fir.real<4>> // AARCH64: fir.store [[RES]] to [[ADDRT]] : !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> // AARCH64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> !fir.ref<!fir.complex<4>> @@ -299,7 +377,9 @@ func.func @callcomplex4(%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i3 // I32: fir.dispatch "with_complex2"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}}, %{{.*}} : !fir.ref<tuple<!fir.real<4>, !fir.real<4>>>, !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) {pass_arg_pos = 1 : i32} + // I32_MINGW: fir.dispatch "with_complex2"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}}, %{{.*}} : !fir.ref<tuple<!fir.real<4>, !fir.real<4>>>, !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) {pass_arg_pos = 1 : i32} // X64: fir.dispatch "with_complex2"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}}, %{{.*}} : !fir.vector<2:!fir.real<4>>, !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) {pass_arg_pos = 1 : i32} + // X64_MINGW: fir.dispatch "with_complex2"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}}, %{{.*}} : i64, !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) {pass_arg_pos = 1 : i32} // AARCH64: fir.dispatch "with_complex2"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}}, %{{.*}} : !fir.array<2x!fir.real<4>>, !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) {pass_arg_pos = 1 : i32} // PPC64le: fir.dispatch "with_complex2"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}}, %{{.*}}, %{{.*}} : !fir.real<4>, !fir.real<4>, !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) {pass_arg_pos = 2 : i32} // SPARCV9: fir.dispatch "with_complex2"(%{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%{{.*}}, %{{.*}}, %{{.*}} : !fir.real<4>, !fir.real<4>, !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) {pass_arg_pos = 2 : i32} @@ -312,7 +392,9 @@ func.func @callcomplex4(%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i3 // Test that we rewrite the signature of a function that accepts a complex<8>. // I32-LABEL: func private @paramcomplex8(!fir.ref<tuple<!fir.real<8>, !fir.real<8>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<8>, !fir.real<8>>}) +// I32_MINGW-LABEL: func private @paramcomplex8(!fir.ref<tuple<!fir.real<8>, !fir.real<8>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<8>, !fir.real<8>>}) // X64-LABEL: func private @paramcomplex8(!fir.real<8>, !fir.real<8>) +// X64_MINGW-LABEL: func private @paramcomplex8(!fir.ref<tuple<!fir.real<8>, !fir.real<8>>> {llvm.align = 8 : i32, llvm.byval = tuple<!fir.real<8>, !fir.real<8>>}) // AARCH64-LABEL: func private @paramcomplex8(!fir.array<2x!fir.real<8>>) // PPC64le-LABEL: func private @paramcomplex8(!fir.real<8>, !fir.real<8>) // SPARCV9-LABEL: func private @paramcomplex8(!fir.real<8>, !fir.real<8>) @@ -322,7 +404,9 @@ func.func private @paramcomplex8(!fir.complex<8>) -> () // Test that we rewrite calls to functions that return or accept complex<8>. // I32-LABEL: func @callcomplex8() +// I32_MINGW-LABEL: func @callcomplex8() // X64-LABEL: func @callcomplex8() +// X64_MINGW-LABEL: func @callcomplex8() // AARCH64-LABEL: func @callcomplex8() // PPC64le-LABEL: func @callcomplex8() // SPARCV9-LABEL: func @callcomplex8() @@ -331,7 +415,11 @@ func.func private @paramcomplex8(!fir.complex<8>) -> () func.func @callcomplex8() { // I32: [[RES:%[0-9A-Za-z]+]] = fir.alloca tuple<!fir.real<8>, !fir.real<8>> // I32: fir.call @returncomplex8([[RES]]) : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> () + // I32_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.alloca tuple<!fir.real<8>, !fir.real<8>> + // I32_MINGW: fir.call @returncomplex8([[RES]]) : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> () // X64: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple<!fir.real<8>, !fir.real<8>> + // X64_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.alloca tuple<!fir.real<8>, !fir.real<8>> + // X64_MINGW: fir.call @returncomplex8([[RES]]) : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> () // AARCH64: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple<!fir.real<8>, !fir.real<8>> // PPC64le: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple<!fir.real<8>, !fir.real<8>> // SPARCV9: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple<!fir.real<8>, !fir.real<8>> @@ -346,6 +434,13 @@ func.func @callcomplex8() { // I32: [[ADDRT:%[0-9A-Za-z]+]] = fir.convert [[ADDRC]] : (!fir.ref<!fir.complex<8>>) -> !fir.ref<tuple<!fir.real<8>, !fir.real<8>>> // I32: fir.call @paramcomplex8([[ADDRT]]) : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> () + // I32_MINGW: [[RESC:%[0-9A-Za-z]+]] = fir.convert [[RES]] : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> !fir.ref<!fir.complex<8>> + // I32_MINGW: [[V:%[0-9A-Za-z]+]] = fir.load [[RESC]] : !fir.ref<!fir.complex<8>> + // I32_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.alloca !fir.complex<8> + // I32_MINGW: fir.store [[V]] to [[ADDRC]] : !fir.ref<!fir.complex<8>> + // I32_MINGW: [[ADDRT:%[0-9A-Za-z]+]] = fir.convert [[ADDRC]] : (!fir.ref<!fir.complex<8>>) -> !fir.ref<tuple<!fir.real<8>, !fir.real<8>>> + // I32_MINGW: fir.call @paramcomplex8([[ADDRT]]) : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> () + // X64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple<!fir.real<8>, !fir.real<8>> // X64: fir.store [[RES]] to [[ADDRT]] : !fir.ref<tuple<!fir.real<8>, !fir.real<8>>> // X64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> !fir.ref<!fir.complex<8>> @@ -354,6 +449,13 @@ func.func @callcomplex8() { // X64: [[B:%[0-9A-Za-z]+]] = fir.extract_value [[V]], [1 : i32] : (!fir.complex<8>) -> !fir.real<8> // X64: fir.call @paramcomplex8([[A]], [[B]]) : (!fir.real<8>, !fir.real<8>) -> () + // X64_MINGW: [[RESC:%[0-9A-Za-z]+]] = fir.convert [[RES]] : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> !fir.ref<!fir.complex<8>> + // X64_MINGW: [[V:%[0-9A-Za-z]+]] = fir.load [[RESC]] : !fir.ref<!fir.complex<8>> + // X64_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.alloca !fir.complex<8> + // X64_MINGW: fir.store [[V]] to [[ADDRC]] : !fir.ref<!fir.complex<8>> + // X64_MINGW: [[ADDRT:%[0-9A-Za-z]+]] = fir.convert [[ADDRC]] : (!fir.ref<!fir.complex<8>>) -> !fir.ref<tuple<!fir.real<8>, !fir.real<8>>> + // X64_MINGW: fir.call @paramcomplex8([[ADDRT]]) : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> () + // AARCH64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple<!fir.real<8>, !fir.real<8>> // AARCH64: fir.store [[RES]] to [[ADDRT]] : !fir.ref<tuple<!fir.real<8>, !fir.real<8>>> // AARCH64: [[ADDRV:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref<tuple<!fir.real<8>, !fir.real<8>>>) -> !fir.ref<!fir.complex<8>> @@ -402,7 +504,9 @@ func.func @callcomplex8() { // Test multiple complex<4> parameters and arguments // I32-LABEL: func private @calleemultipleparamscomplex4(!fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}, !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}, !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}) +// I32_MINGW-LABEL: func private @calleemultipleparamscomplex4(!fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}, !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}, !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}) // X64-LABEL: func private @calleemultipleparamscomplex4(!fir.vector<2:!fir.real<4>>, !fir.vector<2:!fir.real<4>>, !fir.vector<2:!fir.real<4>>) +// X64_MINGW-LABEL: func private @calleemultipleparamscomplex4(i64, i64, i64) // AARCH64-LABEL: func private @calleemultipleparamscomplex4(!fir.array<2x!fir.real<4>>, !fir.array<2x!fir.real<4>>, !fir.array<2x!fir.real<4>>) // PPC64le-LABEL: func private @calleemultipleparamscomplex4(!fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>) // SPARCV9-LABEL: func private @calleemultipleparamscomplex4(!fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>) @@ -412,8 +516,12 @@ func.func private @calleemultipleparamscomplex4(!fir.complex<4>, !fir.complex<4> // I32-LABEL: func @multipleparamscomplex4 // I32-SAME: ([[Z1:%[0-9A-Za-z]+]]: !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}, [[Z2:%[0-9A-Za-z]+]]: !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}, [[Z3:%[0-9A-Za-z]+]]: !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}) +// I32_MINGW-LABEL: func @multipleparamscomplex4 +// I32_MINGW-SAME: ([[Z1:%[0-9A-Za-z]+]]: !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}, [[Z2:%[0-9A-Za-z]+]]: !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}, [[Z3:%[0-9A-Za-z]+]]: !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> {llvm.align = 4 : i32, llvm.byval = tuple<!fir.real<4>, !fir.real<4>>}) // X64-LABEL: func @multipleparamscomplex4 // X64-SAME: ([[Z1:%[0-9A-Za-z]+]]: !fir.vector<2:!fir.real<4>>, [[Z2:%[0-9A-Za-z]+]]: !fir.vector<2:!fir.real<4>>, [[Z3:%[0-9A-Za-z]+]]: !fir.vector<2:!fir.real<4>>) +// X64_MINGW-LABEL: func @multipleparamscomplex4 +// X64_MINGW-SAME: ([[Z1:%[0-9A-Za-z]+]]: i64, [[Z2:%[0-9A-Za-z]+]]: i64, [[Z3:%[0-9A-Za-z]+]]: i64) // AARCH64-LABEL: func @multipleparamscomplex4 // AARCH64-SAME: ([[Z1:%[0-9A-Za-z]+]]: !fir.array<2x!fir.real<4>>, [[Z2:%[0-9A-Za-z]+]]: !fir.array<2x!fir.real<4>>, [[Z3:%[0-9A-Za-z]+]]: !fir.array<2x!fir.real<4>>) // PPC64le-LABEL: func @multipleparamscomplex4 @@ -444,6 +552,25 @@ func.func @multipleparamscomplex4(%z1 : !fir.complex<4>, %z2 : !fir.complex<4>, // I32: fir.call @calleemultipleparamscomplex4([[Z1_ADDRT]], [[Z2_ADDRT]], [[Z3_ADDRT]]) : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>, !fir.ref<tuple<!fir.real<4>, !fir.real<4>>>, !fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> () + // I32_MINGW-DAG: [[Z1_ADDR:%[0-9A-Za-z]+]] = fir.convert [[Z1]] : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> !fir.ref<!fir.complex<4>> + // I32_MINGW-DAG: [[Z1_VAL:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDR]] : !fir.ref<!fir.complex<4>> + // I32_MINGW-DAG: [[Z2_ADDR:%[0-9A-Za-z]+]] = fir.convert [[Z2]] : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> !fir.ref<!fir.complex<4>> + // I32_MINGW-DAG: [[Z2_VAL:%[0-9A-Za-z]+]] = fir.load [[Z2_ADDR]] : !fir.ref<!fir.complex<4>> + // I32_MINGW-DAG: [[Z3_ADDR:%[0-9A-Za-z]+]] = fir.convert [[Z3]] : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> !fir.ref<!fir.complex<4>> + // I32_MINGW-DAG: [[Z3_VAL:%[0-9A-Za-z]+]] = fir.load [[Z3_ADDR]] : !fir.ref<!fir.complex<4>> + + // I32_MINGW-DAG: [[Z1_ADDRC:%[0-9A-Za-z]+]] = fir.alloca !fir.complex<4> + // I32_MINGW-DAG: fir.store [[Z1_VAL]] to [[Z1_ADDRC]] : !fir.ref<!fir.complex<4>> + // I32_MINGW-DAG: [[Z1_ADDRT:%[0-9A-Za-z]+]] = fir.convert [[Z1_ADDRC]] : (!fir.ref<!fir.complex<4>>) -> !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> + // I32_MINGW-DAG: [[Z2_ADDRC:%[0-9A-Za-z]+]] = fir.alloca !fir.complex<4> + // I32_MINGW-DAG: fir.store [[Z2_VAL]] to [[Z2_ADDRC]] : !fir.ref<!fir.complex<4>> + // I32_MINGW-DAG: [[Z2_ADDRT:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDRC]] : (!fir.ref<!fir.complex<4>>) -> !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> + // I32_MINGW-DAG: [[Z3_ADDRC:%[0-9A-Za-z]+]] = fir.alloca !fir.complex<4> + // I32_MINGW-DAG: fir.store [[Z3_VAL]] to [[Z3_ADDRC]] : !fir.ref<!fir.complex<4>> + // I32_MINGW-DAG: [[Z3_ADDRT:%[0-9A-Za-z]+]] = fir.convert [[Z3_ADDRC]] : (!fir.ref<!fir.complex<4>>) -> !fir.ref<tuple<!fir.real<4>, !fir.real<4>>> + + // I32_MINGW: fir.call @calleemultipleparamscomplex4([[Z1_ADDRT]], [[Z2_ADDRT]], [[Z3_ADDRT]]) : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>, !fir.ref<tuple<!fir.real<4>, !fir.real<4>>>, !fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> () + // X64-DAG: [[Z3_ADDR:%[0-9A-Za-z]+]] = fir.alloca !fir.vector<2:!fir.real<4>> // X64-DAG: fir.store [[Z3]] to [[Z3_ADDR]] : !fir.ref<!fir.vector<2:!fir.real<4>>> // X64-DAG: [[Z3_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z3_ADDR]] : (!fir.ref<!fir.vector<2:!fir.real<4>>>) -> !fir.ref<!fir.complex<4>> @@ -472,6 +599,34 @@ func.func @multipleparamscomplex4(%z1 : !fir.complex<4>, %z2 : !fir.complex<4>, // X64: fir.call @calleemultipleparamscomplex4([[Z1_RELOADED]], [[Z2_RELOADED]], [[Z3_RELOADED]]) : (!fir.vector<2:!fir.real<4>>, !fir.vector<2:!fir.real<4>>, !fir.vector<2:!fir.real<4>>) -> () + // X64_MINGW-DAG: [[Z3_ADDR:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW-DAG: fir.store [[Z3]] to [[Z3_ADDR]] : !fir.ref<i64> + // X64_MINGW-DAG: [[Z3_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z3_ADDR]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // X64_MINGW-DAG: [[Z3_VAL:%[0-9A-Za-z]+]] = fir.load [[Z3_ADDRC]] : !fir.ref<!fir.complex<4>> + // X64_MINGW-DAG: [[Z2_ADDR:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW-DAG: fir.store [[Z2]] to [[Z2_ADDR]] : !fir.ref<i64> + // X64_MINGW-DAG: [[Z2_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDR]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // X64_MINGW-DAG: [[Z2_VAL:%[0-9A-Za-z]+]] = fir.load [[Z2_ADDRC]] : !fir.ref<!fir.complex<4>> + // X64_MINGW-DAG: [[Z1_ADDR:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW-DAG: fir.store [[Z1]] to [[Z1_ADDR]] : !fir.ref<i64> + // X64_MINGW-DAG: [[Z1_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z1_ADDR]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // X64_MINGW-DAG: [[Z1_VAL:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDRC]] : !fir.ref<!fir.complex<4>> + + // X64_MINGW-DAG: [[Z1_ADDRV:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW-DAG: [[Z1_ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[Z1_ADDRV]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // X64_MINGW-DAG: fir.store [[Z1_VAL]] to [[Z1_ADDRC2]] : !fir.ref<!fir.complex<4>> + // X64_MINGW-DAG: [[Z1_RELOADED:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDRV]] : !fir.ref<i64> + // X64_MINGW-DAG: [[Z2_ADDRV:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW-DAG: [[Z2_ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDRV]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // X64_MINGW-DAG: fir.store [[Z2_VAL]] to [[Z2_ADDRC2]] : !fir.ref<!fir.complex<4>> + // X64_MINGW-DAG: [[Z2_RELOADED:%[0-9A-Za-z]+]] = fir.load [[Z2_ADDRV]] : !fir.ref<i64> + // X64_MINGW-DAG: [[Z3_ADDRV:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW-DAG: [[Z3_ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[Z3_ADDRV]] : (!fir.ref<i64>) -> !fir.ref<!fir.complex<4>> + // X64_MINGW-DAG: fir.store [[Z3_VAL]] to [[Z3_ADDRC2]] : !fir.ref<!fir.complex<4>> + // X64_MINGW-DAG: [[Z3_RELOADED:%[0-9A-Za-z]+]] = fir.load [[Z3_ADDRV]] : !fir.ref<i64> + + // X64_MINGW: fir.call @calleemultipleparamscomplex4([[Z1_RELOADED]], [[Z2_RELOADED]], [[Z3_RELOADED]]) : (i64, i64, i64) -> () + // AARCH64-DAG: [[Z3_ARR:%[0-9A-Za-z]+]] = fir.alloca !fir.array<2x!fir.real<4>> // AARCH64-DAG: fir.store [[Z3]] to [[Z3_ARR]] : !fir.ref<!fir.array<2x!fir.real<4>>> // AARCH64-DAG: [[Z3_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z3_ARR]] : (!fir.ref<!fir.array<2x!fir.real<4>>>) -> !fir.ref<!fir.complex<4>> @@ -584,9 +739,15 @@ func.func @multipleparamscomplex4(%z1 : !fir.complex<4>, %z2 : !fir.complex<4>, // I32-LABEL: func private @mlircomplexf32 // I32-SAME: ([[Z1:%[0-9A-Za-z]+]]: !fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}, [[Z2:%[0-9A-Za-z]+]]: !fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}) // I32-SAME: -> i64 +// I32_MINGW-LABEL: func private @mlircomplexf32 +// I32_MINGW-SAME: ([[Z1:%[0-9A-Za-z]+]]: !fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}, [[Z2:%[0-9A-Za-z]+]]: !fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}) +// I32_MINGW-SAME: -> i64 // X64-LABEL: func private @mlircomplexf32 // X64-SAME: ([[Z1:%[0-9A-Za-z]+]]: !fir.vector<2:f32>, [[Z2:%[0-9A-Za-z]+]]: !fir.vector<2:f32>) // X64-SAME: -> !fir.vector<2:f32> +// X64_MINGW-LABEL: func private @mlircomplexf32 +// X64_MINGW-SAME: ([[Z1:%[0-9A-Za-z]+]]: i64, [[Z2:%[0-9A-Za-z]+]]: i64) +// X64_MINGW-SAME: -> i64 // AARCH64-LABEL: func private @mlircomplexf32 // AARCH64-SAME: ([[Z1:%[0-9A-Za-z]+]]: !fir.array<2xf32>, [[Z2:%[0-9A-Za-z]+]]: !fir.array<2xf32>) // AARCH64-SAME: -> tuple<f32, f32> @@ -618,6 +779,20 @@ func.func private @mlircomplexf32(%z1: complex<f32>, %z2: complex<f32>) -> compl // I32: [[VAL:%[0-9A-Za-z]+]] = fir.call @mlircomplexf32([[Z1_ADDRT]], [[Z2_ADDRT]]) : (!fir.ref<tuple<f32, f32>>, !fir.ref<tuple<f32, f32>>) -> i64 + // I32_MINGW-DAG: [[Z1_ADDR:%[0-9A-Za-z]+]] = fir.convert [[Z1]] : (!fir.ref<tuple<f32, f32>>) -> !fir.ref<complex<f32>> + // I32_MINGW-DAG: [[Z1_VAL:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDR]] : !fir.ref<complex<f32>> + // I32_MINGW-DAG: [[Z2_ADDR:%[0-9A-Za-z]+]] = fir.convert [[Z2]] : (!fir.ref<tuple<f32, f32>>) -> !fir.ref<complex<f32>> + // I32_MINGW-DAG: [[Z2_VAL:%[0-9A-Za-z]+]] = fir.load [[Z2_ADDR]] : !fir.ref<complex<f32>> + + // I32_MINGW-DAG: [[Z1_ADDRC:%[0-9A-Za-z]+]] = fir.alloca complex<f32> + // I32_MINGW-DAG: fir.store [[Z1_VAL]] to [[Z1_ADDRC]] : !fir.ref<complex<f32>> + // I32_MINGW-DAG: [[Z1_ADDRT:%[0-9A-Za-z]+]] = fir.convert [[Z1_ADDRC]] : (!fir.ref<complex<f32>>) -> !fir.ref<tuple<f32, f32>> + // I32_MINGW-DAG: [[Z2_ADDRC:%[0-9A-Za-z]+]] = fir.alloca complex<f32> + // I32_MINGW-DAG: fir.store [[Z2_VAL]] to [[Z2_ADDRC]] : !fir.ref<complex<f32>> + // I32_MINGW-DAG: [[Z2_ADDRT:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDRC]] : (!fir.ref<complex<f32>>) -> !fir.ref<tuple<f32, f32>> + + // I32_MINGW: [[VAL:%[0-9A-Za-z]+]] = fir.call @mlircomplexf32([[Z1_ADDRT]], [[Z2_ADDRT]]) : (!fir.ref<tuple<f32, f32>>, !fir.ref<tuple<f32, f32>>) -> i64 + // X64-DAG: [[Z2_ADDR:%[0-9A-Za-z]+]] = fir.alloca !fir.vector<2:f32> // X64-DAG: fir.store [[Z2]] to [[Z2_ADDR]] : !fir.ref<!fir.vector<2:f32>> // X64-DAG: [[Z2_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDR]] : (!fir.ref<!fir.vector<2:f32>>) -> !fir.ref<complex<f32>> @@ -638,6 +813,26 @@ func.func private @mlircomplexf32(%z1: complex<f32>, %z2: complex<f32>) -> compl // X64: [[VAL:%[0-9A-Za-z]+]] = fir.call @mlircomplexf32([[Z1_RELOADED]], [[Z2_RELOADED]]) : (!fir.vector<2:f32>, !fir.vector<2:f32>) -> !fir.vector<2:f32> + // X64_MINGW-DAG: [[Z2_ADDR:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW-DAG: fir.store [[Z2]] to [[Z2_ADDR]] : !fir.ref<i64> + // X64_MINGW-DAG: [[Z2_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDR]] : (!fir.ref<i64>) -> !fir.ref<complex<f32>> + // X64_MINGW-DAG: [[Z2_VAL:%[0-9A-Za-z]+]] = fir.load [[Z2_ADDRC]] : !fir.ref<complex<f32>> + // X64_MINGW-DAG: [[Z1_ADDR:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW-DAG: fir.store [[Z1]] to [[Z1_ADDR]] : !fir.ref<i64> + // X64_MINGW-DAG: [[Z1_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z1_ADDR]] : (!fir.ref<i64>) -> !fir.ref<complex<f32>> + // X64_MINGW-DAG: [[Z1_VAL:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDRC]] : !fir.ref<complex<f32>> + + // X64_MINGW-DAG: [[Z1_ADDRV:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW-DAG: [[Z1_ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[Z1_ADDRV]] : (!fir.ref<i64>) -> !fir.ref<complex<f32>> + // X64_MINGW-DAG: fir.store [[Z1_VAL]] to [[Z1_ADDRC2]] : !fir.ref<complex<f32>> + // X64_MINGW-DAG: [[Z1_RELOADED:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDRV]] : !fir.ref<i64> + // X64_MINGW-DAG: [[Z2_ADDRV:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW-DAG: [[Z2_ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDRV]] : (!fir.ref<i64>) -> !fir.ref<complex<f32>> + // X64_MINGW-DAG: fir.store [[Z2_VAL]] to [[Z2_ADDRC2]] : !fir.ref<complex<f32>> + // X64_MINGW-DAG: [[Z2_RELOADED:%[0-9A-Za-z]+]] = fir.load [[Z2_ADDRV]] : !fir.ref<i64> + + // X64_MINGW: [[VAL:%[0-9A-Za-z]+]] = fir.call @mlircomplexf32([[Z1_RELOADED]], [[Z2_RELOADED]]) : (i64, i64) -> i64 + // AARCH64-DAG: [[Z2_ARR:%[0-9A-Za-z]+]] = fir.alloca !fir.array<2xf32> // AARCH64-DAG: fir.store [[Z2]] to [[Z2_ARR]] : !fir.ref<!fir.array<2xf32>> // AARCH64-DAG: [[Z2_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z2_ARR]] : (!fir.ref<!fir.array<2xf32>>) -> !fir.ref<complex<f32>> @@ -725,6 +920,16 @@ func.func private @mlircomplexf32(%z1: complex<f32>, %z2: complex<f32>) -> compl // I32: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRI64_2]] : !fir.ref<i64> // I32: return [[RES]] : i64 + // I32_MINGW: [[ADDRI64:%[0-9A-Za-z]+]] = fir.alloca i64 + // I32_MINGW: fir.store [[VAL]] to [[ADDRI64]] : !fir.ref<i64> + // I32_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRI64]] : (!fir.ref<i64>) -> !fir.ref<complex<f32>> + // I32_MINGW: [[VAL_2:%[0-9A-Za-z]+]] = fir.load [[ADDRC]] : !fir.ref<complex<f32>> + // I32_MINGW: [[ADDRI64_2:%[0-9A-Za-z]+]] = fir.alloca i64 + // I32_MINGW: [[ADDRC_2:%[0-9A-Za-z]+]] = fir.convert [[ADDRI64_2]] : (!fir.ref<i64>) -> !fir.ref<complex<f32>> + // I32_MINGW: fir.store [[VAL_2]] to [[ADDRC_2]] : !fir.ref<complex<f32>> + // I32_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRI64_2]] : !fir.ref<i64> + // I32_MINGW: return [[RES]] : i64 + // X64: [[ADDRV:%[0-9A-Za-z]+]] = fir.alloca !fir.vector<2:f32> // X64: fir.store [[VAL]] to [[ADDRV]] : !fir.ref<!fir.vector<2:f32>> // X64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRV]] : (!fir.ref<!fir.vector<2:f32>>) -> !fir.ref<complex<f32>> @@ -735,6 +940,16 @@ func.func private @mlircomplexf32(%z1: complex<f32>, %z2: complex<f32>) -> compl // X64: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRV_2]] : !fir.ref<!fir.vector<2:f32>> // X64: return [[RES]] : !fir.vector<2:f32> + // X64_MINGW: [[ADDRV:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW: fir.store [[VAL]] to [[ADDRV]] : !fir.ref<i64> + // X64_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRV]] : (!fir.ref<i64>) -> !fir.ref<complex<f32>> + // X64_MINGW: [[V:%[0-9A-Za-z]+]] = fir.load [[ADDRC]] : !fir.ref<complex<f32>> + // X64_MINGW: [[ADDRV_2:%[0-9A-Za-z]+]] = fir.alloca i64 + // X64_MINGW: [[ADDRC_2:%[0-9A-Za-z]+]] = fir.convert [[ADDRV_2]] : (!fir.ref<i64>) -> !fir.ref<complex<f32>> + // X64_MINGW: fir.store [[V]] to [[ADDRC_2]] : !fir.ref<complex<f32>> + // X64_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRV_2]] : !fir.ref<i64> + // X64_MINGW: return [[RES]] : i64 + // AARCH64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple<f32, f32> // AARCH64: fir.store [[VAL]] to [[ADDRT]] : !fir.ref<tuple<f32, f32>> // AARCH64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref<tuple<f32, f32>>) -> !fir.ref<complex<f32>> @@ -789,7 +1004,9 @@ func.func private @mlircomplexf32(%z1: complex<f32>, %z2: complex<f32>) -> compl // Test that we rewrite the fir.address_of operator. // I32-LABEL: func @addrof() +// I32_MINGW-LABEL: func @addrof() // X64-LABEL: func @addrof() +// X64_MINGW-LABEL: func @addrof() // AARCH64-LABEL: func @addrof() // PPC64le-LABEL: func @addrof() // SPARCV9-LABEL: func @addrof() @@ -797,7 +1014,9 @@ func.func private @mlircomplexf32(%z1: complex<f32>, %z2: complex<f32>) -> compl // PPC64-LABEL: func @addrof() func.func @addrof() { // I32: {{%.*}} = fir.address_of(@returncomplex4) : () -> i64 + // I32_MINGW: {{%.*}} = fir.address_of(@returncomplex4) : () -> i64 // X64: {{%.*}} = fir.address_of(@returncomplex4) : () -> !fir.vector<2:!fir.real<4>> + // X64_MINGW: {{%.*}} = fir.address_of(@returncomplex4) : () -> i64 // AARCH64: {{%.*}} = fir.address_of(@returncomplex4) : () -> tuple<!fir.real<4>, !fir.real<4>> // PPC64le: {{%.*}} = fir.address_of(@returncomplex4) : () -> tuple<!fir.real<4>, !fir.real<4>> // RISCV64: {{%.*}} = fir.address_of(@returncomplex4) : () -> tuple<!fir.real<4>, !fir.real<4>> @@ -805,7 +1024,9 @@ func.func @addrof() { %r = fir.address_of(@returncomplex4) : () -> !fir.complex<4> // I32: {{%.*}} = fir.address_of(@paramcomplex4) : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> () + // I32_MINGW: {{%.*}} = fir.address_of(@paramcomplex4) : (!fir.ref<tuple<!fir.real<4>, !fir.real<4>>>) -> () // X64: {{%.*}} = fir.address_of(@paramcomplex4) : (!fir.vector<2:!fir.real<4>>) -> () + // X64_MINGW: {{%.*}} = fir.address_of(@paramcomplex4) : (i64) -> () // AARCH64: {{%.*}} = fir.address_of(@paramcomplex4) : (!fir.array<2x!fir.real<4>>) -> () // PPC64le: {{%.*}} = fir.address_of(@paramcomplex4) : (!fir.real<4>, !fir.real<4>) -> () // SPARCV9: {{%.*}} = fir.address_of(@paramcomplex4) : (!fir.real<4>, !fir.real<4>) -> () |