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"