diff options
author | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2012-10-12 19:26:17 +0000 |
---|---|---|
committer | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2012-10-12 19:26:17 +0000 |
commit | b1f5fe017a596e0c7749dee10c9d3ff1c0f2788c (patch) | |
tree | 3b161601dfacadac22fcde63c540f5c8ba7b8698 /lib/CodeGen | |
parent | 44cbe67dc0e0a35c5369689710a25603ba67356f (diff) |
This patch addresses PR13948.
For 64-bit PowerPC SVR4, an aggregate containing only one
floating-point field (float, double, or long double) must be passed in
a register as though just that field were present. This patch
addresses the issue during Clang code generation by specifying in the
ABIArgInfo for the argument that the underlying type is passed
directly in a register. The included test case verifies flat and
nested structs for the three data types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165816 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 21318b37c2..fe85283930 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -2602,13 +2602,31 @@ class PPC64_SVR4_ABIInfo : public DefaultABIInfo { public: PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} - // TODO: Could override computeInfo to model the ABI more completely if - // it would be helpful. Example: We might remove the byVal flag from - // aggregate arguments that fit in a register to avoid pushing them to - // memory on function entry. Note that this is a performance optimization, - // not a compliance issue. In general we prefer to keep ABI details in - // the back end where possible, but modifying an argument flag seems like - // a good thing to do before invoking the back end. + // TODO: We can add more logic to computeInfo to improve performance. + // Example: For aggregate arguments that fit in a register, we could + // use getDirectInReg (as is done below for structs containing a single + // floating-point value) to avoid pushing them to memory on function + // entry. This would require changing the logic in PPCISelLowering + // when lowering the parameters in the caller and args in the callee. + virtual void computeInfo(CGFunctionInfo &FI) const { + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); + it != ie; ++it) { + // We rely on the default argument classification for the most part. + // One exception: An aggregate containing a single floating-point + // item must be passed in a register if one is available. + const Type *T = isSingleElementStruct(it->type, getContext()); + if (T) { + const BuiltinType *BT = T->getAs<BuiltinType>(); + if (BT && BT->isFloatingPoint()) { + QualType QT(T, 0); + it->info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT)); + continue; + } + } + it->info = classifyArgumentType(it->type); + } + } virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, |