Project import generated by Copybara.

GitOrigin-RevId: b994299e59c9aac01ca0a494b2b861ebd5acc190
Change-Id: I0b7b67a51319af75213a1713a792a4cdc1006ce7
diff --git a/hdr/stdlib_overlay.h b/hdr/stdlib_overlay.h
index f095caf..53c32ec 100644
--- a/hdr/stdlib_overlay.h
+++ b/hdr/stdlib_overlay.h
@@ -19,6 +19,11 @@
 // functions, causing external alias errors.  They are guarded by
 // `__USE_FORTIFY_LEVEL`, which will be temporarily disabled.
 
+#ifdef _FORTIFY_SOURCE
+#define LIBC_OLD_FORTIFY_SOURCE _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+
 #ifdef __USE_FORTIFY_LEVEL
 #define LIBC_OLD_USE_FORTIFY_LEVEL __USE_FORTIFY_LEVEL
 #undef __USE_FORTIFY_LEVEL
@@ -27,6 +32,11 @@
 
 #include <stdlib.h>
 
+#ifdef LIBC_OLD_FORTIFY_SOURCE
+#define _FORTIFY_SOURCE LIBC_OLD_FORTIFY_SOURCE
+#undef LIBC_OLD_FORTIFY_SOURCE
+#endif
+
 #ifdef LIBC_OLD_USE_FORTIFY_LEVEL
 #undef __USE_FORTIFY_LEVEL
 #define __USE_FORTIFY_LEVEL LIBC_OLD_USE_FORTIFY_LEVEL
diff --git a/src/math/atanf16.h b/src/math/atanf16.h
new file mode 100644
index 0000000..96ae35c
--- /dev/null
+++ b/src/math/atanf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for atanf16 -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_ATANF16_H
+#define LLVM_LIBC_SRC_MATH_ATANF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float16 atanf16(float16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ATANF16_H
diff --git a/src/math/generic/atanf16.cpp b/src/math/generic/atanf16.cpp
new file mode 100644
index 0000000..9b6ec65
--- /dev/null
+++ b/src/math/generic/atanf16.cpp
@@ -0,0 +1,107 @@
+//===-- Half-precision atanf16(x) function --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception.
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/atanf16.h"
+#include "hdr/errno_macros.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+// Generated by Solly using the following command:
+// > round(pi/2, SG, RN);
+static constexpr float PI_2 = 0x1.921fb6p0;
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+static constexpr size_t N_EXCEPTS = 6;
+
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ATANF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    {0x2745, 0x2744, 1, 0, 1},
+    {0x3099, 0x3090, 1, 0, 1},
+    {0x3c6c, 0x3aae, 1, 0, 1},
+    {0x466e, 0x3daa, 1, 0, 1},
+    {0x48ae, 0x3ddb, 1, 0, 0},
+    {0x5619, 0x3e3d, 1, 0, 1},
+}};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+LLVM_LIBC_FUNCTION(float16, atanf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+  bool x_sign = x_u >> 15;
+  float sign = (x_sign ? -1.0 : 1.0);
+
+  // |x| >= +/-inf
+  if (LIBC_UNLIKELY(x_abs >= 0x7c00)) {
+    if (xbits.is_nan()) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+        return FPBits::quiet_nan().get_val();
+      }
+      return x;
+    }
+
+    // atanf16(+/-inf) = +/-pi/2
+    return fputil::cast<float16>(sign * PI_2);
+  }
+
+  float xf = x;
+  float xsq = xf * xf;
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+  // Handle exceptional values
+  if (auto r = ATANF16_EXCEPTS.lookup_odd(x_abs, x_sign);
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+#endif
+
+  // |x| <= 0x1p0, |x| <= 1
+  if (x_abs <= 0x3c00) {
+    // atanf16(+/-0) = +/-0
+    if (LIBC_UNLIKELY(x_abs == 0))
+      return x;
+
+    // Degree-14 minimax odd polynomial of atan(x) generated by Sollya with:
+    // > P = fpminimax(atan(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|], [|SG...|],
+    // [0, 1]);
+    float result = fputil::polyeval(
+        xsq, 0x1.fffffcp-1f, -0x1.55519ep-2f, 0x1.98f6a8p-3f, -0x1.1f0a92p-3f,
+        0x1.95b654p-4f, -0x1.e65492p-5f, 0x1.8c0c36p-6f, -0x1.32316ep-8f);
+    return fputil::cast<float16>(xf * result);
+  }
+
+  // If |x| > 1
+  // y = atan(x) = sign(x) * atan(|x|)
+  // atan(|x|) = pi/2 - atan(1/|x|)
+  // Recall, 1/|x| < 1
+  float x_inv_sq = 1.0f / xsq;
+  float x_inv = fputil::sqrt<float>(x_inv_sq);
+
+  // Degree-14 minimax odd polynomial of atan(x) generated by Sollya with:
+  // > P = fpminimax(atan(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|], [|SG...|],
+  // [0, 1]);
+  float interm =
+      fputil::polyeval(x_inv_sq, 0x1.fffffcp-1f, -0x1.55519ep-2f,
+                       0x1.98f6a8p-3f, -0x1.1f0a92p-3f, 0x1.95b654p-4f,
+                       -0x1.e65492p-5f, 0x1.8c0c36p-6f, -0x1.32316ep-8f);
+
+  return fputil::cast<float16>(sign *
+                               fputil::multiply_add(x_inv, -interm, PI_2));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/src/wchar/wcscat.cpp b/src/wchar/wcscat.cpp
new file mode 100644
index 0000000..50d90c0
--- /dev/null
+++ b/src/wchar/wcscat.cpp
@@ -0,0 +1,29 @@
+//===-- Implementation of wcscat ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wcscat.h"
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/string/string_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(wchar_t *, wcscat,
+                   (wchar_t *__restrict s1, const wchar_t *__restrict s2)) {
+  size_t size_1 = internal::string_length(s1);
+  size_t i = 0;
+  for (; s2[i] != L'\0'; i++)
+    s1[size_1 + i] = s2[i];
+  s1[size_1 + i] = L'\0';
+  return s1;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/src/wchar/wcscat.h b/src/wchar/wcscat.h
new file mode 100644
index 0000000..b0b4455
--- /dev/null
+++ b/src/wchar/wcscat.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for wcscat ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_WCHAR_WCSCAT_H
+#define LLVM_LIBC_SRC_WCHAR_WCSCAT_H
+
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+wchar_t *wcscat(wchar_t *__restrict s1, const wchar_t *__restrict s2);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCSCAT_H
diff --git a/src/wchar/wcscmp.cpp b/src/wchar/wcscmp.cpp
new file mode 100644
index 0000000..f285efd
--- /dev/null
+++ b/src/wchar/wcscmp.cpp
@@ -0,0 +1,30 @@
+//===-- Implementation of wcscmp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wcscmp.h"
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/null_check.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, wcscmp, (const wchar_t *left, const wchar_t *right)) {
+  LIBC_CRASH_ON_NULLPTR(left);
+  LIBC_CRASH_ON_NULLPTR(right);
+
+  auto comp = [](wchar_t l, wchar_t r) -> int { return l - r; };
+
+  for (; *left && !comp(*left, *right); ++left, ++right)
+    ;
+
+  return comp(*left, *right);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/src/wchar/wcscmp.h b/src/wchar/wcscmp.h
new file mode 100644
index 0000000..af82d06
--- /dev/null
+++ b/src/wchar/wcscmp.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for wcscmp ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_WCHAR_WCSCMP_H
+#define LLVM_LIBC_SRC_WCHAR_WCSCMP_H
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int wcscmp(const wchar_t *left, const wchar_t *right);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCSCMP_H
diff --git a/src/wchar/wcscpy.cpp b/src/wchar/wcscpy.cpp
new file mode 100644
index 0000000..dc46b972
--- /dev/null
+++ b/src/wchar/wcscpy.cpp
@@ -0,0 +1,27 @@
+//===-- Implementation of wcscpy ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wcscpy.h"
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/string/memory_utils/inline_memcpy.h"
+#include "src/string/string_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(wchar_t *, wcscpy,
+                   (wchar_t *__restrict s1, const wchar_t *__restrict s2)) {
+  size_t size = internal::string_length(s2) + 1;
+  inline_memcpy(s1, s2, size * sizeof(wchar_t));
+  return s1;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/src/wchar/wcscpy.h b/src/wchar/wcscpy.h
new file mode 100644
index 0000000..c3f0e5f
--- /dev/null
+++ b/src/wchar/wcscpy.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for wcscpy ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_WCHAR_WCSCPY_H
+#define LLVM_LIBC_SRC_WCHAR_WCSCPY_H
+
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+wchar_t *wcscpy(wchar_t *__restrict s1, const wchar_t *__restrict s2);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCSCPY_H
diff --git a/src/wchar/wcsncat.cpp b/src/wchar/wcsncat.cpp
new file mode 100644
index 0000000..62595b4
--- /dev/null
+++ b/src/wchar/wcsncat.cpp
@@ -0,0 +1,31 @@
+//===-- Implementation of wcsncat -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wcsncat.h"
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/string/string_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(wchar_t *, wcsncat,
+                   (wchar_t *__restrict s1, const wchar_t *__restrict s2,
+                    size_t n)) {
+  size_t size = internal::string_length(s1);
+  size_t i = 0;
+  for (; s2[i] && i < n; ++i)
+    s1[size + i] = s2[i];
+  // Appending null character to the end of the result.
+  s1[size + i] = L'\0';
+  return s1;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/src/wchar/wcsncat.h b/src/wchar/wcsncat.h
new file mode 100644
index 0000000..978645e
--- /dev/null
+++ b/src/wchar/wcsncat.h
@@ -0,0 +1,23 @@
+//===-- Implementation header for wcsncat ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_WCHAR_WCSNCAT_H
+#define LLVM_LIBC_SRC_WCHAR_WCSNCAT_H
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+wchar_t *wcsncat(wchar_t *__restrict s1, const wchar_t *__restrict s2,
+                 size_t n);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCSNCAT_H
diff --git a/src/wchar/wcsncmp.cpp b/src/wchar/wcsncmp.cpp
new file mode 100644
index 0000000..f2e052b
--- /dev/null
+++ b/src/wchar/wcsncmp.cpp
@@ -0,0 +1,37 @@
+//===-- Implementation of wcsncmp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wcsncmp.h"
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/null_check.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, wcsncmp,
+                   (const wchar_t *left, const wchar_t *right, size_t n)) {
+  LIBC_CRASH_ON_NULLPTR(left);
+  LIBC_CRASH_ON_NULLPTR(right);
+
+  if (n == 0)
+    return 0;
+
+  auto comp = [](wchar_t l, wchar_t r) -> int { return l - r; };
+
+  for (; n > 1; --n, ++left, ++right) {
+    wchar_t lc = *left;
+    if (!comp(lc, '\0') || comp(lc, *right))
+      break;
+  }
+  return comp(*reinterpret_cast<const wchar_t *>(left),
+              *reinterpret_cast<const wchar_t *>(right));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/src/wchar/wcsncmp.h b/src/wchar/wcsncmp.h
new file mode 100644
index 0000000..0b4187e73
--- /dev/null
+++ b/src/wchar/wcsncmp.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for wcsncmp ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_WCHAR_WCSNCMP_H
+#define LLVM_LIBC_SRC_WCHAR_WCSNCMP_H
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int wcsncmp(const wchar_t *left, const wchar_t *right, size_t n);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCSNCMP_H
diff --git a/src/wchar/wcspbrk.cpp b/src/wchar/wcspbrk.cpp
index bf305a5..a00ba99 100644
--- a/src/wchar/wcspbrk.cpp
+++ b/src/wchar/wcspbrk.cpp
@@ -10,6 +10,7 @@
 
 #include "hdr/types/wchar_t.h"
 #include "src/__support/common.h"
+#include "src/__support/macros/null_check.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
@@ -23,6 +24,9 @@
 
 LLVM_LIBC_FUNCTION(const wchar_t *, wcspbrk,
                    (const wchar_t *src, const wchar_t *breakset)) {
+  LIBC_CRASH_ON_NULLPTR(src);
+  LIBC_CRASH_ON_NULLPTR(breakset);
+
   // currently O(n * m), can be further optimized to O(n + m) with a hash set
   for (int src_idx = 0; src[src_idx] != 0; src_idx++)
     if (contains_char(breakset, src[src_idx]))
diff --git a/src/wchar/wcsrchr.cpp b/src/wchar/wcsrchr.cpp
new file mode 100644
index 0000000..bb4e373
--- /dev/null
+++ b/src/wchar/wcsrchr.cpp
@@ -0,0 +1,31 @@
+//===-- Implementation of wcsrchr -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wcsrchr.h"
+
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(const wchar_t *, wcsrchr, (const wchar_t *s, wchar_t c)) {
+  LIBC_CRASH_ON_NULLPTR(s);
+
+  const wchar_t *last_occurrence = nullptr;
+  while (true) {
+    if (*s == c)
+      last_occurrence = s;
+    if (*s == L'\0')
+      return last_occurrence;
+    ++s;
+  }
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/src/wchar/wcsrchr.h b/src/wchar/wcsrchr.h
new file mode 100644
index 0000000..5e9d8c3
--- /dev/null
+++ b/src/wchar/wcsrchr.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for wcsrchr ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_WCHAR_WCSRCHR_H
+#define LLVM_LIBC_SRC_WCHAR_WCSRCHR_H
+
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+const wchar_t *wcsrchr(const wchar_t *s, wchar_t c);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCSRCHR_H
diff --git a/src/wchar/wcsstr.cpp b/src/wchar/wcsstr.cpp
new file mode 100644
index 0000000..961835a
--- /dev/null
+++ b/src/wchar/wcsstr.cpp
@@ -0,0 +1,38 @@
+//===-- Implementation of wcsstr ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wcsstr.h"
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/string/string_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(const wchar_t *, wcsstr,
+                   (const wchar_t *s1, const wchar_t *s2)) {
+  size_t s1_len = internal::string_length(s1);
+  size_t s2_len = internal::string_length(s2);
+  if (s2_len == 0)
+    return s1;
+  if (s2_len > s1_len)
+    return nullptr;
+  for (size_t i = 0; i <= (s1_len - s2_len); ++i) {
+    size_t j = 0;
+    // j will increment until the characters don't match or end of string.
+    for (; j < s2_len && s1[i + j] == s2[j]; ++j)
+      ;
+    if (j == s2_len)
+      return (s1 + i);
+  }
+  return nullptr;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/src/wchar/wcsstr.h b/src/wchar/wcsstr.h
new file mode 100644
index 0000000..af054d8
--- /dev/null
+++ b/src/wchar/wcsstr.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for wcsstr ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_WCHAR_WCSSTR_H
+#define LLVM_LIBC_SRC_WCHAR_WCSSTR_H
+
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+const wchar_t *wcsstr(const wchar_t *s1, const wchar_t *s2);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCSSTR_H
diff --git a/src/wchar/wmempcpy.cpp b/src/wchar/wmempcpy.cpp
new file mode 100644
index 0000000..d8b89c0
--- /dev/null
+++ b/src/wchar/wmempcpy.cpp
@@ -0,0 +1,25 @@
+//===-- Implementation of wmempcpy ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wmempcpy.h"
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/string/memory_utils/inline_memcpy.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(wchar_t *, wmempcpy,
+                   (wchar_t *__restrict to, const wchar_t *__restrict from,
+                    size_t size)) {
+  inline_memcpy(to, from, size * sizeof(wchar_t));
+  return reinterpret_cast<wchar_t *>(to) + size;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/src/wchar/wmempcpy.h b/src/wchar/wmempcpy.h
new file mode 100644
index 0000000..580674b
--- /dev/null
+++ b/src/wchar/wmempcpy.h
@@ -0,0 +1,23 @@
+//===-- Implementation header for wmempcpy---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_WCHAR_WMEMPCPY_H
+#define LLVM_LIBC_SRC_WCHAR_WMEMPCPY_H
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+wchar_t *wmempcpy(wchar_t *__restrict from, const wchar_t *__restrict s2,
+                  size_t n);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WMEMPCPY_H
diff --git a/test/src/math/atanf16_test.cpp b/test/src/math/atanf16_test.cpp
new file mode 100644
index 0000000..fa383e7
--- /dev/null
+++ b/test/src/math/atanf16_test.cpp
@@ -0,0 +1,40 @@
+//===-- Exhaustive test for atanf16 ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/atanf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcAtanf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+// Range: [0, Inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7c00U;
+
+// Range: [-Inf, 0]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xfc00U;
+
+TEST_F(LlvmLibcAtanf16Test, PositiveRange) {
+  for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
+    float16 x = FPBits(v).get_val();
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+                                   LIBC_NAMESPACE::atanf16(x), 0.5);
+  }
+}
+
+TEST_F(LlvmLibcAtanf16Test, NegativeRange) {
+  for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
+    float16 x = FPBits(v).get_val();
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+                                   LIBC_NAMESPACE::atanf16(x), 0.5);
+  }
+}
diff --git a/test/src/math/smoke/atanf16_test.cpp b/test/src/math/smoke/atanf16_test.cpp
new file mode 100644
index 0000000..af50287
--- /dev/null
+++ b/test/src/math/smoke/atanf16_test.cpp
@@ -0,0 +1,35 @@
+//===-- Unittests for atanf16 ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception.
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/atanf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAtanf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAtanf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::atanf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::atanf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(zero, LIBC_NAMESPACE::atanf16(zero));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::atanf16(neg_zero));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(0x1.92p0, LIBC_NAMESPACE::atanf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(-0x1.92p0, LIBC_NAMESPACE::atanf16(neg_inf));
+  EXPECT_MATH_ERRNO(0);
+}
diff --git a/test/src/wchar/wcscat_test.cpp b/test/src/wchar/wcscat_test.cpp
new file mode 100644
index 0000000..e91f796
--- /dev/null
+++ b/test/src/wchar/wcscat_test.cpp
@@ -0,0 +1,47 @@
+//===-- Unittests for wcscat ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/wchar_t.h"
+#include "src/wchar/wcscat.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcWCSCatTest, EmptyDest) {
+  // Dest should be fully replaced with src.
+  wchar_t dest[4] = {L'\0'};
+  const wchar_t *src = L"abc";
+  LIBC_NAMESPACE::wcscat(dest, src);
+  ASSERT_TRUE(dest[0] == L'a');
+  ASSERT_TRUE(dest[1] == L'b');
+  ASSERT_TRUE(dest[2] == L'c');
+  ASSERT_TRUE(dest[3] == L'\0');
+}
+
+TEST(LlvmLibcWCSCatTest, NonEmptyDest) {
+  // Src should be appended on to dest.
+  wchar_t dest[7] = {L'x', L'y', L'z', L'\0'};
+  const wchar_t *src = L"abc";
+  LIBC_NAMESPACE::wcscat(dest, src);
+  ASSERT_TRUE(dest[0] == L'x');
+  ASSERT_TRUE(dest[1] == L'y');
+  ASSERT_TRUE(dest[2] == L'z');
+  ASSERT_TRUE(dest[3] == L'a');
+  ASSERT_TRUE(dest[4] == L'b');
+  ASSERT_TRUE(dest[5] == L'c');
+  ASSERT_TRUE(dest[6] == L'\0');
+}
+
+TEST(LlvmLibcWCSCatTest, EmptySrc) {
+  // Dest should remain intact.
+  wchar_t dest[4] = {L'x', L'y', L'z', L'\0'};
+  const wchar_t *src = L"";
+  LIBC_NAMESPACE::wcscat(dest, src);
+  ASSERT_TRUE(dest[0] == L'x');
+  ASSERT_TRUE(dest[1] == L'y');
+  ASSERT_TRUE(dest[2] == L'z');
+  ASSERT_TRUE(dest[3] == L'\0');
+}
diff --git a/test/src/wchar/wcscmp_test.cpp b/test/src/wchar/wcscmp_test.cpp
new file mode 100644
index 0000000..6572aad
--- /dev/null
+++ b/test/src/wchar/wcscmp_test.cpp
@@ -0,0 +1,97 @@
+//===-- Unittests for wcscmp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wcscmp.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcWcscmpTest, EmptyStringsShouldReturnZero) {
+  const wchar_t *s1 = L"";
+  const wchar_t *s2 = L"";
+  int result = LIBC_NAMESPACE::wcscmp(s1, s2);
+  ASSERT_EQ(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcscmp(s2, s1);
+  ASSERT_EQ(result, 0);
+}
+
+TEST(LlvmLibcWcscmpTest, EmptyStringShouldNotEqualNonEmptyString) {
+  const wchar_t *empty = L"";
+  const wchar_t *s2 = L"abc";
+  int result = LIBC_NAMESPACE::wcscmp(empty, s2);
+  ASSERT_LT(result, 0);
+
+  // Similar case if empty string is second argument.
+  const wchar_t *s3 = L"123";
+  result = LIBC_NAMESPACE::wcscmp(s3, empty);
+  ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcWcscmpTest, EqualStringsShouldReturnZero) {
+  const wchar_t *s1 = L"abc";
+  const wchar_t *s2 = L"abc";
+  int result = LIBC_NAMESPACE::wcscmp(s1, s2);
+  ASSERT_EQ(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcscmp(s2, s1);
+  ASSERT_EQ(result, 0);
+}
+
+TEST(LlvmLibcWcscmpTest, ShouldReturnResultOfFirstDifference) {
+  const wchar_t *s1 = L"___B42__";
+  const wchar_t *s2 = L"___C55__";
+  int result = LIBC_NAMESPACE::wcscmp(s1, s2);
+  ASSERT_LT(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcscmp(s2, s1);
+  ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcWcscmpTest, CapitalizedLetterShouldNotBeEqual) {
+  const wchar_t *s1 = L"abcd";
+  const wchar_t *s2 = L"abCd";
+  int result = LIBC_NAMESPACE::wcscmp(s1, s2);
+  ASSERT_GT(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcscmp(s2, s1);
+  ASSERT_LT(result, 0);
+}
+
+TEST(LlvmLibcWcscmpTest, UnequalLengthStringsShouldNotReturnZero) {
+  const wchar_t *s1 = L"abc";
+  const wchar_t *s2 = L"abcd";
+  int result = LIBC_NAMESPACE::wcscmp(s1, s2);
+  ASSERT_LT(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcscmp(s2, s1);
+  ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcWcscmpTest, StringArgumentSwapChangesSign) {
+  const wchar_t *a = L"a";
+  const wchar_t *b = L"b";
+  int result = LIBC_NAMESPACE::wcscmp(b, a);
+  ASSERT_GT(result, 0);
+
+  result = LIBC_NAMESPACE::wcscmp(a, b);
+  ASSERT_LT(result, 0);
+}
+
+#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+TEST(LlvmLibcWcscmpTest, NullptrCrash) {
+  // Passing in a nullptr should crash the program.
+  EXPECT_DEATH([] { LIBC_NAMESPACE::wcscmp(L"aaaaaaaaaaaaaa", nullptr); },
+               WITH_SIGNAL(-1));
+  EXPECT_DEATH([] { LIBC_NAMESPACE::wcscmp(nullptr, L"aaaaaaaaaaaaaa"); },
+               WITH_SIGNAL(-1));
+}
+#endif // LIBC_HAS_ADDRESS_SANITIZER
diff --git a/test/src/wchar/wcscpy_test.cpp b/test/src/wchar/wcscpy_test.cpp
new file mode 100644
index 0000000..7b71b2b
--- /dev/null
+++ b/test/src/wchar/wcscpy_test.cpp
@@ -0,0 +1,48 @@
+//===-- Unittests for wcscpy ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/wchar_t.h"
+#include "src/wchar/wcscpy.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcWCSCpyTest, EmptySrc) {
+  // Empty src should lead to empty destination.
+  wchar_t dest[4] = {L'a', L'b', L'c', L'\0'};
+  const wchar_t *src = L"";
+  LIBC_NAMESPACE::wcscpy(dest, src);
+  ASSERT_TRUE(dest[0] == src[0]);
+  ASSERT_TRUE(dest[0] == L'\0');
+}
+
+TEST(LlvmLibcWCSCpyTest, EmptyDest) {
+  // Empty dest should result in src
+  const wchar_t *src = L"abc";
+  wchar_t dest[4];
+  LIBC_NAMESPACE::wcscpy(dest, src);
+  ASSERT_TRUE(dest[0] == L'a');
+  ASSERT_TRUE(dest[1] == L'b');
+  ASSERT_TRUE(dest[2] == L'c');
+  ASSERT_TRUE(dest[3] == L'\0');
+}
+
+TEST(LlvmLibcWCSCpyTest, OffsetDest) {
+  // Offsetting should result in a concatenation.
+  const wchar_t *src = L"abc";
+  wchar_t dest[7];
+  dest[0] = L'x';
+  dest[1] = L'y';
+  dest[2] = L'z';
+  LIBC_NAMESPACE::wcscpy(dest + 3, src);
+  ASSERT_TRUE(dest[0] == L'x');
+  ASSERT_TRUE(dest[1] == L'y');
+  ASSERT_TRUE(dest[2] == L'z');
+  ASSERT_TRUE(dest[3] == src[0]);
+  ASSERT_TRUE(dest[4] == src[1]);
+  ASSERT_TRUE(dest[5] == src[2]);
+  ASSERT_TRUE(dest[6] == src[3]);
+}
diff --git a/test/src/wchar/wcsncat_test.cpp b/test/src/wchar/wcsncat_test.cpp
new file mode 100644
index 0000000..47359f8
--- /dev/null
+++ b/test/src/wchar/wcsncat_test.cpp
@@ -0,0 +1,82 @@
+//===-- Unittests for wcscat ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/wchar_t.h"
+#include "src/wchar/wcsncat.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcWCSNCatTest, EmptyDest) {
+  wchar_t dest[4] = {L'\0'};
+  const wchar_t *src = L"abc";
+
+  // Start by copying nothing
+  LIBC_NAMESPACE::wcsncat(dest, src, 0);
+  ASSERT_TRUE(dest[0] == L'\0');
+
+  // Copying part of it.
+  LIBC_NAMESPACE::wcsncat(dest, src, 1);
+  ASSERT_TRUE(dest[0] == L'a');
+  ASSERT_TRUE(dest[1] == L'\0');
+
+  // Resetting for the last test.
+  dest[0] = '\0';
+
+  // Copying all of it.
+  LIBC_NAMESPACE::wcsncat(dest, src, 3);
+  ASSERT_TRUE(dest[0] == L'a');
+  ASSERT_TRUE(dest[1] == L'b');
+  ASSERT_TRUE(dest[2] == L'c');
+  ASSERT_TRUE(dest[3] == L'\0');
+}
+
+TEST(LlvmLibcWCSNCatTest, NonEmptyDest) {
+  wchar_t dest[7] = {L'x', L'y', L'z', L'\0'};
+  const wchar_t *src = L"abc";
+
+  // Adding on only part of the string
+  LIBC_NAMESPACE::wcsncat(dest, src, 1);
+  ASSERT_TRUE(dest[0] == L'x');
+  ASSERT_TRUE(dest[1] == L'y');
+  ASSERT_TRUE(dest[2] == L'z');
+  ASSERT_TRUE(dest[3] == L'a');
+  ASSERT_TRUE(dest[4] == L'\0');
+
+  // Copying more without resetting
+  LIBC_NAMESPACE::wcsncat(dest, src, 2);
+  ASSERT_TRUE(dest[0] == L'x');
+  ASSERT_TRUE(dest[1] == L'y');
+  ASSERT_TRUE(dest[2] == L'z');
+  ASSERT_TRUE(dest[3] == L'a');
+  ASSERT_TRUE(dest[4] == L'a');
+  ASSERT_TRUE(dest[5] == L'b');
+  ASSERT_TRUE(dest[6] == L'\0');
+
+  // Setting end marker to make sure it overwrites properly.
+  dest[3] = L'\0';
+
+  // Copying all of it.
+  LIBC_NAMESPACE::wcsncat(dest, src, 3);
+  ASSERT_TRUE(dest[0] == L'x');
+  ASSERT_TRUE(dest[1] == L'y');
+  ASSERT_TRUE(dest[2] == L'z');
+  ASSERT_TRUE(dest[3] == L'a');
+  ASSERT_TRUE(dest[4] == L'b');
+  ASSERT_TRUE(dest[5] == L'c');
+  ASSERT_TRUE(dest[6] == L'\0');
+
+  // Check that copying still works when count > src length.
+  dest[0] = L'\0';
+  // And that it doesn't write beyond what is necessary.
+  dest[4] = L'Z';
+  LIBC_NAMESPACE::wcsncat(dest, src, 4);
+  ASSERT_TRUE(dest[0] == L'a');
+  ASSERT_TRUE(dest[1] == L'b');
+  ASSERT_TRUE(dest[2] == L'c');
+  ASSERT_TRUE(dest[3] == L'\0');
+  ASSERT_TRUE(dest[4] == L'Z');
+}
diff --git a/test/src/wchar/wcsncmp_test.cpp b/test/src/wchar/wcsncmp_test.cpp
new file mode 100644
index 0000000..28bbb52
--- /dev/null
+++ b/test/src/wchar/wcsncmp_test.cpp
@@ -0,0 +1,169 @@
+//===-- Unittests for wcsncmp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wcsncmp.h"
+#include "test/UnitTest/Test.h"
+
+// This group is just copies of the wcscmp tests, since all the same cases still
+// need to be tested.
+
+TEST(LlvmLibcWcsncmpTest, EmptyStringsShouldReturnZeroWithSufficientLength) {
+  const wchar_t *s1 = L"";
+  const wchar_t *s2 = L"";
+  int result = LIBC_NAMESPACE::wcsncmp(s1, s2, 1);
+  ASSERT_EQ(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcsncmp(s2, s1, 1);
+  ASSERT_EQ(result, 0);
+}
+
+TEST(LlvmLibcWcsncmpTest,
+     EmptyStringShouldNotEqualNonEmptyStringWithSufficientLength) {
+  const wchar_t *empty = L"";
+  const wchar_t *s2 = L"abc";
+  int result = LIBC_NAMESPACE::wcsncmp(empty, s2, 3);
+  ASSERT_LT(result, 0);
+
+  // Similar case if empty string is second argument.
+  const wchar_t *s3 = L"123";
+  result = LIBC_NAMESPACE::wcsncmp(s3, empty, 3);
+  ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcWcsncmpTest, EqualStringsShouldReturnZeroWithSufficientLength) {
+  const wchar_t *s1 = L"abc";
+  const wchar_t *s2 = L"abc";
+  int result = LIBC_NAMESPACE::wcsncmp(s1, s2, 3);
+  ASSERT_EQ(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcsncmp(s2, s1, 3);
+  ASSERT_EQ(result, 0);
+}
+
+TEST(LlvmLibcWcsncmpTest,
+     ShouldReturnResultOfFirstDifferenceWithSufficientLength) {
+  const wchar_t *s1 = L"___B42__";
+  const wchar_t *s2 = L"___C55__";
+  int result = LIBC_NAMESPACE::wcsncmp(s1, s2, 8);
+  ASSERT_LT(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcsncmp(s2, s1, 8);
+  ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcWcsncmpTest,
+     CapitalizedLetterShouldNotBeEqualWithSufficientLength) {
+  const wchar_t *s1 = L"abcd";
+  const wchar_t *s2 = L"abCd";
+  int result = LIBC_NAMESPACE::wcsncmp(s1, s2, 4);
+  ASSERT_GT(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcsncmp(s2, s1, 4);
+  ASSERT_LT(result, 0);
+}
+
+TEST(LlvmLibcWcsncmpTest,
+     UnequalLengthStringsShouldNotReturnZeroWithSufficientLength) {
+  const wchar_t *s1 = L"abc";
+  const wchar_t *s2 = L"abcd";
+  int result = LIBC_NAMESPACE::wcsncmp(s1, s2, 4);
+  ASSERT_LT(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcsncmp(s2, s1, 4);
+  ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcWcsncmpTest, StringArgumentSwapChangesSignWithSufficientLength) {
+  const wchar_t *a = L"a";
+  const wchar_t *b = L"b";
+  int result = LIBC_NAMESPACE::wcsncmp(b, a, 1);
+  ASSERT_GT(result, 0);
+
+  result = LIBC_NAMESPACE::wcsncmp(a, b, 1);
+  ASSERT_LT(result, 0);
+}
+
+#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+TEST(LlvmLibcWcsncmpTest, NullptrCrash) {
+  // Passing in a nullptr should crash the program.
+  EXPECT_DEATH([] { LIBC_NAMESPACE::wcsncmp(L"aaaaaaaaaaaaaa", nullptr, 3); },
+               WITH_SIGNAL(-1));
+  EXPECT_DEATH([] { LIBC_NAMESPACE::wcsncmp(nullptr, L"aaaaaaaaaaaaaa", 3); },
+               WITH_SIGNAL(-1));
+}
+#endif // LIBC_HAS_ADDRESS_SANITIZER
+
+// This group is actually testing wcsncmp functionality
+
+TEST(LlvmLibcWcsncmpTest, NonEqualStringsEqualWithLengthZero) {
+  const wchar_t *s1 = L"abc";
+  const wchar_t *s2 = L"def";
+  int result = LIBC_NAMESPACE::wcsncmp(s1, s2, 0);
+  ASSERT_EQ(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcsncmp(s2, s1, 0);
+  ASSERT_EQ(result, 0);
+}
+
+TEST(LlvmLibcWcsncmpTest, NonEqualStringsNotEqualWithLengthOne) {
+  const wchar_t *s1 = L"abc";
+  const wchar_t *s2 = L"def";
+  int result = LIBC_NAMESPACE::wcsncmp(s1, s2, 1);
+  ASSERT_LT(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcsncmp(s2, s1, 1);
+  ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcWcsncmpTest, NonEqualStringsEqualWithShorterLength) {
+  const wchar_t *s1 = L"___B42__";
+  const wchar_t *s2 = L"___C55__";
+  int result = LIBC_NAMESPACE::wcsncmp(s1, s2, 3);
+  ASSERT_EQ(result, 0);
+
+  // This should return 'B' - 'C' = -1.
+  result = LIBC_NAMESPACE::wcsncmp(s1, s2, 4);
+  ASSERT_LT(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcsncmp(s2, s1, 3);
+  ASSERT_EQ(result, 0);
+
+  // This should return 'C' - 'B' = 1.
+  result = LIBC_NAMESPACE::wcsncmp(s2, s1, 4);
+  ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcWcsncmpTest, StringComparisonEndsOnNullByteEvenWithLongerLength) {
+  const wchar_t *s1 = L"abc\0def";
+  const wchar_t *s2 = L"abc\0abc";
+  int result = LIBC_NAMESPACE::wcsncmp(s1, s2, 7);
+  ASSERT_EQ(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcsncmp(s2, s1, 7);
+  ASSERT_EQ(result, 0);
+}
+
+TEST(LlvmLibcWcsncmpTest, Case) {
+  const wchar_t *s1 = L"aB";
+  const wchar_t *s2 = L"ab";
+  int result = LIBC_NAMESPACE::wcsncmp(s1, s2, 2);
+  ASSERT_LT(result, 0);
+
+  // Verify operands reversed.
+  result = LIBC_NAMESPACE::wcsncmp(s2, s1, 2);
+  ASSERT_GT(result, 0);
+}
diff --git a/test/src/wchar/wcspbrk_test.cpp b/test/src/wchar/wcspbrk_test.cpp
index f7754c0..bca9bff 100644
--- a/test/src/wchar/wcspbrk_test.cpp
+++ b/test/src/wchar/wcspbrk_test.cpp
@@ -60,3 +60,13 @@
   EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"34"), src + 2);
   EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"43"), src + 2);
 }
+
+#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+TEST(LlvmLibcWCSPBrkTest, NullptrCrash) {
+  // Passing in a nullptr should crash the program.
+  EXPECT_DEATH([] { LIBC_NAMESPACE::wcspbrk(L"aaaaaaaaaaaaaa", nullptr); },
+               WITH_SIGNAL(-1));
+  EXPECT_DEATH([] { LIBC_NAMESPACE::wcspbrk(nullptr, L"aaaaaaaaaaaaaa"); },
+               WITH_SIGNAL(-1));
+}
+#endif // LIBC_HAS_ADDRESS_SANITIZER
diff --git a/test/src/wchar/wcsrchr_test.cpp b/test/src/wchar/wcsrchr_test.cpp
new file mode 100644
index 0000000..707dfb6
--- /dev/null
+++ b/test/src/wchar/wcsrchr_test.cpp
@@ -0,0 +1,68 @@
+//===-- Unittests for wcsrchr ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/wchar_t.h"
+#include "src/wchar/wcsrchr.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcWCSRChrTest, FindsFirstCharacter) {
+  // Should return pointer to original string since 'a' is the first character.
+  const wchar_t *src = L"abcde";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsrchr(src, L'a'), src);
+}
+
+TEST(LlvmLibcWCSRChrTest, FindsMiddleCharacter) {
+  // Should return pointer to 'c'.
+  const wchar_t *src = L"abcde";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsrchr(src, L'c'), (src + 2));
+}
+
+TEST(LlvmLibcWCSRChrTest, FindsLastCharacterThatIsNotNullTerminator) {
+  // Should return pointer to 'e'.
+  const wchar_t *src = L"abcde";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsrchr(src, L'e'), (src + 4));
+}
+
+TEST(LlvmLibcWCSRChrTest, FindsNullTerminator) {
+  // Should return pointer to null terminator.
+  const wchar_t *src = L"abcde";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsrchr(src, L'\0'), (src + 5));
+}
+
+TEST(LlvmLibcWCSRChrTest, CharacterNotWithinStringShouldReturnNullptr) {
+  // Since 'z' is not within the string, should return nullptr.
+  const wchar_t *src = L"abcde";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsrchr(src, L'z'), nullptr);
+}
+
+TEST(LlvmLibcWCSRChrTest, ShouldFindLastOfDuplicates) {
+  // Should return pointer to the last '1'.
+  const wchar_t *src = L"abc1def1ghi";
+  ASSERT_EQ((int)(LIBC_NAMESPACE::wcsrchr(src, L'1') - src), 7);
+
+  // Should return pointer to the last 'X'
+  const wchar_t *dups = L"XXXXX";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsrchr(dups, L'X'), dups + 4);
+}
+
+TEST(LlvmLibcWCSRChrTest, EmptyStringShouldOnlyMatchNullTerminator) {
+  // Null terminator should match
+  const wchar_t *src = L"";
+  ASSERT_EQ(src, LIBC_NAMESPACE::wcsrchr(src, L'\0'));
+  // All other characters should not match
+  ASSERT_EQ(LIBC_NAMESPACE::wcsrchr(src, L'Z'), nullptr);
+  ASSERT_EQ(LIBC_NAMESPACE::wcsrchr(src, L'3'), nullptr);
+  ASSERT_EQ(LIBC_NAMESPACE::wcsrchr(src, L'*'), nullptr);
+}
+
+#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+TEST(LlvmLibcWCSRChrTest, NullptrCrash) {
+  // Passing in a nullptr should crash the program.
+  EXPECT_DEATH([] { LIBC_NAMESPACE::wcsrchr(nullptr, L'a'); }, WITH_SIGNAL(-1));
+}
+#endif // LIBC_HAS_ADDRESS_SANITIZER
diff --git a/test/src/wchar/wcsstr_test.cpp b/test/src/wchar/wcsstr_test.cpp
new file mode 100644
index 0000000..c1448bb
--- /dev/null
+++ b/test/src/wchar/wcsstr_test.cpp
@@ -0,0 +1,113 @@
+//===-- Unittests for wcsstr ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/wchar_t.h"
+#include "src/wchar/wcsstr.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcWCSStrTest, NeedleNotInHaystack) {
+  // Should return nullptr if string is not found.
+  const wchar_t *haystack = L"12345";
+  const wchar_t *needle = L"a";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, needle), nullptr);
+}
+
+TEST(LlvmLibcWCSStrTest, NeedleIsEmptyString) {
+  // Should return pointer to first character if needle is empty.
+  const wchar_t *haystack = L"12345";
+  const wchar_t *needle = L"";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, needle), haystack);
+}
+
+TEST(LlvmLibcWCSStrTest, HaystackIsEmptyString) {
+  // Should return nullptr since haystack is empty.
+  const wchar_t *needle = L"12345";
+  const wchar_t *haystack = L"";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, needle), nullptr);
+}
+
+TEST(LlvmLibcWCSStrTest, HaystackAndNeedleAreEmptyStrings) {
+  // Should point to haystack since needle is empty.
+  const wchar_t *needle = L"";
+  const wchar_t *haystack = L"";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, needle), haystack);
+}
+
+TEST(LlvmLibcWCSStrTest, HaystackAndNeedleAreSingleCharacters) {
+  const wchar_t *haystack = L"a";
+  // Should point to haystack.
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, L"a"), haystack);
+  // Should return nullptr.
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, L"b"), nullptr);
+}
+
+TEST(LlvmLibcWCSStrTest, NeedleEqualToHaystack) {
+  const wchar_t *haystack = L"12345";
+  // Should point to haystack.
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, L"12345"), haystack);
+}
+
+TEST(LlvmLibcWCSStrTest, NeedleLargerThanHaystack) {
+  const wchar_t *haystack = L"123";
+  // Should return nullptr.
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, L"12345"), nullptr);
+}
+
+TEST(LlvmLibcWCSStrTest, NeedleAtBeginning) {
+  const wchar_t *haystack = L"12345";
+  const wchar_t *needle = L"12";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, needle), haystack);
+}
+
+TEST(LlvmLibcWCSStrTest, NeedleInMiddle) {
+  const wchar_t *haystack = L"abcdefghi";
+  const wchar_t *needle = L"def";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, needle), haystack + 3);
+}
+
+TEST(LlvmLibcWCSStrTest, NeedleDirectlyBeforeNullTerminator) {
+  const wchar_t *haystack = L"abcdefghi";
+  const wchar_t *needle = L"ghi";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, needle), haystack + 6);
+}
+
+TEST(LlvmLibcWCSStrTest, NeedlePastNullTerminator) {
+  const wchar_t haystack[5] = {L'1', L'2', L'\0', L'3', L'4'};
+  // Shouldn't find anything after the null terminator.
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, /*needle=*/L"3"), nullptr);
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, /*needle=*/L"4"), nullptr);
+}
+
+TEST(LlvmLibcWCSStrTest, PartialNeedle) {
+  const wchar_t *haystack = L"la_ap_lap";
+  const wchar_t *needle = L"lap";
+  // Shouldn't find la or ap.
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, needle), haystack + 6);
+}
+
+TEST(LlvmLibcWCSStrTest, MisspelledNeedle) {
+  const wchar_t *haystack = L"atalloftwocities...wait, tale";
+  const wchar_t *needle = L"tale";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, needle), haystack + 25);
+}
+
+TEST(LlvmLibcWCSStrTest, AnagramNeedle) {
+  const wchar_t *haystack = L"dgo_ogd_god_odg_gdo_dog";
+  const wchar_t *needle = L"dog";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, needle), haystack + 20);
+}
+
+TEST(LlvmLibcWCSStrTest, MorphedNeedle) {
+  // Changes a single letter in the needle to mismatch with the haystack.
+  const wchar_t *haystack = L"once upon a time";
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, L"time"), haystack + 12);
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, L"lime"), nullptr);
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, L"tome"), nullptr);
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, L"tire"), nullptr);
+  ASSERT_EQ(LIBC_NAMESPACE::wcsstr(haystack, L"timo"), nullptr);
+}
diff --git a/test/src/wchar/wmempcpy_test.cpp b/test/src/wchar/wmempcpy_test.cpp
new file mode 100644
index 0000000..000e4b3
--- /dev/null
+++ b/test/src/wchar/wmempcpy_test.cpp
@@ -0,0 +1,50 @@
+//===-- Unittests for wmempcpy --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wmempcpy.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcWMempcpyTest, Simple) {
+  const wchar_t *src = L"12345";
+  wchar_t dest[10] = {};
+  void *result = LIBC_NAMESPACE::wmempcpy(dest, src, 6);
+  ASSERT_EQ(static_cast<wchar_t *>(result), dest + 6);
+
+  ASSERT_TRUE(dest[0] == src[0]);
+  ASSERT_TRUE(dest[1] == src[1]);
+  ASSERT_TRUE(dest[2] == src[2]);
+  ASSERT_TRUE(dest[3] == src[3]);
+  ASSERT_TRUE(dest[4] == src[4]);
+  ASSERT_TRUE(dest[5] == src[5]);
+}
+
+TEST(LlvmLibcWmempcpyTest, ZeroCount) {
+  const wchar_t *src = L"12345";
+  wchar_t dest[5] = {};
+  void *result = LIBC_NAMESPACE::wmempcpy(dest, src, 0);
+  ASSERT_EQ(static_cast<wchar_t *>(result), dest);
+
+  ASSERT_TRUE(dest[0] == 0);
+  ASSERT_TRUE(dest[1] == 0);
+  ASSERT_TRUE(dest[2] == 0);
+  ASSERT_TRUE(dest[3] == 0);
+  ASSERT_TRUE(dest[4] == 0);
+}
+
+TEST(LlvmLibcWMempcpyTest, BoundaryCheck) {
+  const wchar_t *src = L"12345";
+  wchar_t dest[4] = {};
+  void *result = LIBC_NAMESPACE::wmempcpy(dest + 1, src + 1, 2);
+
+  ASSERT_TRUE(dest[0] == 0);
+  ASSERT_TRUE(dest[1] == src[1]);
+  ASSERT_TRUE(dest[2] == src[2]);
+  ASSERT_TRUE(dest[3] == 0);
+
+  ASSERT_EQ(static_cast<wchar_t *>(result), dest + 3);
+}