[libc] Add implementations of div, ldiv, lldiv and imaxdiv.

Reviewed By: michaelrj

Differential Revision: https://reviews.llvm.org/D109952

GitOrigin-RevId: 74670e79b0a00224c04dfc6a446ea4439f4cfca4
diff --git a/config/linux/aarch64/entrypoints.txt b/config/linux/aarch64/entrypoints.txt
index 8dbbb64..20583ea 100644
--- a/config/linux/aarch64/entrypoints.txt
+++ b/config/linux/aarch64/entrypoints.txt
@@ -46,13 +46,20 @@
     libc.src.string.strtok_r
 
     # inttypes.h entrypoints
+    libc.src.inttypes.imaxdiv
     libc.src.inttypes.strtoimax
     libc.src.inttypes.strtoumax
 
     # stdlib.h entrypoints
+    libc.src.stdlib.abs
     libc.src.stdlib.atoi
     libc.src.stdlib.atol
     libc.src.stdlib.atoll
+    libc.src.stdlib.div
+    libc.src.stdlib.labs
+    libc.src.stdlib.ldiv
+    libc.src.stdlib.llabs
+    libc.src.stdlib.lldiv
     libc.src.stdlib.strtol
     libc.src.stdlib.strtoll
     libc.src.stdlib.strtoul
@@ -161,15 +168,6 @@
     libc.src.math.truncl
 )
 
-if(LLVM_LIBC_FULL_BUILD)
-  list(APPEND TARGET_LIBC_ENTRYPOINTS
-    # stdlib.h entrypoints
-    libc.src.stdlib.abs
-    libc.src.stdlib.labs
-    libc.src.stdlib.llabs
-  )
-endif()
-
 set(TARGET_LLVMLIBC_ENTRYPOINTS
   ${TARGET_LIBC_ENTRYPOINTS}
   ${TARGET_LIBM_ENTRYPOINTS}
diff --git a/config/linux/api.td b/config/linux/api.td
index ddcf901..757469b 100644
--- a/config/linux/api.td
+++ b/config/linux/api.td
@@ -111,6 +111,21 @@
 def CTypeAPI : PublicAPI<"ctype.h"> {
 }
 
+def IMaxDivT : TypeDecl<"imaxdiv_t"> {
+  let Decl = [{
+    typedef struct {
+      intmax_t quot;
+      intmax_t rem;
+    } imaxdiv_t;
+  }];
+}
+
+def IntTypesAPI : PublicAPI<"inttypes.h"> {
+  let TypeDeclarations = [
+    IMaxDivT,
+  ];
+}
+
 def MathErrHandlingMacro : MacroDef<"math_errhandling"> {
   let Defn = [{
     #ifndef math_errhandling
@@ -239,7 +254,39 @@
   ];
 }
 
+def DivT : TypeDecl<"div_t"> {
+  let Decl = [{
+    typedef struct {
+      int quot;
+      int rem;
+    } div_t;
+  }];
+}
+
+def LDivT : TypeDecl<"ldiv_t"> {
+  let Decl = [{
+    typedef struct {
+      long quot;
+      long rem;
+    } ldiv_t;
+  }];
+}
+
+def LLDivT : TypeDecl<"lldiv_t"> {
+  let Decl = [{
+    typedef struct {
+      long long quot;
+      long long rem;
+    } lldiv_t;
+  }];
+}
+
 def StdlibAPI : PublicAPI<"stdlib.h"> {
+  let TypeDeclarations = [
+    DivT,
+    LDivT,
+    LLDivT,
+  ];
 }
 
 def TimeAPI : PublicAPI<"time.h"> {
diff --git a/config/linux/x86_64/entrypoints.txt b/config/linux/x86_64/entrypoints.txt
index 9836d62..503bd9a 100644
--- a/config/linux/x86_64/entrypoints.txt
+++ b/config/linux/x86_64/entrypoints.txt
@@ -46,13 +46,20 @@
     libc.src.string.strtok_r
 
     # inttypes.h entrypoints
+    libc.src.inttypes.imaxdiv
     libc.src.inttypes.strtoimax
     libc.src.inttypes.strtoumax
 
     # stdlib.h entrypoints
+    libc.src.stdlib.abs
     libc.src.stdlib.atoi
     libc.src.stdlib.atol
     libc.src.stdlib.atoll
+    libc.src.stdlib.div
+    libc.src.stdlib.labs
+    libc.src.stdlib.ldiv
+    libc.src.stdlib.llabs
+    libc.src.stdlib.lldiv
     libc.src.stdlib.strtol
     libc.src.stdlib.strtoll
     libc.src.stdlib.strtoul
@@ -172,9 +179,6 @@
     # stdlib.h entrypoints
     libc.src.stdlib._Exit
     libc.src.stdlib.abort
-    libc.src.stdlib.abs
-    libc.src.stdlib.labs
-    libc.src.stdlib.llabs
 
     # signal.h entrypoints
     libc.src.signal.raise
diff --git a/spec/stdc.td b/spec/stdc.td
index c50f917..46f56a4 100644
--- a/spec/stdc.td
+++ b/spec/stdc.td
@@ -7,6 +7,10 @@
   PtrType StructTmPtr = PtrType<StructTmType>;
   PtrType TimeTTypePtr = PtrType<TimeTType>;
 
+  NamedType DivTType = NamedType<"div_t">;
+  NamedType LDivTType = NamedType<"ldiv_t">;
+  NamedType LLDivTType = NamedType<"lldiv_t">;
+
   HeaderSpec Assert = HeaderSpec<
       "assert.h",
       [
@@ -471,32 +475,48 @@
   HeaderSpec StdLib = HeaderSpec<
       "stdlib.h",
       [], // Macros
-      [], // Types
+      [
+          DivTType,
+          LDivTType,
+          LLDivTType,
+      ], // Types
       [], // Enumerations
       [
           FunctionSpec<"abort", RetValSpec<NoReturn>, [ArgSpec<VoidType>]>,
+
           FunctionSpec<"abs", RetValSpec<IntType>, [ArgSpec<IntType>]>,
+          FunctionSpec<"labs", RetValSpec<LongType>, [ArgSpec<LongType>]>,
+          FunctionSpec<"llabs", RetValSpec<LongLongType>, [ArgSpec<LongLongType>]>,
+
           FunctionSpec<"atoi", RetValSpec<IntType>, [ArgSpec<ConstCharPtr>]>,
           FunctionSpec<"atol", RetValSpec<LongType>, [ArgSpec<ConstCharPtr>]>,
           FunctionSpec<"atoll", RetValSpec<LongLongType>, [ArgSpec<ConstCharPtr>]>,
-          FunctionSpec<"labs", RetValSpec<LongType>, [ArgSpec<LongType>]>,
-          FunctionSpec<"llabs", RetValSpec<LongLongType>, [ArgSpec<LongLongType>]>,
+
+          FunctionSpec<"div", RetValSpec<DivTType>, [ArgSpec<IntType>, ArgSpec<IntType>]>,
+          FunctionSpec<"ldiv", RetValSpec<LDivTType>, [ArgSpec<LongType>, ArgSpec<LongType>]>,
+          FunctionSpec<"lldiv", RetValSpec<LLDivTType>, [ArgSpec<LongLongType>, ArgSpec<LongLongType>]>,
+
           FunctionSpec<"strtol", RetValSpec<LongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
           FunctionSpec<"strtoll", RetValSpec<LongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
           FunctionSpec<"strtoul", RetValSpec<UnsignedLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
           FunctionSpec<"strtoull", RetValSpec<UnsignedLongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
+
           FunctionSpec<"_Exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
       ]
   >;
 
+  NamedType IMaxDivTType = NamedType<"imaxdiv_t">;
+
   HeaderSpec IntTypes = HeaderSpec<
       "inttypes.h",
       [], // Macros
-      [], // Types
+      [
+        IMaxDivTType,
+      ], // Types
       [], // Enumerations
       [
           FunctionSpec<"imaxabs", RetValSpec<IntMaxTType>, [ArgSpec<IntMaxTType>]>,
-          FunctionSpec<"imaxdiv", RetValSpec<IntMaxTType>, [ArgSpec<IntMaxTType>, ArgSpec<IntMaxTType>]>,
+          FunctionSpec<"imaxdiv", RetValSpec<IMaxDivTType>, [ArgSpec<IntMaxTType>, ArgSpec<IntMaxTType>]>,
           FunctionSpec<"strtoimax", RetValSpec<IntMaxTType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
           FunctionSpec<"strtoumax", RetValSpec<UIntMaxTType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
       ]
diff --git a/src/__support/integer_operations.h b/src/__support/integer_operations.h
index 4c13bb8..c27a263 100644
--- a/src/__support/integer_operations.h
+++ b/src/__support/integer_operations.h
@@ -19,6 +19,13 @@
   return (n < 0) ? -n : n;
 }
 
+template <typename T>
+static constexpr cpp::EnableIfType<cpp::IsIntegral<T>::Value, void>
+integerRemQuo(T x, T y, T &quot, T &rem) {
+  quot = x / y;
+  rem = x % y;
+}
+
 } // namespace __llvm_libc
 
 #endif // LLVM_LIBC_SRC_STDLIB_ABS_UTILS_H
diff --git a/src/inttypes/CMakeLists.txt b/src/inttypes/CMakeLists.txt
index 65c1d7e..81068bd 100644
--- a/src/inttypes/CMakeLists.txt
+++ b/src/inttypes/CMakeLists.txt
@@ -17,3 +17,13 @@
   DEPENDS
     libc.src.__support.str_conv_utils
 )
+
+add_entrypoint_object(
+  imaxdiv
+  SRCS
+    imaxdiv.cpp
+  HDRS
+    imaxdiv.h
+  DEPENDS
+    libc.src.__support.integer_operations
+)
diff --git a/src/inttypes/imaxdiv.cpp b/src/inttypes/imaxdiv.cpp
new file mode 100644
index 0000000..6189fc1
--- /dev/null
+++ b/src/inttypes/imaxdiv.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of imaxdiv -----------------------------------------===//
+//
+// 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/inttypes/imaxdiv.h"
+#include "src/__support/common.h"
+#include "src/__support/integer_operations.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(imaxdiv_t, imaxdiv, (intmax_t x, intmax_t y)) {
+  imaxdiv_t res;
+  integerRemQuo(x, y, res.quot, res.rem);
+  return res;
+}
+
+} // namespace __llvm_libc
diff --git a/src/inttypes/imaxdiv.h b/src/inttypes/imaxdiv.h
new file mode 100644
index 0000000..c8af352
--- /dev/null
+++ b/src/inttypes/imaxdiv.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for imaxdiv -----------------------*- 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_INTTYPES_IMAXDIV_H
+#define LLVM_LIBC_SRC_INTTYPES_IMAXDIV_H
+
+#include <inttypes.h>
+
+namespace __llvm_libc {
+
+imaxdiv_t imaxdiv(intmax_t x, intmax_t y);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_INTTYPES_IMAXDIV_H
diff --git a/src/stdlib/CMakeLists.txt b/src/stdlib/CMakeLists.txt
index bf1b637..4f67612 100644
--- a/src/stdlib/CMakeLists.txt
+++ b/src/stdlib/CMakeLists.txt
@@ -124,3 +124,33 @@
   DEPENDS
     libc.src.__support.integer_operations
 )
+
+add_entrypoint_object(
+  div
+  SRCS
+    div.cpp
+  HDRS
+    div.h
+  DEPENDS
+    libc.src.__support.integer_operations
+)
+
+add_entrypoint_object(
+  ldiv
+  SRCS
+    ldiv.cpp
+  HDRS
+    ldiv.h
+  DEPENDS
+    libc.src.__support.integer_operations
+)
+
+add_entrypoint_object(
+  lldiv
+  SRCS
+    lldiv.cpp
+  HDRS
+    lldiv.h
+  DEPENDS
+    libc.src.__support.integer_operations
+)
diff --git a/src/stdlib/div.cpp b/src/stdlib/div.cpp
new file mode 100644
index 0000000..042346d
--- /dev/null
+++ b/src/stdlib/div.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of div ---------------------------------------------===//
+//
+// 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/stdlib/div.h"
+#include "src/__support/common.h"
+#include "src/__support/integer_operations.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(div_t, div, (int x, int y)) {
+  div_t res;
+  integerRemQuo(x, y, res.quot, res.rem);
+  return res;
+}
+
+} // namespace __llvm_libc
diff --git a/src/stdlib/div.h b/src/stdlib/div.h
new file mode 100644
index 0000000..ec1ded7
--- /dev/null
+++ b/src/stdlib/div.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for div ---------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+#ifndef LLVM_LIBC_SRC_STDLIB_DIV_H
+#define LLVM_LIBC_SRC_STDLIB_DIV_H
+
+namespace __llvm_libc {
+
+div_t div(int x, int y);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDLIB_DIV_H
diff --git a/src/stdlib/ldiv.cpp b/src/stdlib/ldiv.cpp
new file mode 100644
index 0000000..fdac260
--- /dev/null
+++ b/src/stdlib/ldiv.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of ldiv --------------------------------------------===//
+//
+// 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/stdlib/ldiv.h"
+#include "src/__support/common.h"
+#include "src/__support/integer_operations.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(ldiv_t, ldiv, (long x, long y)) {
+  ldiv_t res;
+  integerRemQuo(x, y, res.quot, res.rem);
+  return res;
+}
+
+} // namespace __llvm_libc
diff --git a/src/stdlib/ldiv.h b/src/stdlib/ldiv.h
new file mode 100644
index 0000000..f4e7730
--- /dev/null
+++ b/src/stdlib/ldiv.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for ldiv --------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+#ifndef LLVM_LIBC_SRC_STDLIB_LDIV_H
+#define LLVM_LIBC_SRC_STDLIB_LDIV_H
+
+namespace __llvm_libc {
+
+ldiv_t ldiv(long x, long y);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDLIB_LDIV_H
diff --git a/src/stdlib/lldiv.cpp b/src/stdlib/lldiv.cpp
new file mode 100644
index 0000000..958b01f
--- /dev/null
+++ b/src/stdlib/lldiv.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of lldiv -------------------------------------------===//
+//
+// 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/stdlib/lldiv.h"
+#include "src/__support/common.h"
+#include "src/__support/integer_operations.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(lldiv_t, lldiv, (long long x, long long y)) {
+  lldiv_t res;
+  integerRemQuo(x, y, res.quot, res.rem);
+  return res;
+}
+
+} // namespace __llvm_libc
diff --git a/src/stdlib/lldiv.h b/src/stdlib/lldiv.h
new file mode 100644
index 0000000..7f0de5c
--- /dev/null
+++ b/src/stdlib/lldiv.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for lldiv -------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+#ifndef LLVM_LIBC_SRC_STDLIB_LLDIV_H
+#define LLVM_LIBC_SRC_STDLIB_LLDIV_H
+
+namespace __llvm_libc {
+
+lldiv_t lldiv(long long x, long long y);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDLIB_LDIV_H
diff --git a/test/src/inttypes/CMakeLists.txt b/test/src/inttypes/CMakeLists.txt
index d9885ba..9a6d6ac 100644
--- a/test/src/inttypes/CMakeLists.txt
+++ b/test/src/inttypes/CMakeLists.txt
@@ -19,3 +19,16 @@
   DEPENDS
     libc.src.inttypes.strtoumax
 )
+
+add_libc_unittest(
+  imaxdiv_test
+  SUITE
+    libc_inttypes_unittests
+  SRCS
+    imaxdiv_test.cpp
+  HDRS
+    ../stdlib/DivTest.h
+  DEPENDS
+    libc.include.stdlib
+    libc.src.inttypes.imaxdiv
+)
diff --git a/test/src/inttypes/imaxdiv_test.cpp b/test/src/inttypes/imaxdiv_test.cpp
new file mode 100644
index 0000000..321aad5
--- /dev/null
+++ b/test/src/inttypes/imaxdiv_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for imaxdiv ---------------------------------------------===//
+//
+// 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 "../stdlib/DivTest.h"
+
+#include "src/inttypes/imaxdiv.h"
+
+#include <inttypes.h>
+
+LIST_DIV_TESTS(intmax_t, imaxdiv_t, __llvm_libc::imaxdiv)
diff --git a/test/src/stdlib/CMakeLists.txt b/test/src/stdlib/CMakeLists.txt
index 6aed171..4eb8526 100644
--- a/test/src/stdlib/CMakeLists.txt
+++ b/test/src/stdlib/CMakeLists.txt
@@ -128,3 +128,42 @@
   DEPENDS
     libc.src.stdlib.llabs
 )
+
+add_libc_unittest(
+  div_test
+  SUITE
+    libc_stdlib_unittests
+  SRCS
+    div_test.cpp
+  HDRS
+    DivTest.h
+  DEPENDS
+    libc.include.stdlib
+    libc.src.stdlib.div
+)
+
+add_libc_unittest(
+  ldiv_test
+  SUITE
+    libc_stdlib_unittests
+  SRCS
+    ldiv_test.cpp
+  HDRS
+    DivTest.h
+  DEPENDS
+    libc.include.stdlib
+    libc.src.stdlib.ldiv
+)
+
+add_libc_unittest(
+  lldiv_test
+  SUITE
+    libc_stdlib_unittests
+  SRCS
+    lldiv_test.cpp
+  HDRS
+    DivTest.h
+  DEPENDS
+    libc.include.stdlib
+    libc.src.stdlib.lldiv
+)
diff --git a/test/src/stdlib/DivTest.h b/test/src/stdlib/DivTest.h
new file mode 100644
index 0000000..13978ac
--- /dev/null
+++ b/test/src/stdlib/DivTest.h
@@ -0,0 +1,37 @@
+//===-- A template class for testing div functions --------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "utils/UnitTest/Test.h"
+
+template <typename IntType, typename ReturnType>
+class DivTest : public __llvm_libc::testing::Test {
+public:
+  using DivFunc = ReturnType(IntType, IntType);
+
+  void simpleTest(DivFunc func) {
+    auto result = func(10, 3);
+    EXPECT_EQ(result.quot, IntType(3));
+    EXPECT_EQ(result.rem, IntType(1));
+
+    result = func(-10, 3);
+    EXPECT_EQ(result.quot, IntType(-3));
+    EXPECT_EQ(result.rem, IntType(-1));
+
+    result = func(-10, -3);
+    EXPECT_EQ(result.quot, IntType(3));
+    EXPECT_EQ(result.rem, IntType(-1));
+
+    result = func(10, -3);
+    EXPECT_EQ(result.quot, IntType(-3));
+    EXPECT_EQ(result.rem, IntType(1));
+  }
+};
+
+#define LIST_DIV_TESTS(IntType, ReturnType, func)                              \
+  using LlvmLibcDivTest = DivTest<IntType, ReturnType>;                        \
+  TEST_F(LlvmLibcDivTest, SimpleTest) { simpleTest(func); }
diff --git a/test/src/stdlib/div_test.cpp b/test/src/stdlib/div_test.cpp
new file mode 100644
index 0000000..6b1f20d
--- /dev/null
+++ b/test/src/stdlib/div_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for div -------------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/stdlib/div.h"
+
+#include <stdlib.h>
+
+LIST_DIV_TESTS(int, div_t, __llvm_libc::div)
diff --git a/test/src/stdlib/ldiv_test.cpp b/test/src/stdlib/ldiv_test.cpp
new file mode 100644
index 0000000..d28d387
--- /dev/null
+++ b/test/src/stdlib/ldiv_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for ldiv ------------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/stdlib/ldiv.h"
+
+#include <stdlib.h>
+
+LIST_DIV_TESTS(long, ldiv_t, __llvm_libc::ldiv)
diff --git a/test/src/stdlib/lldiv_test.cpp b/test/src/stdlib/lldiv_test.cpp
new file mode 100644
index 0000000..5fa0de2
--- /dev/null
+++ b/test/src/stdlib/lldiv_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for lldiv -----------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/stdlib/lldiv.h"
+
+#include <stdlib.h>
+
+LIST_DIV_TESTS(long long, lldiv_t, __llvm_libc::lldiv)