summaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/CodeGen/Target.cpp
diff options
context:
space:
mode:
authorjeanPerier <jperier@nvidia.com>2023-12-04 09:47:12 +0100
committerGitHub <noreply@github.com>2023-12-04 09:47:12 +0100
commitf65e3af73dd507568bcb645e1fcb3ddb738fb809 (patch)
tree193dfbcaed0cd9c7cdffd354eb27ff0c7acb026f /flang/lib/Optimizer/CodeGen/Target.cpp
parent71f2ec2db1295462d61e1407fcc1e715ba5d458b (diff)
[flang] Implement COMPLEX(10) passing and return ABI for X86-64 linux (#74094)
COMPLEX(10) passing by value and returning follows C complex passing/returning ABI. Cover the COMPLEX(10) case (X87 / __Complex long double on X86-64). Implements System V ABI for AMD64 version 1.0. The LLVM signatures match the one generated by clang for the __Complex long double case. Note that a FIXME is added for the COMPLEX(8) case that is incorrect in a corner case. This will be fixed when dealing with passing derived type by value in BIND(C) context.
Diffstat (limited to 'flang/lib/Optimizer/CodeGen/Target.cpp')
-rw-r--r--flang/lib/Optimizer/CodeGen/Target.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp
index b136c8f7a9dd..112f56e268c3 100644
--- a/flang/lib/Optimizer/CodeGen/Target.cpp
+++ b/flang/lib/Optimizer/CodeGen/Target.cpp
@@ -261,9 +261,20 @@ struct TargetX86_64 : public GenericTarget<TargetX86_64> {
// <2 x t> vector of 2 eleTy
marshal.emplace_back(fir::VectorType::get(2, eleTy), AT{});
} else if (sem == &llvm::APFloat::IEEEdouble()) {
+ // FIXME: In case of SSE register exhaustion, the ABI here may be
+ // incorrect since LLVM may pass the real via register and the imaginary
+ // part via the stack while the ABI it should be all in register or all
+ // in memory. Register occupancy must be analyzed here.
// two distinct double arguments
marshal.emplace_back(eleTy, AT{});
marshal.emplace_back(eleTy, AT{});
+ } else if (sem == &llvm::APFloat::x87DoubleExtended()) {
+ // Use a type that will be translated into LLVM as:
+ // { x86_fp80, x86_fp80 } struct of 2 fp128, byval, align 16
+ marshal.emplace_back(
+ fir::ReferenceType::get(mlir::TupleType::get(
+ eleTy.getContext(), mlir::TypeRange{eleTy, eleTy})),
+ AT{/*align=*/16, /*byval=*/true});
} else if (sem == &llvm::APFloat::IEEEquad()) {
// Use a type that will be translated into LLVM as:
// { fp128, fp128 } struct of 2 fp128, byval, align 16
@@ -290,6 +301,11 @@ struct TargetX86_64 : public GenericTarget<TargetX86_64> {
marshal.emplace_back(mlir::TupleType::get(eleTy.getContext(),
mlir::TypeRange{eleTy, eleTy}),
AT{});
+ } else if (sem == &llvm::APFloat::x87DoubleExtended()) {
+ // { x86_fp80, x86_fp80 }
+ marshal.emplace_back(mlir::TupleType::get(eleTy.getContext(),
+ mlir::TypeRange{eleTy, eleTy}),
+ AT{});
} 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