From 29dfc18dcc36ee4b604075ff02b9eae55d26d2f8 Mon Sep 17 00:00:00 2001 From: yangzhaoxin Date: Tue, 29 Oct 2024 09:15:07 +0800 Subject: [PATCH 1/2] [Flang][LoongArch] Add support for complex16 params/returns. This patch fixes the failure in flang test `Integration/debug-complex-1.f90`: ``` llvm-project/flang/lib/Optimizer/codeGen/Target.cpp:56: not yet implemented: complex for this precision for return type ``` --- flang/lib/Optimizer/CodeGen/Target.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp index 6c148dffb0e55..43a039e46d143 100644 --- a/flang/lib/Optimizer/CodeGen/Target.cpp +++ b/flang/lib/Optimizer/CodeGen/Target.cpp @@ -1087,7 +1087,8 @@ struct TargetLoongArch64 : public GenericTarget { CodeGenSpecifics::Marshalling marshal; const auto *sem = &floatToSemantics(kindMap, eleTy); if (sem == &llvm::APFloat::IEEEsingle() || - sem == &llvm::APFloat::IEEEdouble()) { + sem == &llvm::APFloat::IEEEdouble() || + sem == &llvm::APFloat::IEEEquad()) { // Two distinct element type arguments (re, im) marshal.emplace_back(eleTy, AT{}); marshal.emplace_back(eleTy, AT{}); @@ -1102,7 +1103,8 @@ struct TargetLoongArch64 : public GenericTarget { CodeGenSpecifics::Marshalling marshal; const auto *sem = &floatToSemantics(kindMap, eleTy); if (sem == &llvm::APFloat::IEEEsingle() || - sem == &llvm::APFloat::IEEEdouble()) { + sem == &llvm::APFloat::IEEEdouble() || + sem == &llvm::APFloat::IEEEquad()) { // Use a type that will be translated into LLVM as: // { t, t } struct of 2 eleTy, byVal marshal.emplace_back(mlir::TupleType::get(eleTy.getContext(), From 499a259afec6def049a80b0ff0ea1aa017d1e234 Mon Sep 17 00:00:00 2001 From: yangzhaoxin Date: Mon, 11 Nov 2024 14:09:13 +0800 Subject: [PATCH 2/2] [Flang][LoongArch] Add support for complex16 params/returns. In LoongArch64, the passing and returning of type `complex16` is similar to that of structure type like `struct {fp128, fp128}`, meaning they are passed and returned by reference. This behavior is similar to clang, so it can implement conveniently `iso_c_binding`. Additionally, this patch fixes the failure in flang test Integration/debug-complex-1.f90: ``` llvm-project/flang/lib/Optimizer/codeGen/Target.cpp:56: not yet implemented: complex for this precision for return type ``` --- flang/lib/Optimizer/CodeGen/Target.cpp | 20 ++++++++++++++++---- flang/test/Fir/target-rewrite-complex16.fir | 1 + 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp index 43a039e46d143..5f746bf80e9d5 100644 --- a/flang/lib/Optimizer/CodeGen/Target.cpp +++ b/flang/lib/Optimizer/CodeGen/Target.cpp @@ -1087,11 +1087,17 @@ struct TargetLoongArch64 : public GenericTarget { CodeGenSpecifics::Marshalling marshal; const auto *sem = &floatToSemantics(kindMap, eleTy); if (sem == &llvm::APFloat::IEEEsingle() || - sem == &llvm::APFloat::IEEEdouble() || - sem == &llvm::APFloat::IEEEquad()) { + sem == &llvm::APFloat::IEEEdouble()) { // Two distinct element type arguments (re, im) marshal.emplace_back(eleTy, AT{}); marshal.emplace_back(eleTy, AT{}); + } else if (sem == &llvm::APFloat::IEEEquad()) { + // Use a type that will be translated into LLVM as: + // { fp128, fp128 } struct of 2 fp128, byval + marshal.emplace_back( + fir::ReferenceType::get(mlir::TupleType::get( + eleTy.getContext(), mlir::TypeRange{eleTy, eleTy})), + AT{/*align=*/16, /*byval=*/true}); } else { typeTodo(sem, loc, "argument"); } @@ -1103,13 +1109,19 @@ struct TargetLoongArch64 : public GenericTarget { CodeGenSpecifics::Marshalling marshal; const auto *sem = &floatToSemantics(kindMap, eleTy); if (sem == &llvm::APFloat::IEEEsingle() || - sem == &llvm::APFloat::IEEEdouble() || - sem == &llvm::APFloat::IEEEquad()) { + sem == &llvm::APFloat::IEEEdouble()) { // Use a type that will be translated into LLVM as: // { t, t } struct of 2 eleTy, byVal marshal.emplace_back(mlir::TupleType::get(eleTy.getContext(), mlir::TypeRange{eleTy, eleTy}), AT{/*alignment=*/0, /*byval=*/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 { typeTodo(sem, loc, "return"); } diff --git a/flang/test/Fir/target-rewrite-complex16.fir b/flang/test/Fir/target-rewrite-complex16.fir index 4f807e828d8f1..86a5b0051ab2e 100644 --- a/flang/test/Fir/target-rewrite-complex16.fir +++ b/flang/test/Fir/target-rewrite-complex16.fir @@ -1,4 +1,5 @@ // RUN: fir-opt --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s +// RUN: fir-opt --target-rewrite="target=loongarch64-unknown-linux-gnu" %s | FileCheck %s // Test that we rewrite the signature and body of a func.function that returns a // complex<16>.