[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 ", 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)