Index: include/clang/CodeGen/CGFunctionInfo.h =================================================================== --- include/clang/CodeGen/CGFunctionInfo.h +++ include/clang/CodeGen/CGFunctionInfo.h @@ -95,6 +95,7 @@ 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 @@ 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 getExtendInReg(llvm::Type *T = nullptr) { - auto AI = getExtend(T); + + 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; + } + + // 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 @@ 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); } Index: lib/CodeGen/ABIInfo.h =================================================================== --- lib/CodeGen/ABIInfo.h +++ lib/CodeGen/ABIInfo.h @@ -108,8 +108,6 @@ 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; Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1925,9 +1925,9 @@ 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 @@ // 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()) Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -201,10 +201,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ if (RetTy->isIntegralOrEnumerationType() && RetTy->isPromotableIntegerType()) - return ABIArgInfo::getExtend(); + return ABIArgInfo::getExtend(RetTy); } break; @@ -3413,7 +3409,7 @@ if (Ty->isIntegralOrEnumerationType() && Ty->isPromotableIntegerType()) - return ABIArgInfo::getExtend(); + return ABIArgInfo::getExtend(Ty); } break; @@ -3938,7 +3934,7 @@ // 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 @@ /*Realign=*/TyAlign > ABIAlign); } - return (isPromotableTypeForABI(Ty) ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) + : ABIArgInfo::getDirect()); } ABIArgInfo @@ -4746,8 +4742,8 @@ 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 @@ Ty = EnumTy->getDecl()->getIntegerType(); return (Ty->isPromotableIntegerType() && isDarwinPCS() - ? ABIArgInfo::getExtend() + ? ABIArgInfo::getExtend(Ty) : ABIArgInfo::getDirect()); } @@ -5068,7 +5064,7 @@ RetTy = EnumTy->getDecl()->getIntegerType(); return (RetTy->isPromotableIntegerType() && isDarwinPCS() - ? ABIArgInfo::getExtend() + ? ABIArgInfo::getExtend(RetTy) : ABIArgInfo::getDirect()); } @@ -5741,7 +5737,7 @@ Ty = EnumTy->getDecl()->getIntegerType(); } - return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend() + return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty) : ABIArgInfo::getDirect()); } @@ -5938,7 +5934,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ if (Ty->isPromotableIntegerType()) { if (InReg) return ABIArgInfo::getDirectInReg(); - return ABIArgInfo::getExtend(); + return ABIArgInfo::getExtend(Ty); } if (InReg) return ABIArgInfo::getDirectInReg(); @@ -7985,7 +7981,7 @@ // 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))