int getEHDataRegisterNumber(unsigned RegNo) const override;
bool hasInt128Type() const override;
+
+ bool hasExtIntType() const override { return true; }
};
class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo {
}
void setAuxTarget(const TargetInfo *Aux) override;
+
+ bool hasExtIntType() const override { return true; }
};
} // namespace targets
TargetInfo::ConstraintInfo &Info) const override {
return false;
}
+
+ bool hasExtIntType() const override { return true; }
};
} // namespace targets
int getEHDataRegisterNumber(unsigned RegNo) const override;
bool hasSjLjLowering() const override;
+
+ bool hasExtIntType() const override { return true; }
};
class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo {
// We can write more stricter checks later.
return CPU.find('t') != std::string::npos;
}
+
+ bool hasExtIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
}
const char *getClobbers() const override { return ""; }
+
+ bool hasExtIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
unsigned getUnwindWordWidth() const override;
bool validateTarget(DiagnosticsEngine &Diags) const override;
+ bool hasExtIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
return HostTarget->checkCallingConvention(CC);
return CCCR_Warning;
}
+
+ bool hasExtIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
}
const char *getClobbers() const override { return ""; }
+
+ bool hasExtIntType() const override { return true; }
};
// We attempt to use PNaCl (le32) frontend and Mips32EL backend.
: "u9__ieee128";
}
const char *getFloat128Mangling() const override { return "u9__ieee128"; }
+
+ bool hasExtIntType() const override { return true; }
};
class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo {
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override;
+
+ bool hasExtIntType() const override { return true; }
};
class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
public:
// for SPIR since it is a generic target.
getSupportedOpenCLOpts().supportAll();
}
+
+ bool hasExtIntType() const override { return true; }
};
class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
public:
MacroBuilder &Builder) const override;
bool hasSjLjLowering() const override { return true; }
+ bool hasExtIntType() const override { return true; }
};
// SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
return false;
return getCPUGeneration(CPU) == CG_V9;
}
+
+ bool hasExtIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
}
const char *getLongDoubleMangling() const override { return "g"; }
+
+ bool hasExtIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
return CCCR_Warning;
}
}
+
+ bool hasExtIntType() const override { return true; }
};
class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
: public WebAssemblyTargetInfo {
}
bool allowsLargerPreferedTypeAlignment() const override { return false; }
+
+ bool hasExtIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
uint64_t &Members) const;
+ // Implement the Type::IsPromotableIntegerType for ABI specific needs. The
+ // only difference is that this considers _ExtInt as well.
+ bool isPromotableIntegerTypeForABI(QualType Ty) const;
+
/// A convenience method to return an indirect ABIArgInfo with an
/// expected alignment equal to the ABI alignment of the given type.
CodeGen::ABIArgInfo
return Address::invalid();
}
+bool ABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
+ if (Ty->isPromotableIntegerType())
+ return true;
+
+ if (const auto *EIT = Ty->getAs<ExtIntType>())
+ if (EIT->getNumBits() < getContext().getTypeSize(getContext().IntTy))
+ return true;
+
+ return false;
+}
+
ABIInfo::~ABIInfo() {}
/// Does the given lowering require more than the given number of
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
- return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
- : ABIArgInfo::getDirect());
+ ASTContext &Context = getContext();
+ if (const auto *EIT = Ty->getAs<ExtIntType>())
+ if (EIT->getNumBits() >
+ Context.getTypeSize(Context.getTargetInfo().hasInt128Type()
+ ? Context.Int128Ty
+ : Context.LongLongTy))
+ return getNaturalAlignIndirect(Ty);
+
+ return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+ : ABIArgInfo::getDirect());
}
ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
RetTy = EnumTy->getDecl()->getIntegerType();
- return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
- : ABIArgInfo::getDirect());
+ if (const auto *EIT = RetTy->getAs<ExtIntType>())
+ if (EIT->getNumBits() >
+ getContext().getTypeSize(getContext().getTargetInfo().hasInt128Type()
+ ? getContext().Int128Ty
+ : getContext().LongLongTy))
+ return getNaturalAlignIndirect(RetTy);
+
+ return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+ : ABIArgInfo::getDirect());
}
//===----------------------------------------------------------------------===//
} else if (Ty->isFloatingType()) {
// Floating-point types don't go inreg.
return ABIArgInfo::getDirect();
+ } else if (const auto *EIT = Ty->getAs<ExtIntType>()) {
+ // Treat extended integers as integers if <=64, otherwise pass indirectly.
+ if (EIT->getNumBits() > 64)
+ return getNaturalAlignIndirect(Ty);
+ return ABIArgInfo::getDirect();
}
- return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
- : ABIArgInfo::getDirect());
+ return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+ : ABIArgInfo::getDirect());
}
ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const {
if (isAggregateTypeForABI(RetTy))
return getNaturalAlignIndirect(RetTy);
+ // Treat extended integers as integers if <=64, otherwise pass indirectly.
+ if (const auto *EIT = RetTy->getAs<ExtIntType>()) {
+ if (EIT->getNumBits() > 64)
+ return getNaturalAlignIndirect(RetTy);
+ return ABIArgInfo::getDirect();
+ }
+
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
RetTy = EnumTy->getDecl()->getIntegerType();
- return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
- : ABIArgInfo::getDirect());
+ return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+ : ABIArgInfo::getDirect());
}
/// IsX86_MMXType - Return true if this is an MMX type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
RetTy = EnumTy->getDecl()->getIntegerType();
- return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
- : ABIArgInfo::getDirect());
+ if (const auto *EIT = RetTy->getAs<ExtIntType>())
+ if (EIT->getNumBits() > 64)
+ return getIndirectReturnResult(RetTy, State);
+
+ return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+ : ABIArgInfo::getDirect());
}
static bool isSSEVectorType(ASTContext &Context, QualType Ty) {
bool InReg = shouldPrimitiveUseInReg(Ty, State);
- if (Ty->isPromotableIntegerType()) {
+ if (isPromotableIntegerTypeForABI(Ty)) {
if (InReg)
return ABIArgInfo::getExtendInReg(Ty);
return ABIArgInfo::getExtend(Ty);
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
- if (!Ty->isExtIntType())
- return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
- : ABIArgInfo::getDirect());
+ if (Ty->isExtIntType())
+ return getNaturalAlignIndirect(Ty);
+
+ return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+ : ABIArgInfo::getDirect());
}
return getNaturalAlignIndirect(Ty);
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
- return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
- : ABIArgInfo::getDirect());
+ return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+ : ABIArgInfo::getDirect());
}
if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
RetTy = EnumTy->getDecl()->getIntegerType();
if (RetTy->isIntegralOrEnumerationType() &&
- RetTy->isPromotableIntegerType())
+ isPromotableIntegerTypeForABI(RetTy))
return ABIArgInfo::getExtend(RetTy);
}
break;
Ty = EnumTy->getDecl()->getIntegerType();
if (Ty->isIntegralOrEnumerationType() &&
- Ty->isPromotableIntegerType())
+ isPromotableIntegerTypeForABI(Ty))
return ABIArgInfo::getExtend(Ty);
}
Ty = EnumTy->getDecl()->getIntegerType();
// Promotable integer types are required to be promoted by the ABI.
- if (Ty->isPromotableIntegerType())
+ if (isPromotableIntegerTypeForABI(Ty))
return true;
// In addition to the usual promotable integer types, we also need to
break;
}
+ if (const auto *EIT = Ty->getAs<ExtIntType>())
+ if (EIT->getNumBits() < 64)
+ return true;
+
return false;
}
}
}
+ if (const auto *EIT = Ty->getAs<ExtIntType>())
+ if (EIT->getNumBits() > 128)
+ return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
+
if (isAggregateTypeForABI(Ty)) {
if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
}
}
+ if (const auto *EIT = RetTy->getAs<ExtIntType>())
+ if (EIT->getNumBits() > 128)
+ return getNaturalAlignIndirect(RetTy, /*ByVal=*/false);
+
if (isAggregateTypeForABI(RetTy)) {
// ELFv2 homogeneous aggregates are returned as array types.
const Type *Base = nullptr;
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
- return (Ty->isPromotableIntegerType() && isDarwinPCS()
+ if (const auto *EIT = Ty->getAs<ExtIntType>())
+ if (EIT->getNumBits() > 128)
+ return getNaturalAlignIndirect(Ty);
+
+ return (isPromotableIntegerTypeForABI(Ty) && isDarwinPCS()
? ABIArgInfo::getExtend(Ty)
: ABIArgInfo::getDirect());
}
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
RetTy = EnumTy->getDecl()->getIntegerType();
- return (RetTy->isPromotableIntegerType() && isDarwinPCS()
+ if (const auto *EIT = RetTy->getAs<ExtIntType>())
+ if (EIT->getNumBits() > 128)
+ return getNaturalAlignIndirect(RetTy);
+
+ return (isPromotableIntegerTypeForABI(RetTy) && isDarwinPCS()
? ABIArgInfo::getExtend(RetTy)
: ABIArgInfo::getDirect());
}
Ty = EnumTy->getDecl()->getIntegerType();
}
- return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
- : ABIArgInfo::getDirect());
+ if (const auto *EIT = Ty->getAs<ExtIntType>())
+ if (EIT->getNumBits() > 64)
+ return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
+
+ return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+ : ABIArgInfo::getDirect());
}
if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
RetTy = EnumTy->getDecl()->getIntegerType();
- return RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
- : ABIArgInfo::getDirect();
+ if (const auto *EIT = RetTy->getAs<ExtIntType>())
+ if (EIT->getNumBits() > 64)
+ return getNaturalAlignIndirect(RetTy, /*ByVal=*/false);
+
+ return isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+ : ABIArgInfo::getDirect();
}
// Are we following APCS?
void computeInfo(CGFunctionInfo &FI) const override;
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty) const override;
+ bool isUnsupportedType(QualType T) const;
+ ABIArgInfo coerceToIntArrayWithLimit(QualType Ty, unsigned MaxSize) const;
};
class NVPTXTargetCodeGenInfo : public TargetCodeGenInfo {
};
/// Checks if the type is unsupported directly by the current target.
-static bool isUnsupportedType(ASTContext &Context, QualType T) {
+bool NVPTXABIInfo::isUnsupportedType(QualType T) const {
+ ASTContext &Context = getContext();
if (!Context.getTargetInfo().hasFloat16Type() && T->isFloat16Type())
return true;
if (!Context.getTargetInfo().hasFloat128Type() &&
(T->isFloat128Type() ||
(T->isRealFloatingType() && Context.getTypeSize(T) == 128)))
return true;
+ if (const auto *EIT = T->getAs<ExtIntType>())
+ return EIT->getNumBits() >
+ (Context.getTargetInfo().hasInt128Type() ? 128 : 64);
if (!Context.getTargetInfo().hasInt128Type() && T->isIntegerType() &&
Context.getTypeSize(T) > 64)
return true;
if (const auto *AT = T->getAsArrayTypeUnsafe())
- return isUnsupportedType(Context, AT->getElementType());
+ return isUnsupportedType(AT->getElementType());
const auto *RT = T->getAs<RecordType>();
if (!RT)
return false;
// If this is a C++ record, check the bases first.
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
for (const CXXBaseSpecifier &I : CXXRD->bases())
- if (isUnsupportedType(Context, I.getType()))
+ if (isUnsupportedType(I.getType()))
return true;
for (const FieldDecl *I : RD->fields())
- if (isUnsupportedType(Context, I->getType()))
+ if (isUnsupportedType(I->getType()))
return true;
return false;
}
/// Coerce the given type into an array with maximum allowed size of elements.
-static ABIArgInfo coerceToIntArrayWithLimit(QualType Ty, ASTContext &Context,
- llvm::LLVMContext &LLVMContext,
- unsigned MaxSize) {
+ABIArgInfo NVPTXABIInfo::coerceToIntArrayWithLimit(QualType Ty,
+ unsigned MaxSize) const {
// Alignment and Size are measured in bits.
- const uint64_t Size = Context.getTypeSize(Ty);
- const uint64_t Alignment = Context.getTypeAlign(Ty);
+ const uint64_t Size = getContext().getTypeSize(Ty);
+ const uint64_t Alignment = getContext().getTypeAlign(Ty);
const unsigned Div = std::min<unsigned>(MaxSize, Alignment);
- llvm::Type *IntType = llvm::Type::getIntNTy(LLVMContext, Div);
+ llvm::Type *IntType = llvm::Type::getIntNTy(getVMContext(), Div);
const uint64_t NumElements = (Size + Div - 1) / Div;
return ABIArgInfo::getDirect(llvm::ArrayType::get(IntType, NumElements));
}
return ABIArgInfo::getIgnore();
if (getContext().getLangOpts().OpenMP &&
- getContext().getLangOpts().OpenMPIsDevice &&
- isUnsupportedType(getContext(), RetTy))
- return coerceToIntArrayWithLimit(RetTy, getContext(), getVMContext(), 64);
+ getContext().getLangOpts().OpenMPIsDevice && isUnsupportedType(RetTy))
+ return coerceToIntArrayWithLimit(RetTy, 64);
// note: this is different from default ABI
if (!RetTy->isScalarType())
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
RetTy = EnumTy->getDecl()->getIntegerType();
- return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
- : ABIArgInfo::getDirect());
+ return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+ : ABIArgInfo::getDirect());
}
ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const {
return getNaturalAlignIndirect(Ty, /* byval */ true);
}
- return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
- : ABIArgInfo::getDirect());
+ if (const auto *EIT = Ty->getAs<ExtIntType>()) {
+ if ((EIT->getNumBits() > 128) ||
+ (!getContext().getTargetInfo().hasInt128Type() &&
+ EIT->getNumBits() > 64))
+ return getNaturalAlignIndirect(Ty, /* byval */ true);
+ }
+
+ return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+ : ABIArgInfo::getDirect());
}
void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const {
SystemZABIInfo(CodeGenTypes &CGT, bool HV, bool SF)
: SwiftABIInfo(CGT), HasVector(HV), IsSoftFloatABI(SF) {}
- bool isPromotableIntegerType(QualType Ty) const;
+ bool isPromotableIntegerTypeForABI(QualType Ty) const;
bool isCompoundType(QualType Ty) const;
bool isVectorArgumentType(QualType Ty) const;
bool isFPArgumentType(QualType Ty) const;
}
-bool SystemZABIInfo::isPromotableIntegerType(QualType Ty) const {
+bool SystemZABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
// Promotable integer types are required to be promoted by the ABI.
- if (Ty->isPromotableIntegerType())
+ if (ABIInfo::isPromotableIntegerTypeForABI(Ty))
return true;
+ if (const auto *EIT = Ty->getAs<ExtIntType>())
+ if (EIT->getNumBits() < 64)
+ return true;
+
// 32-bit values must also be promoted.
if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
switch (BT->getKind()) {
return ABIArgInfo::getDirect();
if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64)
return getNaturalAlignIndirect(RetTy);
- return (isPromotableIntegerType(RetTy) ? ABIArgInfo::getExtend(RetTy)
- : ABIArgInfo::getDirect());
+ return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+ : ABIArgInfo::getDirect());
}
ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
// Integers and enums are extended to full register width.
- if (isPromotableIntegerType(Ty))
+ if (isPromotableIntegerTypeForABI(Ty))
return ABIArgInfo::getExtend(Ty);
// Handle vector types and vector-like structure types. Note that
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
+ // Make sure we pass indirectly things that are too large.
+ if (const auto *EIT = Ty->getAs<ExtIntType>())
+ if (EIT->getNumBits() > 128 ||
+ (EIT->getNumBits() > 64 &&
+ !getContext().getTargetInfo().hasInt128Type()))
+ return getNaturalAlignIndirect(Ty);
+
// All integral types are promoted to the GPR width.
if (Ty->isIntegralOrEnumerationType())
return extendType(Ty);
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
RetTy = EnumTy->getDecl()->getIntegerType();
- if (RetTy->isPromotableIntegerType())
+ // Make sure we pass indirectly things that are too large.
+ if (const auto *EIT = RetTy->getAs<ExtIntType>())
+ if (EIT->getNumBits() > 128 ||
+ (EIT->getNumBits() > 64 &&
+ !getContext().getTargetInfo().hasInt128Type()))
+ return getNaturalAlignIndirect(RetTy);
+
+ if (isPromotableIntegerTypeForABI(RetTy))
return ABIArgInfo::getExtend(RetTy);
if ((RetTy->isUnsignedIntegerOrEnumerationType() ||
if (Size <= 64)
HexagonAdjustRegsLeft(Size, RegsLeft);
- return Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
- : ABIArgInfo::getDirect();
+ if (Size > 64 && Ty->isExtIntType())
+ return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
+
+ return isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+ : ABIArgInfo::getDirect();
}
if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
RetTy = EnumTy->getDecl()->getIntegerType();
- return RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
- : ABIArgInfo::getDirect();
+ if (Size > 64 && RetTy->isExtIntType())
+ return getNaturalAlignIndirect(RetTy, /*ByVal=*/false);
+
+ return isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+ : ABIArgInfo::getDirect();
}
if (isEmptyRecord(getContext(), RetTy, true))
Ty = EnumTy->getDecl()->getIntegerType();
bool InReg = shouldUseInReg(Ty, State);
- if (Ty->isPromotableIntegerType()) {
+
+ // Don't pass >64 bit integers in registers.
+ if (const auto *EIT = Ty->getAs<ExtIntType>())
+ if (EIT->getNumBits() > 64)
+ return getIndirectResult(Ty, /*ByVal=*/true, State);
+
+ if (isPromotableIntegerTypeForABI(Ty)) {
if (InReg)
return ABIArgInfo::getDirectInReg();
return ABIArgInfo::getExtend(Ty);
if (Size < 64 && Ty->isIntegerType())
return ABIArgInfo::getExtend(Ty);
+ if (const auto *EIT = Ty->getAs<ExtIntType>())
+ if (EIT->getNumBits() < 64)
+ return ABIArgInfo::getExtend(Ty);
+
// Other non-aggregates go in registers.
if (!isAggregateTypeForABI(Ty))
return ABIArgInfo::getDirect();
ABIArgInfo::getDirect(Result, 0, nullptr, false);
}
- return Ty->isPromotableIntegerType() ?
- (FreeRegs >= SizeInRegs ? ABIArgInfo::getExtendInReg(Ty) :
- ABIArgInfo::getExtend(Ty)) :
- (FreeRegs >= SizeInRegs ? ABIArgInfo::getDirectInReg() :
- ABIArgInfo::getDirect());
+ if (const auto *EIT = Ty->getAs<ExtIntType>())
+ if (EIT->getNumBits() > 64)
+ return getIndirectByValue(Ty);
+
+ return isPromotableIntegerTypeForABI(Ty)
+ ? (FreeRegs >= SizeInRegs ? ABIArgInfo::getExtendInReg(Ty)
+ : ABIArgInfo::getExtend(Ty))
+ : (FreeRegs >= SizeInRegs ? ABIArgInfo::getDirectInReg()
+ : ABIArgInfo::getDirect());
}
ABIArgInfo ARCABIInfo::classifyReturnType(QualType RetTy) const {
return extendType(Ty);
}
+ if (const auto *EIT = Ty->getAs<ExtIntType>()) {
+ if (EIT->getNumBits() < XLen && !MustUseStack)
+ return extendType(Ty);
+ if (EIT->getNumBits() > 128 ||
+ (!getContext().getTargetInfo().hasInt128Type() &&
+ EIT->getNumBits() > 64))
+ return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
+ }
+
return ABIArgInfo::getDirect();
}
// RUN: %clang_cc1 -triple x86_64-windows-pc -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=WIN64
// RUN: %clang_cc1 -triple i386-gnu-linux -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=LIN32
// RUN: %clang_cc1 -triple i386-windows-pc -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=WIN32
+// RUN: %clang_cc1 -triple le32-nacl -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=NACL
+// RUN: %clang_cc1 -triple nvptx64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=NVPTX64
+// RUN: %clang_cc1 -triple nvptx -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=NVPTX
+// RUN: %clang_cc1 -triple sparcv9 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=SPARCV9
+// RUN: %clang_cc1 -triple sparc -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=SPARC
+// RUN: %clang_cc1 -triple mips64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=MIPS64
+// RUN: %clang_cc1 -triple mips -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=MIPS
+// RUN: %clang_cc1 -triple spir64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=SPIR64
+// RUN: %clang_cc1 -triple spir -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=SPIR
+// RUN: %clang_cc1 -triple hexagon -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=HEX
+// RUN: %clang_cc1 -triple lanai -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=LANAI
+// RUN: %clang_cc1 -triple r600 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=R600
+// RUN: %clang_cc1 -triple arc -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=ARC
+// RUN: %clang_cc1 -triple xcore -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=XCORE
+// RUN: %clang_cc1 -triple riscv64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=RISCV64
+// RUN: %clang_cc1 -triple riscv32 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=RISCV32
+// RUN: %clang_cc1 -triple wasm64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=WASM
+// RUN: %clang_cc1 -triple wasm32 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=WASM
+// RUN: %clang_cc1 -triple systemz -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=SYSTEMZ
+// RUN: %clang_cc1 -triple ppc64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=PPC64
+// RUN: %clang_cc1 -triple ppc -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=PPC32
+// RUN: %clang_cc1 -triple aarch64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=AARCH64
+// RUN: %clang_cc1 -triple aarch64 -target-abi darwinpcs -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=AARCH64DARWIN
+// RUN: %clang_cc1 -triple arm64_32-apple-ios -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=AARCH64
+// RUN: %clang_cc1 -triple arm64_32-apple-ios -target-abi darwinpcs -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=AARCH64DARWIN
+// RUN: %clang_cc1 -triple arm -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=ARM
// Make sure 128 and 64 bit versions are passed like integers, and that >128
// is passed indirectly.
// WIN64: define dso_local void @ParamPassing(i129* %{{.+}}, i128* %{{.+}}, i64 %{{.+}})
// LIN32: define void @ParamPassing(i129* %{{.+}}, i128* %{{.+}}, i64 %{{.+}})
// WIN32: define dso_local void @ParamPassing(i129* %{{.+}}, i128* %{{.+}}, i64 %{{.+}})
+// NACL: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// NVPTX64: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// NVPTX: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// SPARCV9: define void @ParamPassing(i129* %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// SPARC: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// MIPS64: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 signext %{{.+}}, i64 signext %{{.+}})
+// MIPS: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 signext %{{.+}})
+// SPIR64: define spir_func void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// SPIR: define spir_func void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// HEX: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// LANAI: define void @ParamPassing(i129* byval(i129) align 4 %{{.+}}, i128* byval(i128) align 4 %{{.+}}, i64 %{{.+}})
+// R600: define void @ParamPassing(i129 addrspace(5)* byval(i129) align 8 %{{.+}}, i128 addrspace(5)* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// ARC: define void @ParamPassing(i129* byval(i129) align 4 %{{.+}}, i128* byval(i128) align 4 %{{.+}}, i64 inreg %{{.+}})
+// XCORE: define void @ParamPassing(i129* byval(i129) align 4 %{{.+}}, i128* byval(i128) align 4 %{{.+}}, i64 %{{.+}})
+// RISCV64: define void @ParamPassing(i129* %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// RISCV32: define void @ParamPassing(i129* %{{.+}}, i128* %{{.+}}, i64 %{{.+}})
+// WASM: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// SYSTEMZ: define void @ParamPassing(i129* %{{.+}}, i128* %{{.+}}, i64 %{{.+}})
+// PPC64: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// PPC32: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// AARCH64: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// AARCH64DARWIN: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// ARM: define arm_aapcscc void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+
void ParamPassing2(_ExtInt(129) a, _ExtInt(127) b, _ExtInt(63) c) {}
// LIN64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i64 %{{.+}})
// WIN64: define dso_local void @ParamPassing2(i129* %{{.+}}, i127* %{{.+}}, i63 %{{.+}})
// LIN32: define void @ParamPassing2(i129* %{{.+}}, i127* %{{.+}}, i63 %{{.+}})
// WIN32: define dso_local void @ParamPassing2(i129* %{{.+}}, i127* %{{.+}}, i63 %{{.+}})
+// NACL: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// NVPTX64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
+// NVPTX: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// SPARCV9: define void @ParamPassing2(i129* %{{.+}}, i127 %{{.+}}, i63 signext %{{.+}})
+// SPARC: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// MIPS64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 signext %{{.+}}, i63 signext %{{.+}})
+// MIPS: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 signext %{{.+}})
+// SPIR64: define spir_func void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
+// SPIR: define spir_func void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// HEX: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// LANAI: define void @ParamPassing2(i129* byval(i129) align 4 %{{.+}}, i127* byval(i127) align 4 %{{.+}}, i63 %{{.+}})
+// R600: define void @ParamPassing2(i129 addrspace(5)* byval(i129) align 8 %{{.+}}, i127 addrspace(5)* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// ARC: define void @ParamPassing2(i129* byval(i129) align 4 %{{.+}}, i127* byval(i127) align 4 %{{.+}}, i63 inreg %{{.+}})
+// XCORE: define void @ParamPassing2(i129* byval(i129) align 4 %{{.+}}, i127* byval(i127) align 4 %{{.+}}, i63 %{{.+}})
+// RISCV64: define void @ParamPassing2(i129* %{{.+}}, i127 %{{.+}}, i63 signext %{{.+}})
+// RISCV32: define void @ParamPassing2(i129* %{{.+}}, i127* %{{.+}}, i63 %{{.+}})
+// WASM: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
+// SYSTEMZ: define void @ParamPassing2(i129* %{{.+}}, i127* %{{.+}}, i63 signext %{{.+}})
+// PPC64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 signext %{{.+}})
+// PPC32: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// AARCH64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
+// AARCH64DARWIN: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
+// ARM: define arm_aapcscc void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+
+// Make sure we follow the signext rules for promotable integer types.
+void ParamPassing3(_ExtInt(15) a, _ExtInt(31) b) {}
+// LIN64: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// WIN64: define dso_local void @ParamPassing3(i15 %{{.+}}, i31 %{{.+}})
+// LIN32: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// WIN32: define dso_local void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// NACL: define void @ParamPassing3(i15 %{{.+}}, i31 %{{.+}})
+// NVPTX64: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// NVPTX: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// SPARCV9: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// SPARC: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// MIPS64: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// MIPS: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// SPIR64: define spir_func void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// SPIR: define spir_func void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// HEX: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// LANAI: define void @ParamPassing3(i15 inreg %{{.+}}, i31 inreg %{{.+}})
+// R600: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// ARC: define void @ParamPassing3(i15 inreg signext %{{.+}}, i31 inreg signext %{{.+}})
+// XCORE: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// RISCV64: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// RISCV32: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// WASM: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// SYSTEMZ: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// PPC64: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// PPC32: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// AARCH64: define void @ParamPassing3(i15 %{{.+}}, i31 %{{.+}})
+// AARCH64DARWIN: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// ARM: define arm_aapcscc void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+
_ExtInt(63) ReturnPassing(){}
// LIN64: define i64 @ReturnPassing(
// WIN64: define dso_local i63 @ReturnPassing(
// LIN32: define i63 @ReturnPassing(
// WIN32: define dso_local i63 @ReturnPassing(
+// NACL: define i63 @ReturnPassing(
+// NVPTX64: define i63 @ReturnPassing(
+// NVPTX: define i63 @ReturnPassing(
+// SPARCV9: define signext i63 @ReturnPassing(
+// SPARC: define i63 @ReturnPassing(
+// MIPS64: define i63 @ReturnPassing(
+// MIPS: define i63 @ReturnPassing(
+// SPIR64: define spir_func i63 @ReturnPassing(
+// SPIR: define spir_func i63 @ReturnPassing(
+// HEX: define i63 @ReturnPassing(
+// LANAI: define i63 @ReturnPassing(
+// R600: define i63 @ReturnPassing(
+// ARC: define i63 @ReturnPassing(
+// XCORE: define i63 @ReturnPassing(
+// RISCV64: define signext i63 @ReturnPassing(
+// RISCV32: define i63 @ReturnPassing(
+// WASM: define i63 @ReturnPassing(
+// SYSTEMZ: define signext i63 @ReturnPassing(
+// PPC64: define signext i63 @ReturnPassing(
+// PPC32: define i63 @ReturnPassing(
+// AARCH64: define i63 @ReturnPassing(
+// AARCH64DARWIN: define i63 @ReturnPassing(
+// ARM: define arm_aapcscc i63 @ReturnPassing(
+
_ExtInt(64) ReturnPassing2(){}
// LIN64: define i64 @ReturnPassing2(
// WIN64: define dso_local i64 @ReturnPassing2(
// LIN32: define i64 @ReturnPassing2(
// WIN32: define dso_local i64 @ReturnPassing2(
+// NACL: define i64 @ReturnPassing2(
+// NVPTX64: define i64 @ReturnPassing2(
+// NVPTX: define i64 @ReturnPassing2(
+// SPARCV9: define i64 @ReturnPassing2(
+// SPARC: define i64 @ReturnPassing2(
+// MIPS64: define i64 @ReturnPassing2(
+// MIPS: define i64 @ReturnPassing2(
+// SPIR64: define spir_func i64 @ReturnPassing2(
+// SPIR: define spir_func i64 @ReturnPassing2(
+// HEX: define i64 @ReturnPassing2(
+// LANAI: define i64 @ReturnPassing2(
+// R600: define i64 @ReturnPassing2(
+// ARC: define i64 @ReturnPassing2(
+// XCORE: define i64 @ReturnPassing2(
+// RISCV64: define i64 @ReturnPassing2(
+// RISCV32: define i64 @ReturnPassing2(
+// WASM: define i64 @ReturnPassing2(
+// SYSTEMZ: define i64 @ReturnPassing2(
+// PPC64: define i64 @ReturnPassing2(
+// PPC32: define i64 @ReturnPassing2(
+// AARCH64: define i64 @ReturnPassing2(
+// AARCH64DARWIN: define i64 @ReturnPassing2(
+// ARM: define arm_aapcscc i64 @ReturnPassing2(
+
_ExtInt(127) ReturnPassing3(){}
// LIN64: define { i64, i64 } @ReturnPassing3(
// WIN64: define dso_local void @ReturnPassing3(i127* noalias sret
-// LIN32: define i127 @ReturnPassing3(
-// WIN32: define dso_local i127 @ReturnPassing3(
+// LIN32: define void @ReturnPassing3(i127* noalias sret
+// WIN32: define dso_local void @ReturnPassing3(i127* noalias sret
+// NACL: define void @ReturnPassing3(i127* noalias sret
+// NVPTX/64 makes the intentional choice to put all return values direct, even
+// large structures, so we do the same here.
+// NVPTX64: define i127 @ReturnPassing3(
+// NVPTX: define i127 @ReturnPassing3(
+// SPARCV9: define i127 @ReturnPassing3(
+// SPARC: define void @ReturnPassing3(i127* noalias sret
+// MIPS64: define i127 @ReturnPassing3(
+// MIPS: define void @ReturnPassing3(i127* noalias sret
+// SPIR64: define spir_func i127 @ReturnPassing3(
+// SPIR: define spir_func void @ReturnPassing3(i127* noalias sret
+// HEX: define void @ReturnPassing3(i127* noalias sret
+// LANAI: define void @ReturnPassing3(i127* noalias sret
+// R600: define void @ReturnPassing3(i127 addrspace(5)* noalias sret
+// ARC: define void @ReturnPassing3(i127* noalias sret
+// XCORE: define void @ReturnPassing3(i127* noalias sret
+// RISCV64: define i127 @ReturnPassing3(
+// RISCV32: define void @ReturnPassing3(i127* noalias sret
+// WASM: define i127 @ReturnPassing3(
+// SYSTEMZ: define void @ReturnPassing3(i127* noalias sret
+// PPC64: define i127 @ReturnPassing3(
+// PPC32: define void @ReturnPassing3(i127* noalias sret
+// AARCH64: define i127 @ReturnPassing3(
+// AARCH64DARWIN: define i127 @ReturnPassing3(
+// ARM: define arm_aapcscc void @ReturnPassing3(i127* noalias sret
+
_ExtInt(128) ReturnPassing4(){}
// LIN64: define { i64, i64 } @ReturnPassing4(
// WIN64: define dso_local void @ReturnPassing4(i128* noalias sret
-// LIN32: define i128 @ReturnPassing4(
-// WIN32: define dso_local i128 @ReturnPassing4(
+// LIN32: define void @ReturnPassing4(i128* noalias sret
+// WIN32: define dso_local void @ReturnPassing4(i128* noalias sret
+// NACL: define void @ReturnPassing4(i128* noalias sret
+// NVPTX64: define i128 @ReturnPassing4(
+// NVPTX: define i128 @ReturnPassing4(
+// SPARCV9: define i128 @ReturnPassing4(
+// SPARC: define void @ReturnPassing4(i128* noalias sret
+// MIPS64: define i128 @ReturnPassing4(
+// MIPS: define void @ReturnPassing4(i128* noalias sret
+// SPIR64: define spir_func i128 @ReturnPassing4(
+// SPIR: define spir_func void @ReturnPassing4(i128* noalias sret
+// HEX: define void @ReturnPassing4(i128* noalias sret
+// LANAI: define void @ReturnPassing4(i128* noalias sret
+// R600: define void @ReturnPassing4(i128 addrspace(5)* noalias sret
+// ARC: define void @ReturnPassing4(i128* noalias sret
+// XCORE: define void @ReturnPassing4(i128* noalias sret
+// RISCV64: define i128 @ReturnPassing4(
+// RISCV32: define void @ReturnPassing4(i128* noalias sret
+// WASM: define i128 @ReturnPassing4(
+// SYSTEMZ: define void @ReturnPassing4(i128* noalias sret
+// PPC64: define i128 @ReturnPassing4(
+// PPC32: define void @ReturnPassing4(i128* noalias sret
+// AARCH64: define i128 @ReturnPassing4(
+// AARCH64DARWIN: define i128 @ReturnPassing4(
+// ARM: define arm_aapcscc void @ReturnPassing4(i128* noalias sret
+
_ExtInt(129) ReturnPassing5(){}
// LIN64: define void @ReturnPassing5(i129* noalias sret
// WIN64: define dso_local void @ReturnPassing5(i129* noalias sret
-// LIN32: define i129 @ReturnPassing5(
-// WIN32: define dso_local i129 @ReturnPassing5(
+// LIN32: define void @ReturnPassing5(i129* noalias sret
+// WIN32: define dso_local void @ReturnPassing5(i129* noalias sret
+// NACL: define void @ReturnPassing5(i129* noalias sret
+// NVPTX64: define i129 @ReturnPassing5(
+// NVPTX: define i129 @ReturnPassing5(
+// SPARCV9: define i129 @ReturnPassing5(
+// SPARC: define void @ReturnPassing5(i129* noalias sret
+// MIPS64: define void @ReturnPassing5(i129* noalias sret
+// MIPS: define void @ReturnPassing5(i129* noalias sret
+// SPIR64: define spir_func void @ReturnPassing5(i129* noalias sret
+// SPIR: define spir_func void @ReturnPassing5(i129* noalias sret
+// HEX: define void @ReturnPassing5(i129* noalias sret
+// LANAI: define void @ReturnPassing5(i129* noalias sret
+// R600: define void @ReturnPassing5(i129 addrspace(5)* noalias sret
+// ARC: define void @ReturnPassing5(i129* inreg noalias sret
+// XCORE: define void @ReturnPassing5(i129* noalias sret
+// RISCV64: define void @ReturnPassing5(i129* noalias sret
+// RISCV32: define void @ReturnPassing5(i129* noalias sret
+// WASM: define void @ReturnPassing5(i129* noalias sret
+// SYSTEMZ: define void @ReturnPassing5(i129* noalias sret
+// PPC64: define void @ReturnPassing5(i129* noalias sret
+// PPC32: define void @ReturnPassing5(i129* noalias sret
+// AARCH64: define void @ReturnPassing5(i129* noalias sret
+// AARCH64DARWIN: define void @ReturnPassing5(i129* noalias sret
+// ARM: define arm_aapcscc void @ReturnPassing5(i129* noalias sret
+
+// SparcV9 is odd in that it has a return-size limit of 256, not 128 or 64
+// like other platforms, so test to make sure this behavior will still work.
+_ExtInt(256) ReturnPassing6() {}
+// SPARCV9: define i256 @ReturnPassing6(
+_ExtInt(257) ReturnPassing7() {}
+// SPARCV9: define void @ReturnPassing7(i257* noalias sret
// Also triggers signed integer overflow.
E / E;
- // CHECK: %[[E1LOAD:.+]] = load i11
- // CHECK: store i11 %[[E1LOAD]], i11* %[[EADDR:.+]]
+ // CHECK: %[[EADDR:.+]] = alloca i11
// CHECK: %[[E:.+]] = load i11, i11* %[[EADDR]]
// CHECK: %[[E2:.+]] = load i11, i11* %[[EADDR]]
// CHECK: %[[NEZERO:.+]] = icmp ne i11 %[[E2]], 0
// CHECK: define void @_Z6ShiftsU7_ExtIntILi9EEi
void Shifts(_ExtInt(9) E) {
E >> E;
- // CHECK: %[[E1LOAD:.+]] = load i9, i9*
- // CHECK: store i9 %[[E1LOAD]], i9* %[[EADDR:.+]]
+ // CHECK: %[[EADDR:.+]] = alloca i9
// CHECK: %[[LHSE:.+]] = load i9, i9* %[[EADDR]]
// CHECK: %[[RHSE:.+]] = load i9, i9* %[[EADDR]]
// CHECK: %[[CMP:.+]] = icmp ule i9 %[[RHSE]], 8
unsigned _ExtInt(23) SmallE,
unsigned _ExtInt(35) BigE) {
u = SmallE + SmallE;
- // CHECK: %[[LOADBIGGESTE2:.+]] = load i23
- // CHECK: store i23 %[[LOADBIGGESTE2]], i23* %[[BIGGESTEADDR:.+]]
+ // CHECK: %[[BIGGESTEADDR:.+]] = alloca i23
// CHECK: %[[LOADE1:.+]] = load i23, i23* %[[BIGGESTEADDR]]
// CHECK: %[[LOADE2:.+]] = load i23, i23* %[[BIGGESTEADDR]]
// CHECK: %[[OFCALL:.+]] = call { i23, i1 } @llvm.uadd.with.overflow.i23(i23 %[[LOADE1]], i23 %[[LOADE2]])
};
void UnderlyingTypeUsage(AsEnumUnderlyingType Param) {
- // LIN: define void @_Z19UnderlyingTypeUsage20AsEnumUnderlyingType(i16 %
+ // LIN: define void @_Z19UnderlyingTypeUsage20AsEnumUnderlyingType(i9 signext %
// WIN: define dso_local void @"?UnderlyingTypeUsage@@YAXW4AsEnumUnderlyingType@@@Z"(i9 %
AsEnumUnderlyingType Var;
// CHECK: alloca i9, align 2
+++ /dev/null
-// RUN: %clang_cc1 -triple armv7 -fsyntax-only -verify %s
-
-void foo() {
- _ExtInt(33) a; // expected-error{{_ExtInt is not supported on this target}}
-}