Author: carwil
Date: Fri Mar 22 09:20:45 2019
New Revision: 356776
URL: http://llvm.org/viewvc/llvm-project?rev=356776&view=rev
Log:
[ARM] Fix bug 39982 - pcs("aapcs-vfp") is not consistent
Correctly handle homogeneous aggregates when a
function's ABI is specified via the pcs attribute.
Bug: https://bugs.llvm.org/show_bug.cgi?id=39982
Differential Revision: https://reviews.llvm.org/D59094
Added:
cfe/trunk/test/CodeGenCXX/arm-pcs.cpp
Modified:
cfe/trunk/lib/CodeGen/TargetInfo.cpp
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=356776&r1=356775&r2=356776&view=diff
==
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Fri Mar 22 09:20:45 2019
@@ -5597,8 +5597,10 @@ public:
ABIKind getABIKind() const { return Kind; }
private:
- ABIArgInfo classifyReturnType(QualType RetTy, bool isVariadic) const;
- ABIArgInfo classifyArgumentType(QualType RetTy, bool isVariadic) const;
+ ABIArgInfo classifyReturnType(QualType RetTy, bool isVariadic,
+unsigned functionCallConv) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy, bool isVariadic,
+ unsigned functionCallConv) const;
ABIArgInfo classifyHomogeneousAggregate(QualType Ty, const Type *Base,
uint64_t Members) const;
ABIArgInfo coerceIllegalVector(QualType Ty) const;
@@ -5608,6 +5610,8 @@ private:
bool isHomogeneousAggregateSmallEnough(const Type *Ty,
uint64_t Members) const override;
+ bool isEffectivelyAAPCS_VFP(unsigned callConvention, bool acceptHalf) const;
+
void computeInfo(CGFunctionInfo &FI) const override;
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
@@ -5728,11 +5732,13 @@ void WindowsARMTargetCodeGenInfo::setTar
void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
if (!::classifyReturnType(getCXXABI(), FI, *this))
-FI.getReturnInfo() =
-classifyReturnType(FI.getReturnType(), FI.isVariadic());
+FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
FI.isVariadic(),
+FI.getCallingConvention());
for (auto &I : FI.arguments())
-I.info = classifyArgumentType(I.type, FI.isVariadic());
+I.info = classifyArgumentType(I.type, FI.isVariadic(),
+ FI.getCallingConvention());
+
// Always honor user-specified calling convention.
if (FI.getCallingConvention() != llvm::CallingConv::C)
@@ -5811,8 +5817,8 @@ ABIArgInfo ARMABIInfo::classifyHomogeneo
return ABIArgInfo::getDirect(nullptr, 0, nullptr, false);
}
-ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
-bool isVariadic) const {
+ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic,
+unsigned functionCallConv) const {
// 6.1.2.1 The following argument types are VFP CPRCs:
// A single-precision floating-point type (including promoted
// half-precision types); A double-precision floating-point type;
@@ -5820,7 +5826,9 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
// with a Base Type of a single- or double-precision floating-point type,
// 64-bit containerized vectors or 128-bit containerized vectors with one
// to four Elements.
- bool IsEffectivelyAAPCS_VFP = getABIKind() == AAPCS_VFP && !isVariadic;
+ // Variadic functions should always marshal to the base standard.
+ bool IsAAPCS_VFP =
+ !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv, /* AAPCS16 */
false);
Ty = useFirstFieldIfTransparentUnion(Ty);
@@ -5833,7 +5841,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
// half type natively, and does not need to interwork with AAPCS code.
if ((Ty->isFloat16Type() || Ty->isHalfType()) &&
!getContext().getLangOpts().NativeHalfArgsAndReturns) {
-llvm::Type *ResType = IsEffectivelyAAPCS_VFP ?
+llvm::Type *ResType = IsAAPCS_VFP ?
llvm::Type::getFloatTy(getVMContext()) :
llvm::Type::getInt32Ty(getVMContext());
return ABIArgInfo::getDirect(ResType);
@@ -5857,7 +5865,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
if (isEmptyRecord(getContext(), Ty, true))
return ABIArgInfo::getIgnore();
- if (IsEffectivelyAAPCS_VFP) {
+ if (IsAAPCS_VFP) {
// Homogeneous Aggregates need to be expanded when we can fit the aggregate
// into VFP registers.
const Type *Base = nullptr;
@@ -6014,10 +6022,12 @@ static bool isIntegerLikeType(QualType T
return true;
}
-ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
- bool isVariadic) const {
- bool IsEffectivelyAAPCS_VFP =
- (getABIKind() == AAPCS_VFP || getABIKind() == AAPCS16_VFP) &&