diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp index 6c148dffb0e55..5f746bf80e9d5 100644 --- a/flang/lib/Optimizer/CodeGen/Target.cpp +++ b/flang/lib/Optimizer/CodeGen/Target.cpp @@ -1091,6 +1091,13 @@ struct TargetLoongArch64 : public GenericTarget { // 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"); } @@ -1108,6 +1115,13 @@ struct TargetLoongArch64 : public GenericTarget { 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>.