[flang-commits] [flang] [Flang][LoongArch] Add support for complex16 params/returns. (PR #114732)

Zhaoxin Yang via flang-commits flang-commits at lists.llvm.org
Mon Nov 11 00:55:22 PST 2024


https://github.com/ylzsx updated https://github.com/llvm/llvm-project/pull/114732

>From 29dfc18dcc36ee4b604075ff02b9eae55d26d2f8 Mon Sep 17 00:00:00 2001
From: yangzhaoxin <yangzhaoxin at loongson.cn>
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 6c148dffb0e55a..43a039e46d143d 100644
--- a/flang/lib/Optimizer/CodeGen/Target.cpp
+++ b/flang/lib/Optimizer/CodeGen/Target.cpp
@@ -1087,7 +1087,8 @@ struct TargetLoongArch64 : public GenericTarget<TargetLoongArch64> {
     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<TargetLoongArch64> {
     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 <yangzhaoxin at loongson.cn>
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 43a039e46d143d..5f746bf80e9d5b 100644
--- a/flang/lib/Optimizer/CodeGen/Target.cpp
+++ b/flang/lib/Optimizer/CodeGen/Target.cpp
@@ -1087,11 +1087,17 @@ struct TargetLoongArch64 : public GenericTarget<TargetLoongArch64> {
     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<TargetLoongArch64> {
     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 4f807e828d8f10..86a5b0051ab2ed 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>.



More information about the flang-commits mailing list