diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.def b/llvm/include/llvm/Analysis/TargetLibraryInfo.def --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.def +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.def @@ -262,6 +262,12 @@ /// long double __atanhl_finite(long double x); TLI_DEFINE_ENUM_INTERNAL(atanhl_finite) TLI_DEFINE_STRING_INTERNAL("__atanhl_finite") +/// void __atomic_load(size_t size, void *mptr, void *vptr, int smodel); +TLI_DEFINE_ENUM_INTERNAL(atomic_load) +TLI_DEFINE_STRING_INTERNAL("__atomic_load") +/// void __atomic_store(size_t size, void *mptr, void *vptr, int smodel); +TLI_DEFINE_ENUM_INTERNAL(atomic_store) +TLI_DEFINE_STRING_INTERNAL("__atomic_store") /// double __cosh_finite(double x); TLI_DEFINE_ENUM_INTERNAL(cosh_finite) TLI_DEFINE_STRING_INTERNAL("__cosh_finite") diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -86,6 +86,9 @@ TLI.setUnavailable(LibFunc_fputs_unlocked); TLI.setUnavailable(LibFunc_fgets_unlocked); + TLI.setUnavailable(LibFunc_atomic_load); + TLI.setUnavailable(LibFunc_atomic_store); + bool ShouldExtI32Param = false, ShouldExtI32Return = false, ShouldSignExtI32Param = false; // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and @@ -172,6 +175,8 @@ TLI.setUnavailable(LibFunc_small_fprintf); } + bool isARM = (T.getArch() == Triple::aarch64 || T.getArch() == Triple::arm); + if (T.isOSWindows() && !T.isOSCygMing()) { // XXX: The earliest documentation available at the moment is for VS2015/VC19: // https://docs.microsoft.com/en-us/cpp/c-runtime-library/floating-point-support?view=vs-2015 @@ -186,8 +191,6 @@ } // Latest targets support C89 math functions, in part. - bool isARM = (T.getArch() == Triple::aarch64 || - T.getArch() == Triple::arm); bool hasPartialFloat = (isARM || T.getArch() == Triple::x86_64); @@ -549,6 +552,14 @@ TLI.setUnavailable(LibFunc_nvvm_reflect); } + // libatomic __atomic_load and __atomic_store are available on platforms + // which support atomic operations. Even if there's no libatomic.a library, + // LLVM will generate calls to them which may be fulfilled by compiler-rt + if (isARM || T.isX86() || T.isPPC64() || T.isRISCV()) { + TLI.setAvailable(LibFunc_atomic_load); + TLI.setAvailable(LibFunc_atomic_store); + } + TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary); } @@ -1228,6 +1239,15 @@ case LibFunc_ZdaPvmSt11align_val_t: return (NumParams == 3 && FTy.getParamType(0)->isPointerTy()); + case LibFunc_atomic_load: + // void __atomic_load(size_t, void *, void *, int) + case LibFunc_atomic_store: + // void __atomic_store(size_t, void *, void *, int) + return (NumParams == 4 && FTy.getParamType(0)->isIntegerTy() && + FTy.getParamType(1)->isPointerTy() && + FTy.getParamType(2)->isPointerTy() && + FTy.getParamType(3)->isIntegerTy()); + case LibFunc_memset_pattern16: return (!FTy.isVarArg() && NumParams == 3 && FTy.getParamType(0)->isPointerTy() && diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp --- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp +++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp @@ -495,6 +495,9 @@ "declare i8* @mempcpy(i8*, i8*, i64)\n" "declare i8* @memrchr(i8*, i32, i64)\n" + "declare void @__atomic_load(i64, i8*, i8*, i32)\n" + "declare void @__atomic_store(i64, i8*, i8*, i32)\n" + // These are similar to the FILE* fgetc/fputc. "declare i32 @_IO_getc(%struct*)\n" "declare i32 @_IO_putc(i32, %struct*)\n"