Date: Tue, 20 Aug 2019 21:35:29 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r351305 - in vendor/clang/dist-release_90: include/clang/AST include/clang/Basic include/clang/Driver include/clang/Frontend include/clang/Sema lib/AST lib/Basic lib/Basic/Targets lib/C... Message-ID: <201908202135.x7KLZTRK005751@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Tue Aug 20 21:35:28 2019 New Revision: 351305 URL: https://svnweb.freebsd.org/changeset/base/351305 Log: Vendor import of clang release_90 branch r369369: https://llvm.org/svn/llvm-project/cfe/branches/release_90@369369 Modified: vendor/clang/dist-release_90/include/clang/AST/ExprCXX.h vendor/clang/dist-release_90/include/clang/Basic/DiagnosticSemaKinds.td vendor/clang/dist-release_90/include/clang/Basic/TargetInfo.h vendor/clang/dist-release_90/include/clang/Driver/Options.td vendor/clang/dist-release_90/include/clang/Frontend/LangStandards.def vendor/clang/dist-release_90/include/clang/Sema/Sema.h vendor/clang/dist-release_90/lib/AST/ASTContext.cpp vendor/clang/dist-release_90/lib/AST/ExprCXX.cpp vendor/clang/dist-release_90/lib/AST/ItaniumCXXABI.cpp vendor/clang/dist-release_90/lib/AST/MicrosoftCXXABI.cpp vendor/clang/dist-release_90/lib/Basic/Targets/AArch64.cpp vendor/clang/dist-release_90/lib/Basic/Targets/OSTargets.h vendor/clang/dist-release_90/lib/Basic/Targets/RISCV.cpp vendor/clang/dist-release_90/lib/Basic/Targets/RISCV.h vendor/clang/dist-release_90/lib/Basic/Targets/SPIR.h vendor/clang/dist-release_90/lib/Basic/Targets/X86.h vendor/clang/dist-release_90/lib/Basic/Version.cpp vendor/clang/dist-release_90/lib/CodeGen/CGBuiltin.cpp vendor/clang/dist-release_90/lib/CodeGen/CGExprAgg.cpp vendor/clang/dist-release_90/lib/CodeGen/CGStmt.cpp vendor/clang/dist-release_90/lib/CodeGen/ItaniumCXXABI.cpp vendor/clang/dist-release_90/lib/CodeGen/MicrosoftCXXABI.cpp vendor/clang/dist-release_90/lib/CodeGen/TargetInfo.cpp vendor/clang/dist-release_90/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp vendor/clang/dist-release_90/lib/Driver/ToolChains/Clang.cpp vendor/clang/dist-release_90/lib/Frontend/ASTUnit.cpp vendor/clang/dist-release_90/lib/Frontend/CompilerInvocation.cpp vendor/clang/dist-release_90/lib/Frontend/InitPreprocessor.cpp vendor/clang/dist-release_90/lib/Headers/emmintrin.h vendor/clang/dist-release_90/lib/Headers/opencl-c-base.h vendor/clang/dist-release_90/lib/Headers/opencl-c.h vendor/clang/dist-release_90/lib/Lex/PPDirectives.cpp vendor/clang/dist-release_90/lib/Sema/Sema.cpp vendor/clang/dist-release_90/lib/Sema/SemaDecl.cpp vendor/clang/dist-release_90/lib/Sema/SemaDeclCXX.cpp vendor/clang/dist-release_90/lib/Sema/SemaExprCXX.cpp vendor/clang/dist-release_90/lib/Sema/SemaInit.cpp vendor/clang/dist-release_90/lib/Sema/SemaOpenMP.cpp vendor/clang/dist-release_90/lib/Sema/SemaStmtAsm.cpp vendor/clang/dist-release_90/lib/Sema/SemaTemplate.cpp vendor/clang/dist-release_90/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp Modified: vendor/clang/dist-release_90/include/clang/AST/ExprCXX.h ============================================================================== --- vendor/clang/dist-release_90/include/clang/AST/ExprCXX.h Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/include/clang/AST/ExprCXX.h Tue Aug 20 21:35:28 2019 (r351305) @@ -185,15 +185,20 @@ class CXXMemberCallExpr final : public CallExpr { (pub static CXXMemberCallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs, EmptyShell Empty); - /// Retrieves the implicit object argument for the member call. + /// Retrieve the implicit object argument for the member call. /// /// For example, in "x.f(5)", this returns the sub-expression "x". Expr *getImplicitObjectArgument() const; - /// Retrieves the declaration of the called method. + /// Retrieve the type of the object argument. + /// + /// Note that this always returns a non-pointer type. + QualType getObjectType() const; + + /// Retrieve the declaration of the called method. CXXMethodDecl *getMethodDecl() const; - /// Retrieves the CXXRecordDecl for the underlying type of + /// Retrieve the CXXRecordDecl for the underlying type of /// the implicit object argument. /// /// Note that this is may not be the same declaration as that of the class Modified: vendor/clang/dist-release_90/include/clang/Basic/DiagnosticSemaKinds.td ============================================================================== --- vendor/clang/dist-release_90/include/clang/Basic/DiagnosticSemaKinds.td Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/include/clang/Basic/DiagnosticSemaKinds.td Tue Aug 20 21:35:28 2019 (r351305) @@ -598,6 +598,10 @@ def ext_implicit_lib_function_decl : ExtWarn< def note_include_header_or_declare : Note< "include the header <%0> or explicitly provide a declaration for '%1'">; def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">; +def warn_implicit_decl_no_jmp_buf + : Warning<"declaration of built-in function '%0' requires the declaration" + " of the 'jmp_buf' type, commonly provided in the header <setjmp.h>.">, + InGroup<DiagGroup<"incomplete-setjmp-declaration">>; def warn_implicit_decl_requires_sysheader : Warning< "declaration of built-in function '%1' requires inclusion of the header <%0>">, InGroup<BuiltinRequiresHeader>; Modified: vendor/clang/dist-release_90/include/clang/Basic/TargetInfo.h ============================================================================== --- vendor/clang/dist-release_90/include/clang/Basic/TargetInfo.h Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/include/clang/Basic/TargetInfo.h Tue Aug 20 21:35:28 2019 (r351305) @@ -1249,15 +1249,9 @@ class TargetInfo : public virtual TransferrableTargetI bool isBigEndian() const { return BigEndian; } bool isLittleEndian() const { return !BigEndian; } - enum CallingConvMethodType { - CCMT_Unknown, - CCMT_Member, - CCMT_NonMember - }; - /// Gets the default calling convention for the given target and /// declaration context. - virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const { + virtual CallingConv getDefaultCallingConv() const { // Not all targets will specify an explicit calling convention that we can // express. This will always do the right thing, even though it's not // an explicit calling convention. Modified: vendor/clang/dist-release_90/include/clang/Driver/Options.td ============================================================================== --- vendor/clang/dist-release_90/include/clang/Driver/Options.td Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/include/clang/Driver/Options.td Tue Aug 20 21:35:28 2019 (r351305) @@ -518,7 +518,7 @@ def cl_mad_enable : Flag<["-"], "cl-mad-enable">, Grou def cl_no_signed_zeros : Flag<["-"], "cl-no-signed-zeros">, Group<opencl_Group>, Flags<[CC1Option]>, HelpText<"OpenCL only. Allow use of less precise no signed zeros computations in the generated binary.">; def cl_std_EQ : Joined<["-"], "cl-std=">, Group<opencl_Group>, Flags<[CC1Option]>, - HelpText<"OpenCL language standard to compile for.">, Values<"cl,CL,cl1.1,CL1.1,cl1.2,CL1.2,cl2.0,CL2.0,c++">; + HelpText<"OpenCL language standard to compile for.">, Values<"cl,CL,cl1.1,CL1.1,cl1.2,CL1.2,cl2.0,CL2.0,clc++,CLC++">; def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">, Group<opencl_Group>, Flags<[CC1Option]>, HelpText<"OpenCL only. Allow denormals to be flushed to zero.">; def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-rounded-divide-sqrt">, Group<opencl_Group>, Flags<[CC1Option]>, Modified: vendor/clang/dist-release_90/include/clang/Frontend/LangStandards.def ============================================================================== --- vendor/clang/dist-release_90/include/clang/Frontend/LangStandards.def Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/include/clang/Frontend/LangStandards.def Tue Aug 20 21:35:28 2019 (r351305) @@ -174,6 +174,7 @@ LANGSTANDARD_ALIAS_DEPR(opencl10, "CL") LANGSTANDARD_ALIAS_DEPR(opencl11, "CL1.1") LANGSTANDARD_ALIAS_DEPR(opencl12, "CL1.2") LANGSTANDARD_ALIAS_DEPR(opencl20, "CL2.0") +LANGSTANDARD_ALIAS_DEPR(openclcpp, "CLC++") // CUDA LANGSTANDARD(cuda, "cuda", CUDA, "NVIDIA CUDA(tm)", Modified: vendor/clang/dist-release_90/include/clang/Sema/Sema.h ============================================================================== --- vendor/clang/dist-release_90/include/clang/Sema/Sema.h Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/include/clang/Sema/Sema.h Tue Aug 20 21:35:28 2019 (r351305) @@ -11165,6 +11165,7 @@ class Sema { (public) // Emitting members of dllexported classes is delayed until the class // (including field initializers) is fully parsed. SmallVector<CXXRecordDecl*, 4> DelayedDllExportClasses; + SmallVector<CXXMethodDecl*, 4> DelayedDllExportMemberFunctions; private: class SavePendingParsedClassStateRAII { Modified: vendor/clang/dist-release_90/lib/AST/ASTContext.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/AST/ASTContext.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/AST/ASTContext.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -10035,7 +10035,7 @@ CallingConv ASTContext::getDefaultCallingConvention(bo break; } } - return Target->getDefaultCallingConv(TargetInfo::CCMT_Unknown); + return Target->getDefaultCallingConv(); } bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const { Modified: vendor/clang/dist-release_90/lib/AST/ExprCXX.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/AST/ExprCXX.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/AST/ExprCXX.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -651,6 +651,13 @@ Expr *CXXMemberCallExpr::getImplicitObjectArgument() c return nullptr; } +QualType CXXMemberCallExpr::getObjectType() const { + QualType Ty = getImplicitObjectArgument()->getType(); + if (Ty->isPointerType()) + Ty = Ty->getPointeeType(); + return Ty; +} + CXXMethodDecl *CXXMemberCallExpr::getMethodDecl() const { if (const auto *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens())) return cast<CXXMethodDecl>(MemExpr->getMemberDecl()); Modified: vendor/clang/dist-release_90/lib/AST/ItaniumCXXABI.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/AST/ItaniumCXXABI.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/AST/ItaniumCXXABI.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -177,7 +177,7 @@ class ItaniumCXXABI : public CXXABI { (public) if (!isVariadic && T.isWindowsGNUEnvironment() && T.getArch() == llvm::Triple::x86) return CC_X86ThisCall; - return CC_C; + return Context.getTargetInfo().getDefaultCallingConv(); } // We cheat and just check that the class has a vtable pointer, and that it's Modified: vendor/clang/dist-release_90/lib/AST/MicrosoftCXXABI.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/AST/MicrosoftCXXABI.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/AST/MicrosoftCXXABI.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -82,7 +82,7 @@ class MicrosoftCXXABI : public CXXABI { (public) if (!isVariadic && Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86) return CC_X86ThisCall; - return CC_C; + return Context.getTargetInfo().getDefaultCallingConv(); } bool isNearlyEmpty(const CXXRecordDecl *RD) const override { Modified: vendor/clang/dist-release_90/lib/Basic/Targets/AArch64.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/Basic/Targets/AArch64.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/Basic/Targets/AArch64.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -196,9 +196,6 @@ void AArch64TargetInfo::getTargetDefines(const LangOpt Builder.defineMacro("__ARM_NEON_FP", "0xE"); } - if (FPU & SveMode) - Builder.defineMacro("__ARM_FEATURE_SVE", "1"); - if (HasCRC) Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); @@ -351,10 +348,19 @@ const char *const AArch64TargetInfo::GCCRegNames[] = { "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", - // Vector registers + // Neon vector registers "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", - "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" + "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", + + // SVE vector registers + "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10", + "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21", + "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31", + + // SVE predicate registers + "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10", + "p11", "p12", "p13", "p14", "p15" }; ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const { Modified: vendor/clang/dist-release_90/lib/Basic/Targets/OSTargets.h ============================================================================== --- vendor/clang/dist-release_90/lib/Basic/Targets/OSTargets.h Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/Basic/Targets/OSTargets.h Tue Aug 20 21:35:28 2019 (r351305) @@ -618,8 +618,11 @@ class LLVM_LIBRARY_VISIBILITY SolarisTargetInfo : publ Builder.defineMacro("_XOPEN_SOURCE", "600"); else Builder.defineMacro("_XOPEN_SOURCE", "500"); - if (Opts.CPlusPlus) + if (Opts.CPlusPlus) { Builder.defineMacro("__C99FEATURES__"); + Builder.defineMacro("_FILE_OFFSET_BITS", "64"); + } + // GCC restricts the next two to C++. Builder.defineMacro("_LARGEFILE_SOURCE"); Builder.defineMacro("_LARGEFILE64_SOURCE"); Builder.defineMacro("__EXTENSIONS__"); Modified: vendor/clang/dist-release_90/lib/Basic/Targets/RISCV.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/Basic/Targets/RISCV.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/Basic/Targets/RISCV.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -56,6 +56,10 @@ bool RISCVTargetInfo::validateAsmConstraint( // A 5-bit unsigned immediate for CSR access instructions. Info.setRequiresImmediate(0, 31); return true; + case 'f': + // A floating-point register. + Info.setAllowsRegister(); + return true; } } @@ -65,9 +69,18 @@ void RISCVTargetInfo::getTargetDefines(const LangOptio Builder.defineMacro("__riscv"); bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64; Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32"); - // TODO: modify when more code models and ABIs are supported. + // TODO: modify when more code models are supported. Builder.defineMacro("__riscv_cmodel_medlow"); - Builder.defineMacro("__riscv_float_abi_soft"); + + StringRef ABIName = getABI(); + if (ABIName == "ilp32f" || ABIName == "lp64f") + Builder.defineMacro("__riscv_float_abi_single"); + else if (ABIName == "ilp32d" || ABIName == "lp64d") + Builder.defineMacro("__riscv_float_abi_double"); + else if (ABIName == "ilp32e") + Builder.defineMacro("__riscv_abi_rve"); + else + Builder.defineMacro("__riscv_float_abi_soft"); if (HasM) { Builder.defineMacro("__riscv_mul"); Modified: vendor/clang/dist-release_90/lib/Basic/Targets/RISCV.h ============================================================================== --- vendor/clang/dist-release_90/lib/Basic/Targets/RISCV.h Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/Basic/Targets/RISCV.h Tue Aug 20 21:35:28 2019 (r351305) @@ -87,8 +87,7 @@ class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : publ } bool setABI(const std::string &Name) override { - // TODO: support ilp32f and ilp32d ABIs. - if (Name == "ilp32") { + if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") { ABI = Name; return true; } @@ -105,8 +104,7 @@ class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : publ } bool setABI(const std::string &Name) override { - // TODO: support lp64f and lp64d ABIs. - if (Name == "lp64") { + if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") { ABI = Name; return true; } Modified: vendor/clang/dist-release_90/lib/Basic/Targets/SPIR.h ============================================================================== --- vendor/clang/dist-release_90/lib/Basic/Targets/SPIR.h Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/Basic/Targets/SPIR.h Tue Aug 20 21:35:28 2019 (r351305) @@ -88,7 +88,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public : CCCR_Warning; } - CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override { + CallingConv getDefaultCallingConv() const override { return CC_SpirFunction; } Modified: vendor/clang/dist-release_90/lib/Basic/Targets/X86.h ============================================================================== --- vendor/clang/dist-release_90/lib/Basic/Targets/X86.h Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/Basic/Targets/X86.h Tue Aug 20 21:35:28 2019 (r351305) @@ -320,8 +320,8 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public T } } - CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override { - return MT == CCMT_Member ? CC_X86ThisCall : CC_C; + CallingConv getDefaultCallingConv() const override { + return CC_C; } bool hasSjLjLowering() const override { return true; } @@ -659,7 +659,7 @@ class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : publi } } - CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override { + CallingConv getDefaultCallingConv() const override { return CC_C; } Modified: vendor/clang/dist-release_90/lib/Basic/Version.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/Basic/Version.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/Basic/Version.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -35,7 +35,7 @@ std::string getClangRepositoryPath() { // If the CLANG_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. - StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/trunk/lib/Basic/Version.cpp $"); + StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/branches/release_90/lib/Basic/Version.cpp $"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); Modified: vendor/clang/dist-release_90/lib/CodeGen/CGBuiltin.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/CodeGen/CGBuiltin.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/CodeGen/CGBuiltin.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -8011,7 +8011,152 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigne return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), "vgetq_lane"); } + case AArch64::BI_BitScanForward: + case AArch64::BI_BitScanForward64: + return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); + case AArch64::BI_BitScanReverse: + case AArch64::BI_BitScanReverse64: + return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); + case AArch64::BI_InterlockedAnd64: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); + case AArch64::BI_InterlockedExchange64: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); + case AArch64::BI_InterlockedExchangeAdd64: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); + case AArch64::BI_InterlockedExchangeSub64: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); + case AArch64::BI_InterlockedOr64: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); + case AArch64::BI_InterlockedXor64: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); + case AArch64::BI_InterlockedDecrement64: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); + case AArch64::BI_InterlockedIncrement64: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); + case AArch64::BI_InterlockedExchangeAdd8_acq: + case AArch64::BI_InterlockedExchangeAdd16_acq: + case AArch64::BI_InterlockedExchangeAdd_acq: + case AArch64::BI_InterlockedExchangeAdd64_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_acq, E); + case AArch64::BI_InterlockedExchangeAdd8_rel: + case AArch64::BI_InterlockedExchangeAdd16_rel: + case AArch64::BI_InterlockedExchangeAdd_rel: + case AArch64::BI_InterlockedExchangeAdd64_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_rel, E); + case AArch64::BI_InterlockedExchangeAdd8_nf: + case AArch64::BI_InterlockedExchangeAdd16_nf: + case AArch64::BI_InterlockedExchangeAdd_nf: + case AArch64::BI_InterlockedExchangeAdd64_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_nf, E); + case AArch64::BI_InterlockedExchange8_acq: + case AArch64::BI_InterlockedExchange16_acq: + case AArch64::BI_InterlockedExchange_acq: + case AArch64::BI_InterlockedExchange64_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange_acq, E); + case AArch64::BI_InterlockedExchange8_rel: + case AArch64::BI_InterlockedExchange16_rel: + case AArch64::BI_InterlockedExchange_rel: + case AArch64::BI_InterlockedExchange64_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange_rel, E); + case AArch64::BI_InterlockedExchange8_nf: + case AArch64::BI_InterlockedExchange16_nf: + case AArch64::BI_InterlockedExchange_nf: + case AArch64::BI_InterlockedExchange64_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange_nf, E); + case AArch64::BI_InterlockedCompareExchange8_acq: + case AArch64::BI_InterlockedCompareExchange16_acq: + case AArch64::BI_InterlockedCompareExchange_acq: + case AArch64::BI_InterlockedCompareExchange64_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedCompareExchange_acq, E); + case AArch64::BI_InterlockedCompareExchange8_rel: + case AArch64::BI_InterlockedCompareExchange16_rel: + case AArch64::BI_InterlockedCompareExchange_rel: + case AArch64::BI_InterlockedCompareExchange64_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedCompareExchange_rel, E); + case AArch64::BI_InterlockedCompareExchange8_nf: + case AArch64::BI_InterlockedCompareExchange16_nf: + case AArch64::BI_InterlockedCompareExchange_nf: + case AArch64::BI_InterlockedCompareExchange64_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedCompareExchange_nf, E); + case AArch64::BI_InterlockedOr8_acq: + case AArch64::BI_InterlockedOr16_acq: + case AArch64::BI_InterlockedOr_acq: + case AArch64::BI_InterlockedOr64_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr_acq, E); + case AArch64::BI_InterlockedOr8_rel: + case AArch64::BI_InterlockedOr16_rel: + case AArch64::BI_InterlockedOr_rel: + case AArch64::BI_InterlockedOr64_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr_rel, E); + case AArch64::BI_InterlockedOr8_nf: + case AArch64::BI_InterlockedOr16_nf: + case AArch64::BI_InterlockedOr_nf: + case AArch64::BI_InterlockedOr64_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr_nf, E); + case AArch64::BI_InterlockedXor8_acq: + case AArch64::BI_InterlockedXor16_acq: + case AArch64::BI_InterlockedXor_acq: + case AArch64::BI_InterlockedXor64_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor_acq, E); + case AArch64::BI_InterlockedXor8_rel: + case AArch64::BI_InterlockedXor16_rel: + case AArch64::BI_InterlockedXor_rel: + case AArch64::BI_InterlockedXor64_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor_rel, E); + case AArch64::BI_InterlockedXor8_nf: + case AArch64::BI_InterlockedXor16_nf: + case AArch64::BI_InterlockedXor_nf: + case AArch64::BI_InterlockedXor64_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor_nf, E); + case AArch64::BI_InterlockedAnd8_acq: + case AArch64::BI_InterlockedAnd16_acq: + case AArch64::BI_InterlockedAnd_acq: + case AArch64::BI_InterlockedAnd64_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd_acq, E); + case AArch64::BI_InterlockedAnd8_rel: + case AArch64::BI_InterlockedAnd16_rel: + case AArch64::BI_InterlockedAnd_rel: + case AArch64::BI_InterlockedAnd64_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd_rel, E); + case AArch64::BI_InterlockedAnd8_nf: + case AArch64::BI_InterlockedAnd16_nf: + case AArch64::BI_InterlockedAnd_nf: + case AArch64::BI_InterlockedAnd64_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd_nf, E); + case AArch64::BI_InterlockedIncrement16_acq: + case AArch64::BI_InterlockedIncrement_acq: + case AArch64::BI_InterlockedIncrement64_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement_acq, E); + case AArch64::BI_InterlockedIncrement16_rel: + case AArch64::BI_InterlockedIncrement_rel: + case AArch64::BI_InterlockedIncrement64_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement_rel, E); + case AArch64::BI_InterlockedIncrement16_nf: + case AArch64::BI_InterlockedIncrement_nf: + case AArch64::BI_InterlockedIncrement64_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement_nf, E); + case AArch64::BI_InterlockedDecrement16_acq: + case AArch64::BI_InterlockedDecrement_acq: + case AArch64::BI_InterlockedDecrement64_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement_acq, E); + case AArch64::BI_InterlockedDecrement16_rel: + case AArch64::BI_InterlockedDecrement_rel: + case AArch64::BI_InterlockedDecrement64_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement_rel, E); + case AArch64::BI_InterlockedDecrement16_nf: + case AArch64::BI_InterlockedDecrement_nf: + case AArch64::BI_InterlockedDecrement64_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement_nf, E); + + case AArch64::BI_InterlockedAdd: { + Value *Arg0 = EmitScalarExpr(E->getArg(0)); + Value *Arg1 = EmitScalarExpr(E->getArg(1)); + AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( + AtomicRMWInst::Add, Arg0, Arg1, + llvm::AtomicOrdering::SequentiallyConsistent); + return Builder.CreateAdd(RMWI, Arg1); } + } llvm::VectorType *VTy = GetNeonType(this, Type); llvm::Type *Ty = VTy; @@ -9127,151 +9272,6 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigne case NEON::BI__builtin_neon_vuqaddq_v: { Int = Intrinsic::aarch64_neon_suqadd; return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd"); - } - case AArch64::BI_BitScanForward: - case AArch64::BI_BitScanForward64: - return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); - case AArch64::BI_BitScanReverse: - case AArch64::BI_BitScanReverse64: - return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); - case AArch64::BI_InterlockedAnd64: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); - case AArch64::BI_InterlockedExchange64: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); - case AArch64::BI_InterlockedExchangeAdd64: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); - case AArch64::BI_InterlockedExchangeSub64: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); - case AArch64::BI_InterlockedOr64: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); - case AArch64::BI_InterlockedXor64: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); - case AArch64::BI_InterlockedDecrement64: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); - case AArch64::BI_InterlockedIncrement64: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); - case AArch64::BI_InterlockedExchangeAdd8_acq: - case AArch64::BI_InterlockedExchangeAdd16_acq: - case AArch64::BI_InterlockedExchangeAdd_acq: - case AArch64::BI_InterlockedExchangeAdd64_acq: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_acq, E); - case AArch64::BI_InterlockedExchangeAdd8_rel: - case AArch64::BI_InterlockedExchangeAdd16_rel: - case AArch64::BI_InterlockedExchangeAdd_rel: - case AArch64::BI_InterlockedExchangeAdd64_rel: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_rel, E); - case AArch64::BI_InterlockedExchangeAdd8_nf: - case AArch64::BI_InterlockedExchangeAdd16_nf: - case AArch64::BI_InterlockedExchangeAdd_nf: - case AArch64::BI_InterlockedExchangeAdd64_nf: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_nf, E); - case AArch64::BI_InterlockedExchange8_acq: - case AArch64::BI_InterlockedExchange16_acq: - case AArch64::BI_InterlockedExchange_acq: - case AArch64::BI_InterlockedExchange64_acq: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange_acq, E); - case AArch64::BI_InterlockedExchange8_rel: - case AArch64::BI_InterlockedExchange16_rel: - case AArch64::BI_InterlockedExchange_rel: - case AArch64::BI_InterlockedExchange64_rel: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange_rel, E); - case AArch64::BI_InterlockedExchange8_nf: - case AArch64::BI_InterlockedExchange16_nf: - case AArch64::BI_InterlockedExchange_nf: - case AArch64::BI_InterlockedExchange64_nf: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange_nf, E); - case AArch64::BI_InterlockedCompareExchange8_acq: - case AArch64::BI_InterlockedCompareExchange16_acq: - case AArch64::BI_InterlockedCompareExchange_acq: - case AArch64::BI_InterlockedCompareExchange64_acq: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedCompareExchange_acq, E); - case AArch64::BI_InterlockedCompareExchange8_rel: - case AArch64::BI_InterlockedCompareExchange16_rel: - case AArch64::BI_InterlockedCompareExchange_rel: - case AArch64::BI_InterlockedCompareExchange64_rel: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedCompareExchange_rel, E); - case AArch64::BI_InterlockedCompareExchange8_nf: - case AArch64::BI_InterlockedCompareExchange16_nf: - case AArch64::BI_InterlockedCompareExchange_nf: - case AArch64::BI_InterlockedCompareExchange64_nf: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedCompareExchange_nf, E); - case AArch64::BI_InterlockedOr8_acq: - case AArch64::BI_InterlockedOr16_acq: - case AArch64::BI_InterlockedOr_acq: - case AArch64::BI_InterlockedOr64_acq: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr_acq, E); - case AArch64::BI_InterlockedOr8_rel: - case AArch64::BI_InterlockedOr16_rel: - case AArch64::BI_InterlockedOr_rel: - case AArch64::BI_InterlockedOr64_rel: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr_rel, E); - case AArch64::BI_InterlockedOr8_nf: - case AArch64::BI_InterlockedOr16_nf: - case AArch64::BI_InterlockedOr_nf: - case AArch64::BI_InterlockedOr64_nf: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr_nf, E); - case AArch64::BI_InterlockedXor8_acq: - case AArch64::BI_InterlockedXor16_acq: - case AArch64::BI_InterlockedXor_acq: - case AArch64::BI_InterlockedXor64_acq: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor_acq, E); - case AArch64::BI_InterlockedXor8_rel: - case AArch64::BI_InterlockedXor16_rel: - case AArch64::BI_InterlockedXor_rel: - case AArch64::BI_InterlockedXor64_rel: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor_rel, E); - case AArch64::BI_InterlockedXor8_nf: - case AArch64::BI_InterlockedXor16_nf: - case AArch64::BI_InterlockedXor_nf: - case AArch64::BI_InterlockedXor64_nf: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor_nf, E); - case AArch64::BI_InterlockedAnd8_acq: - case AArch64::BI_InterlockedAnd16_acq: - case AArch64::BI_InterlockedAnd_acq: - case AArch64::BI_InterlockedAnd64_acq: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd_acq, E); - case AArch64::BI_InterlockedAnd8_rel: - case AArch64::BI_InterlockedAnd16_rel: - case AArch64::BI_InterlockedAnd_rel: - case AArch64::BI_InterlockedAnd64_rel: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd_rel, E); - case AArch64::BI_InterlockedAnd8_nf: - case AArch64::BI_InterlockedAnd16_nf: - case AArch64::BI_InterlockedAnd_nf: - case AArch64::BI_InterlockedAnd64_nf: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd_nf, E); - case AArch64::BI_InterlockedIncrement16_acq: - case AArch64::BI_InterlockedIncrement_acq: - case AArch64::BI_InterlockedIncrement64_acq: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement_acq, E); - case AArch64::BI_InterlockedIncrement16_rel: - case AArch64::BI_InterlockedIncrement_rel: - case AArch64::BI_InterlockedIncrement64_rel: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement_rel, E); - case AArch64::BI_InterlockedIncrement16_nf: - case AArch64::BI_InterlockedIncrement_nf: - case AArch64::BI_InterlockedIncrement64_nf: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement_nf, E); - case AArch64::BI_InterlockedDecrement16_acq: - case AArch64::BI_InterlockedDecrement_acq: - case AArch64::BI_InterlockedDecrement64_acq: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement_acq, E); - case AArch64::BI_InterlockedDecrement16_rel: - case AArch64::BI_InterlockedDecrement_rel: - case AArch64::BI_InterlockedDecrement64_rel: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement_rel, E); - case AArch64::BI_InterlockedDecrement16_nf: - case AArch64::BI_InterlockedDecrement_nf: - case AArch64::BI_InterlockedDecrement64_nf: - return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement_nf, E); - - case AArch64::BI_InterlockedAdd: { - Value *Arg0 = EmitScalarExpr(E->getArg(0)); - Value *Arg1 = EmitScalarExpr(E->getArg(1)); - AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( - AtomicRMWInst::Add, Arg0, Arg1, - llvm::AtomicOrdering::SequentiallyConsistent); - return Builder.CreateAdd(RMWI, Arg1); } } } Modified: vendor/clang/dist-release_90/lib/CodeGen/CGExprAgg.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/CodeGen/CGExprAgg.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/CodeGen/CGExprAgg.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -1495,6 +1495,13 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E // initializers throws an exception. SmallVector<EHScopeStack::stable_iterator, 16> cleanups; llvm::Instruction *cleanupDominator = nullptr; + auto addCleanup = [&](const EHScopeStack::stable_iterator &cleanup) { + cleanups.push_back(cleanup); + if (!cleanupDominator) // create placeholder once needed + cleanupDominator = CGF.Builder.CreateAlignedLoad( + CGF.Int8Ty, llvm::Constant::getNullValue(CGF.Int8PtrTy), + CharUnits::One()); + }; unsigned curInitIndex = 0; @@ -1519,7 +1526,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E if (QualType::DestructionKind dtorKind = Base.getType().isDestructedType()) { CGF.pushDestroy(dtorKind, V, Base.getType()); - cleanups.push_back(CGF.EHStack.stable_begin()); + addCleanup(CGF.EHStack.stable_begin()); } } } @@ -1596,15 +1603,9 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E = field->getType().isDestructedType()) { assert(LV.isSimple()); if (CGF.needsEHCleanup(dtorKind)) { - if (!cleanupDominator) - cleanupDominator = CGF.Builder.CreateAlignedLoad( - CGF.Int8Ty, - llvm::Constant::getNullValue(CGF.Int8PtrTy), - CharUnits::One()); // placeholder - CGF.pushDestroy(EHCleanup, LV.getAddress(), field->getType(), CGF.getDestroyer(dtorKind), false); - cleanups.push_back(CGF.EHStack.stable_begin()); + addCleanup(CGF.EHStack.stable_begin()); pushedCleanup = true; } } @@ -1620,6 +1621,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E // Deactivate all the partial cleanups in reverse order, which // generally means popping them. + assert((cleanupDominator || cleanups.empty()) && + "Missing cleanupDominator before deactivating cleanup blocks"); for (unsigned i = cleanups.size(); i != 0; --i) CGF.DeactivateCleanupBlock(cleanups[i-1], cleanupDominator); Modified: vendor/clang/dist-release_90/lib/CodeGen/CGStmt.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/CodeGen/CGStmt.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/CodeGen/CGStmt.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -1846,11 +1846,9 @@ llvm::Value* CodeGenFunction::EmitAsmInput( InputExpr->EvaluateAsRValue(EVResult, getContext(), true); llvm::APSInt IntResult; - if (!EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), - getContext())) - llvm_unreachable("Invalid immediate constant!"); - - return llvm::ConstantInt::get(getLLVMContext(), IntResult); + if (EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), + getContext())) + return llvm::ConstantInt::get(getLLVMContext(), IntResult); } Expr::EvalResult Result; Modified: vendor/clang/dist-release_90/lib/CodeGen/ItaniumCXXABI.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/CodeGen/ItaniumCXXABI.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/CodeGen/ItaniumCXXABI.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -1755,10 +1755,11 @@ llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall( CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty); QualType ThisTy; - if (CE) - ThisTy = CE->getImplicitObjectArgument()->getType()->getPointeeType(); - else + if (CE) { + ThisTy = CE->getObjectType(); + } else { ThisTy = D->getDestroyedType(); + } CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, nullptr, QualType(), nullptr); Modified: vendor/clang/dist-release_90/lib/CodeGen/MicrosoftCXXABI.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/CodeGen/MicrosoftCXXABI.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/CodeGen/MicrosoftCXXABI.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -1921,10 +1921,11 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCal DtorType == Dtor_Deleting); QualType ThisTy; - if (CE) - ThisTy = CE->getImplicitObjectArgument()->getType()->getPointeeType(); - else + if (CE) { + ThisTy = CE->getObjectType(); + } else { ThisTy = D->getDestroyedType(); + } This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true); RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, Modified: vendor/clang/dist-release_90/lib/CodeGen/TargetInfo.cpp ============================================================================== --- vendor/clang/dist-release_90/lib/CodeGen/TargetInfo.cpp Tue Aug 20 21:35:24 2019 (r351304) +++ vendor/clang/dist-release_90/lib/CodeGen/TargetInfo.cpp Tue Aug 20 21:35:28 2019 (r351305) @@ -9188,25 +9188,45 @@ static bool getTypeString(SmallStringEnc &Enc, const D namespace { class RISCVABIInfo : public DefaultABIInfo { private: - unsigned XLen; // Size of the integer ('x') registers in bits. + // Size of the integer ('x') registers in bits. + unsigned XLen; + // Size of the floating point ('f') registers in bits. Note that the target + // ISA might have a wider FLen than the selected ABI (e.g. an RV32IF target + // with soft float ABI has FLen==0). + unsigned FLen; static const int NumArgGPRs = 8; + static const int NumArgFPRs = 8; + bool detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff, + llvm::Type *&Field1Ty, + CharUnits &Field1Off, + llvm::Type *&Field2Ty, + CharUnits &Field2Off) const; public: - RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen) - : DefaultABIInfo(CGT), XLen(XLen) {} + RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, unsigned FLen) + : DefaultABIInfo(CGT), XLen(XLen), FLen(FLen) {} // DefaultABIInfo's classifyReturnType and classifyArgumentType are // non-virtual, but computeInfo is virtual, so we overload it. void computeInfo(CGFunctionInfo &FI) const override; - ABIArgInfo classifyArgumentType(QualType Ty, bool IsFixed, - int &ArgGPRsLeft) const; + ABIArgInfo classifyArgumentType(QualType Ty, bool IsFixed, int &ArgGPRsLeft, + int &ArgFPRsLeft) const; ABIArgInfo classifyReturnType(QualType RetTy) const; Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const override; ABIArgInfo extendType(QualType Ty) const; + + bool detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty, + CharUnits &Field1Off, llvm::Type *&Field2Ty, + CharUnits &Field2Off, int &NeededArgGPRs, + int &NeededArgFPRs) const; + ABIArgInfo coerceAndExpandFPCCEligibleStruct(llvm::Type *Field1Ty, + CharUnits Field1Off, + llvm::Type *Field2Ty, + CharUnits Field2Off) const; }; } // end anonymous namespace @@ -9228,18 +9248,215 @@ void RISCVABIInfo::computeInfo(CGFunctionInfo &FI) con // different for variadic arguments, we must also track whether we are // examining a vararg or not. int ArgGPRsLeft = IsRetIndirect ? NumArgGPRs - 1 : NumArgGPRs; + int ArgFPRsLeft = FLen ? NumArgFPRs : 0; int NumFixedArgs = FI.getNumRequiredArgs(); int ArgNum = 0; for (auto &ArgInfo : FI.arguments()) { bool IsFixed = ArgNum < NumFixedArgs; - ArgInfo.info = classifyArgumentType(ArgInfo.type, IsFixed, ArgGPRsLeft); + ArgInfo.info = + classifyArgumentType(ArgInfo.type, IsFixed, ArgGPRsLeft, ArgFPRsLeft); ArgNum++; } } +// Returns true if the struct is a potential candidate for the floating point +// calling convention. If this function returns true, the caller is +// responsible for checking that if there is only a single field then that +// field is a float. +bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff, + llvm::Type *&Field1Ty, + CharUnits &Field1Off, + llvm::Type *&Field2Ty, + CharUnits &Field2Off) const { + bool IsInt = Ty->isIntegralOrEnumerationType(); + bool IsFloat = Ty->isRealFloatingType(); + + if (IsInt || IsFloat) { + uint64_t Size = getContext().getTypeSize(Ty); + if (IsInt && Size > XLen) + return false; + // Can't be eligible if larger than the FP registers. Half precision isn't + // currently supported on RISC-V and the ABI hasn't been confirmed, so + // default to the integer ABI in that case. + if (IsFloat && (Size > FLen || Size < 32)) + return false; + // Can't be eligible if an integer type was already found (int+int pairs + // are not eligible). + if (IsInt && Field1Ty && Field1Ty->isIntegerTy()) + return false; + if (!Field1Ty) { + Field1Ty = CGT.ConvertType(Ty); + Field1Off = CurOff; + return true; + } + if (!Field2Ty) { + Field2Ty = CGT.ConvertType(Ty); + Field2Off = CurOff; + return true; + } + return false; + } + + if (auto CTy = Ty->getAs<ComplexType>()) { + if (Field1Ty) + return false; + QualType EltTy = CTy->getElementType(); + if (getContext().getTypeSize(EltTy) > FLen) + return false; + Field1Ty = CGT.ConvertType(EltTy); + Field1Off = CurOff; + assert(CurOff.isZero() && "Unexpected offset for first field"); + Field2Ty = Field1Ty; + Field2Off = Field1Off + getContext().getTypeSizeInChars(EltTy); + return true; + } + + if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) { + uint64_t ArraySize = ATy->getSize().getZExtValue(); + QualType EltTy = ATy->getElementType(); + CharUnits EltSize = getContext().getTypeSizeInChars(EltTy); + for (uint64_t i = 0; i < ArraySize; ++i) { + bool Ret = detectFPCCEligibleStructHelper(EltTy, CurOff, Field1Ty, + Field1Off, Field2Ty, Field2Off); + if (!Ret) + return false; + CurOff += EltSize; + } + return true; + } + + if (const auto *RTy = Ty->getAs<RecordType>()) { + // Structures with either a non-trivial destructor or a non-trivial + // copy constructor are not eligible for the FP calling convention. + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT.getCXXABI())) + return false; + if (isEmptyRecord(getContext(), Ty, true)) + return true; + const RecordDecl *RD = RTy->getDecl(); + // Unions aren't eligible unless they're empty (which is caught above). + if (RD->isUnion()) + return false; + int ZeroWidthBitFieldCount = 0; + for (const FieldDecl *FD : RD->fields()) { + const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); + uint64_t FieldOffInBits = Layout.getFieldOffset(FD->getFieldIndex()); + QualType QTy = FD->getType(); + if (FD->isBitField()) { + unsigned BitWidth = FD->getBitWidthValue(getContext()); + // Allow a bitfield with a type greater than XLen as long as the + // bitwidth is XLen or less. + if (getContext().getTypeSize(QTy) > XLen && BitWidth <= XLen) + QTy = getContext().getIntTypeForBitwidth(XLen, false); + if (BitWidth == 0) { + ZeroWidthBitFieldCount++; + continue; + } + } + + bool Ret = detectFPCCEligibleStructHelper( + QTy, CurOff + getContext().toCharUnitsFromBits(FieldOffInBits), + Field1Ty, Field1Off, Field2Ty, Field2Off); + if (!Ret) + return false; + + // As a quirk of the ABI, zero-width bitfields aren't ignored for fp+fp + // or int+fp structs, but are ignored for a struct with an fp field and + // any number of zero-width bitfields. + if (Field2Ty && ZeroWidthBitFieldCount > 0) + return false; + } + return Field1Ty != nullptr; + } + + return false; +} + +// Determine if a struct is eligible for passing according to the floating +// point calling convention (i.e., when flattened it contains a single fp +// value, fp+fp, or int+fp of appropriate size). If so, NeededArgFPRs and +// NeededArgGPRs are incremented appropriately. +bool RISCVABIInfo::detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty, + CharUnits &Field1Off, + llvm::Type *&Field2Ty, + CharUnits &Field2Off, + int &NeededArgGPRs, + int &NeededArgFPRs) const { + Field1Ty = nullptr; + Field2Ty = nullptr; + NeededArgGPRs = 0; + NeededArgFPRs = 0; + bool IsCandidate = detectFPCCEligibleStructHelper( + Ty, CharUnits::Zero(), Field1Ty, Field1Off, Field2Ty, Field2Off); + // Not really a candidate if we have a single int but no float. + if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy()) + return IsCandidate = false; + if (!IsCandidate) + return false; + if (Field1Ty && Field1Ty->isFloatingPointTy()) + NeededArgFPRs++; + else if (Field1Ty) + NeededArgGPRs++; + if (Field2Ty && Field2Ty->isFloatingPointTy()) + NeededArgFPRs++; + else if (Field2Ty) + NeededArgGPRs++; + return IsCandidate; +} + +// Call getCoerceAndExpand for the two-element flattened struct described by +// Field1Ty, Field1Off, Field2Ty, Field2Off. This method will create an +// appropriate coerceToType and unpaddedCoerceToType. +ABIArgInfo RISCVABIInfo::coerceAndExpandFPCCEligibleStruct( + llvm::Type *Field1Ty, CharUnits Field1Off, llvm::Type *Field2Ty, + CharUnits Field2Off) const { + SmallVector<llvm::Type *, 3> CoerceElts; + SmallVector<llvm::Type *, 2> UnpaddedCoerceElts; + if (!Field1Off.isZero()) + CoerceElts.push_back(llvm::ArrayType::get( + llvm::Type::getInt8Ty(getVMContext()), Field1Off.getQuantity())); + + CoerceElts.push_back(Field1Ty); + UnpaddedCoerceElts.push_back(Field1Ty); + + if (!Field2Ty) { + return ABIArgInfo::getCoerceAndExpand( + llvm::StructType::get(getVMContext(), CoerceElts, !Field1Off.isZero()), + UnpaddedCoerceElts[0]); + } + + CharUnits Field2Align = + CharUnits::fromQuantity(getDataLayout().getABITypeAlignment(Field2Ty)); + CharUnits Field1Size = + CharUnits::fromQuantity(getDataLayout().getTypeStoreSize(Field1Ty)); + CharUnits Field2OffNoPadNoPack = Field1Size.alignTo(Field2Align); + + CharUnits Padding = CharUnits::Zero(); + if (Field2Off > Field2OffNoPadNoPack) + Padding = Field2Off - Field2OffNoPadNoPack; + else if (Field2Off != Field2Align && Field2Off > Field1Size) + Padding = Field2Off - Field1Size; + + bool IsPacked = !Field2Off.isMultipleOf(Field2Align); + + if (!Padding.isZero()) + CoerceElts.push_back(llvm::ArrayType::get( + llvm::Type::getInt8Ty(getVMContext()), Padding.getQuantity())); + + CoerceElts.push_back(Field2Ty); + UnpaddedCoerceElts.push_back(Field2Ty); + + auto CoerceToType = + llvm::StructType::get(getVMContext(), CoerceElts, IsPacked); + auto UnpaddedCoerceToType = + llvm::StructType::get(getVMContext(), UnpaddedCoerceElts, IsPacked); + + return ABIArgInfo::getCoerceAndExpand(CoerceToType, UnpaddedCoerceToType); +} + ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, - int &ArgGPRsLeft) const { + int &ArgGPRsLeft, + int &ArgFPRsLeft) const { assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow"); Ty = useFirstFieldIfTransparentUnion(Ty); @@ -9257,6 +9474,42 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType return ABIArgInfo::getIgnore(); uint64_t Size = getContext().getTypeSize(Ty); + + // Pass floating point values via FPRs if possible. + if (IsFixed && Ty->isFloatingType() && FLen >= Size && ArgFPRsLeft) { + ArgFPRsLeft--; + return ABIArgInfo::getDirect(); + } + + // Complex types for the hard float ABI must be passed direct rather than + // using CoerceAndExpand. + if (IsFixed && Ty->isComplexType() && FLen && ArgFPRsLeft >= 2) { + QualType EltTy = Ty->getAs<ComplexType>()->getElementType(); + if (getContext().getTypeSize(EltTy) <= FLen) { + ArgFPRsLeft -= 2; + return ABIArgInfo::getDirect(); + } + } + + if (IsFixed && FLen && Ty->isStructureOrClassType()) { + llvm::Type *Field1Ty = nullptr; + llvm::Type *Field2Ty = nullptr; + CharUnits Field1Off = CharUnits::Zero(); + CharUnits Field2Off = CharUnits::Zero(); + int NeededArgGPRs; + int NeededArgFPRs; + bool IsCandidate = + detectFPCCEligibleStruct(Ty, Field1Ty, Field1Off, Field2Ty, Field2Off, + NeededArgGPRs, NeededArgFPRs); + if (IsCandidate && NeededArgGPRs <= ArgGPRsLeft && + NeededArgFPRs <= ArgFPRsLeft) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201908202135.x7KLZTRK005751>