From 1a586d3591b8da8a47212f276e5fe79f9a905e42 Mon Sep 17 00:00:00 2001 From: Alex Bradbury Date: Fri, 12 Jan 2018 20:08:16 +0000 Subject: [PATCH] Refactor handling of signext/zeroext in ABIArgInfo As @rjmccall suggested in D40023, we can get rid of ABIInfo::shouldSignExtUnsignedType (used to handle cases like the Mips calling convention where 32-bit integers are always sign extended regardless of the sign of the type) by adding a SignExt field to ABIArgInfo. In the common case, this new field is set automatically by ABIArgInfo::getExtend based on the sign of the type. For targets that want greater control, they can use ABIArgInfo::getSignExtend or ABIArgInfo::getZeroExtend when necessary. This change also cleans up logic in CGCall.cpp. There is no functional change intended in this patch, and all tests pass unchanged. As noted in D40023, Mips might want to sign-extend unsigned 32-bit integer return types. A future patch might modify MipsABIInfo::classifyReturnType to use MipsABIInfo::extendType. Differential Revision: https://reviews.llvm.org/D41999 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@322396 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/CodeGen/CGFunctionInfo.h | 39 +++++++++- lib/CodeGen/ABIInfo.h | 2 - lib/CodeGen/CGCall.cpp | 14 ++-- lib/CodeGen/TargetInfo.cpp | 98 ++++++++++++-------------- 4 files changed, 88 insertions(+), 65 deletions(-) diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h index d1f05124d5..42f963bad0 100644 --- a/include/clang/CodeGen/CGFunctionInfo.h +++ b/include/clang/CodeGen/CGFunctionInfo.h @@ -95,6 +95,7 @@ private: bool SRetAfterThis : 1; // isIndirect() bool InReg : 1; // isDirect() || isExtend() || isIndirect() bool CanBeFlattened: 1; // isDirect() + bool SignExt : 1; // isExtend() bool canHavePaddingType() const { return isDirect() || isExtend() || isIndirect() || isExpand(); @@ -133,15 +134,38 @@ public: AI.setInReg(true); return AI; } - static ABIArgInfo getExtend(llvm::Type *T = nullptr) { + + static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T = nullptr) { + assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType"); + auto AI = ABIArgInfo(Extend); + AI.setCoerceToType(T); + AI.setPaddingType(nullptr); + AI.setDirectOffset(0); + AI.setSignExt(true); + return AI; + } + + static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T = nullptr) { + assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType"); auto AI = ABIArgInfo(Extend); AI.setCoerceToType(T); AI.setPaddingType(nullptr); AI.setDirectOffset(0); + AI.setSignExt(false); return AI; } - static ABIArgInfo getExtendInReg(llvm::Type *T = nullptr) { - auto AI = getExtend(T); + + // ABIArgInfo will record the argument as being extended based on the sign + // of its type. + static ABIArgInfo getExtend(QualType Ty, llvm::Type *T = nullptr) { + assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType"); + if (Ty->hasSignedIntegerRepresentation()) + return getSignExtend(Ty, T); + return getZeroExtend(Ty, T); + } + + static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T = nullptr) { + auto AI = getExtend(Ty, T); AI.setInReg(true); return AI; } @@ -254,6 +278,15 @@ public: DirectOffset = Offset; } + bool isSignExt() const { + assert(isExtend() && "Invalid kind!"); + return SignExt; + } + void setSignExt(bool SExt) { + assert(isExtend() && "Invalid kind!"); + SignExt = SExt; + } + llvm::Type *getPaddingType() const { return (canHavePaddingType() ? PaddingType : nullptr); } diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h index 4cfc3d059d..fa0461f5d9 100644 --- a/lib/CodeGen/ABIInfo.h +++ b/lib/CodeGen/ABIInfo.h @@ -108,8 +108,6 @@ namespace swiftcall { virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, uint64_t Members) const; - virtual bool shouldSignExtUnsignedType(QualType Ty) const; - bool isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t &Members) const; diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 38d7344572..265173ee44 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1925,9 +1925,9 @@ void CodeGenModule::ConstructAttributeList( const ABIArgInfo &RetAI = FI.getReturnInfo(); switch (RetAI.getKind()) { case ABIArgInfo::Extend: - if (RetTy->hasSignedIntegerRepresentation()) + if (RetAI.isSignExt()) RetAttrs.addAttribute(llvm::Attribute::SExt); - else if (RetTy->hasUnsignedIntegerRepresentation()) + else RetAttrs.addAttribute(llvm::Attribute::ZExt); LLVM_FALLTHROUGH; case ABIArgInfo::Direct: @@ -2006,14 +2006,10 @@ void CodeGenModule::ConstructAttributeList( // sense to do it here because parameters are so messed up. switch (AI.getKind()) { case ABIArgInfo::Extend: - if (ParamType->isSignedIntegerOrEnumerationType()) + if (AI.isSignExt()) Attrs.addAttribute(llvm::Attribute::SExt); - else if (ParamType->isUnsignedIntegerOrEnumerationType()) { - if (getTypes().getABIInfo().shouldSignExtUnsignedType(ParamType)) - Attrs.addAttribute(llvm::Attribute::SExt); - else - Attrs.addAttribute(llvm::Attribute::ZExt); - } + else + Attrs.addAttribute(llvm::Attribute::ZExt); LLVM_FALLTHROUGH; case ABIArgInfo::Direct: if (ArgNo == 0 && FI.isChainCall()) diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index e3f3ba1be4..84719428ba 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -201,10 +201,6 @@ bool ABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base, return false; } -bool ABIInfo::shouldSignExtUnsignedType(QualType Ty) const { - return false; -} - LLVM_DUMP_METHOD void ABIArgInfo::dump() const { raw_ostream &OS = llvm::errs(); OS << "(ABIArgInfo Kind="; @@ -682,8 +678,8 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { if (const EnumType *EnumTy = Ty->getAs()) Ty = EnumTy->getDecl()->getIntegerType(); - return (Ty->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty) + : ABIArgInfo::getDirect()); } ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const { @@ -697,8 +693,8 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const { if (const EnumType *EnumTy = RetTy->getAs()) RetTy = EnumTy->getDecl()->getIntegerType(); - return (RetTy->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy) + : ABIArgInfo::getDirect()); } //===----------------------------------------------------------------------===// @@ -845,8 +841,8 @@ ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty) const { return ABIArgInfo::getDirect(); } - return (Ty->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty) + : ABIArgInfo::getDirect()); } ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const { @@ -861,8 +857,8 @@ ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const { if (const EnumType *EnumTy = RetTy->getAs()) RetTy = EnumTy->getDecl()->getIntegerType(); - return (RetTy->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy) + : ABIArgInfo::getDirect()); } /// IsX86_MMXType - Return true if this is an MMX type. @@ -1403,8 +1399,8 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, if (const EnumType *EnumTy = RetTy->getAs()) RetTy = EnumTy->getDecl()->getIntegerType(); - return (RetTy->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy) + : ABIArgInfo::getDirect()); } static bool isSSEVectorType(ASTContext &Context, QualType Ty) { @@ -1676,8 +1672,8 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, if (Ty->isPromotableIntegerType()) { if (InReg) - return ABIArgInfo::getExtendInReg(); - return ABIArgInfo::getExtend(); + return ABIArgInfo::getExtendInReg(Ty); + return ABIArgInfo::getExtend(Ty); } if (InReg) @@ -2865,8 +2861,8 @@ ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const { if (const EnumType *EnumTy = Ty->getAs()) Ty = EnumTy->getDecl()->getIntegerType(); - return (Ty->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty) + : ABIArgInfo::getDirect()); } return getNaturalAlignIndirect(Ty); @@ -2898,8 +2894,8 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty, if (const EnumType *EnumTy = Ty->getAs()) Ty = EnumTy->getDecl()->getIntegerType(); - return (Ty->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty) + : ABIArgInfo::getDirect()); } if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) @@ -3268,7 +3264,7 @@ classifyReturnType(QualType RetTy) const { if (RetTy->isIntegralOrEnumerationType() && RetTy->isPromotableIntegerType()) - return ABIArgInfo::getExtend(); + return ABIArgInfo::getExtend(RetTy); } break; @@ -3413,7 +3409,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType( if (Ty->isIntegralOrEnumerationType() && Ty->isPromotableIntegerType()) - return ABIArgInfo::getExtend(); + return ABIArgInfo::getExtend(Ty); } break; @@ -3938,7 +3934,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs, // extended. const BuiltinType *BT = Ty->getAs(); if (BT && BT->getKind() == BuiltinType::Bool) - return ABIArgInfo::getExtend(); + return ABIArgInfo::getExtend(Ty); // Mingw64 GCC uses the old 80 bit extended precision floating point unit. It // passes them indirectly through memory. @@ -4691,8 +4687,8 @@ PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { /*Realign=*/TyAlign > ABIAlign); } - return (isPromotableTypeForABI(Ty) ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) + : ABIArgInfo::getDirect()); } ABIArgInfo @@ -4746,8 +4742,8 @@ PPC64_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { return getNaturalAlignIndirect(RetTy); } - return (isPromotableTypeForABI(RetTy) ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (isPromotableTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) + : ABIArgInfo::getDirect()); } // Based on ARMABIInfo::EmitVAArg, adjusted for 64-bit machine. @@ -4998,7 +4994,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty) const { Ty = EnumTy->getDecl()->getIntegerType(); return (Ty->isPromotableIntegerType() && isDarwinPCS() - ? ABIArgInfo::getExtend() + ? ABIArgInfo::getExtend(Ty) : ABIArgInfo::getDirect()); } @@ -5068,7 +5064,7 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy) const { RetTy = EnumTy->getDecl()->getIntegerType(); return (RetTy->isPromotableIntegerType() && isDarwinPCS() - ? ABIArgInfo::getExtend() + ? ABIArgInfo::getExtend(RetTy) : ABIArgInfo::getDirect()); } @@ -5741,7 +5737,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, Ty = EnumTy->getDecl()->getIntegerType(); } - return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend() + return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty) : ABIArgInfo::getDirect()); } @@ -5938,7 +5934,7 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, if (const EnumType *EnumTy = RetTy->getAs()) RetTy = EnumTy->getDecl()->getIntegerType(); - return RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend() + return RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy) : ABIArgInfo::getDirect(); } @@ -6171,8 +6167,8 @@ ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const { if (const EnumType *EnumTy = RetTy->getAs()) RetTy = EnumTy->getDecl()->getIntegerType(); - return (RetTy->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy) + : ABIArgInfo::getDirect()); } ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const { @@ -6184,8 +6180,8 @@ ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const { if (isAggregateTypeForABI(Ty)) return getNaturalAlignIndirect(Ty, /* byval */ true); - return (Ty->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty) + : ABIArgInfo::getDirect()); } void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const { @@ -6580,8 +6576,8 @@ ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const { return ABIArgInfo::getDirect(); if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64) return getNaturalAlignIndirect(RetTy); - return (isPromotableIntegerType(RetTy) ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (isPromotableIntegerType(RetTy) ? ABIArgInfo::getExtend(RetTy) + : ABIArgInfo::getDirect()); } ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { @@ -6591,7 +6587,7 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { // Integers and enums are extended to full register width. if (isPromotableIntegerType(Ty)) - return ABIArgInfo::getExtend(); + return ABIArgInfo::getExtend(Ty); // Handle vector types and vector-like structure types. Note that // as opposed to float-like structure types, we do not allow any @@ -6699,7 +6695,7 @@ public: void computeInfo(CGFunctionInfo &FI) const override; Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const override; - bool shouldSignExtUnsignedType(QualType Ty) const override; + ABIArgInfo extendType(QualType Ty) const; }; class MIPSTargetCodeGenInfo : public TargetCodeGenInfo { @@ -6892,7 +6888,7 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const { // All integral types are promoted to the GPR width. if (Ty->isIntegralOrEnumerationType()) - return ABIArgInfo::getExtend(); + return extendType(Ty); return ABIArgInfo::getDirect( nullptr, 0, IsO32 ? nullptr : getPaddingType(OrigOffset, CurrOffset)); @@ -6974,8 +6970,8 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { if (const EnumType *EnumTy = RetTy->getAs()) RetTy = EnumTy->getDecl()->getIntegerType(); - return (RetTy->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy) + : ABIArgInfo::getDirect()); } void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const { @@ -7041,14 +7037,14 @@ Address MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, return Addr; } -bool MipsABIInfo::shouldSignExtUnsignedType(QualType Ty) const { +ABIArgInfo MipsABIInfo::extendType(QualType Ty) const { int TySize = getContext().getTypeSize(Ty); // MIPS64 ABI requires unsigned 32 bit integers to be sign extended. if (Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32) - return true; + return ABIArgInfo::getSignExtend(Ty); - return false; + return ABIArgInfo::getExtend(Ty); } bool @@ -7221,8 +7217,8 @@ ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty) const { if (const EnumType *EnumTy = Ty->getAs()) Ty = EnumTy->getDecl()->getIntegerType(); - return (Ty->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty) + : ABIArgInfo::getDirect()); } if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) @@ -7259,8 +7255,8 @@ ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy) const { if (const EnumType *EnumTy = RetTy->getAs()) RetTy = EnumTy->getDecl()->getIntegerType(); - return (RetTy->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy) + : ABIArgInfo::getDirect()); } if (isEmptyRecord(getContext(), RetTy, true)) @@ -7403,7 +7399,7 @@ ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty, if (Ty->isPromotableIntegerType()) { if (InReg) return ABIArgInfo::getDirectInReg(); - return ABIArgInfo::getExtend(); + return ABIArgInfo::getExtend(Ty); } if (InReg) return ABIArgInfo::getDirectInReg(); @@ -7985,7 +7981,7 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const { // Integer types smaller than a register are extended. if (Size < 64 && Ty->isIntegerType()) - return ABIArgInfo::getExtend(); + return ABIArgInfo::getExtend(Ty); // Other non-aggregates go in registers. if (!isAggregateTypeForABI(Ty)) -- 2.40.0