[Openmp-commits] [openmp] [OpenMP] Add libomp unit test infrastructure (PR #168063)

Robert Imschweiler via Openmp-commits openmp-commits at lists.llvm.org
Mon Nov 17 02:25:42 PST 2025


https://github.com/ro-i updated https://github.com/llvm/llvm-project/pull/168063

>From c801cb4d20ffc2d7af175ee1030b72cb0430bfad Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Fri, 14 Nov 2025 07:54:28 -0600
Subject: [PATCH 1/2] [OpenMP] Add libomp unit test infrastructure

---
 openmp/runtime/CMakeLists.txt               |   1 +
 openmp/runtime/src/CMakeLists.txt           |  13 +-
 openmp/runtime/unittests/CMakeLists.txt     |  39 ++++
 openmp/runtime/unittests/README.md          |   7 +
 openmp/runtime/unittests/lit.cfg.py         |  22 ++
 openmp/runtime/unittests/lit.site.cfg.py.in |   9 +
 openmp/runtime/unittests/src/CMakeLists.txt |   3 +
 openmp/runtime/unittests/src/TestKmpStr.cpp | 239 ++++++++++++++++++++
 8 files changed, 331 insertions(+), 2 deletions(-)
 create mode 100644 openmp/runtime/unittests/CMakeLists.txt
 create mode 100644 openmp/runtime/unittests/README.md
 create mode 100644 openmp/runtime/unittests/lit.cfg.py
 create mode 100644 openmp/runtime/unittests/lit.site.cfg.py.in
 create mode 100644 openmp/runtime/unittests/src/CMakeLists.txt
 create mode 100644 openmp/runtime/unittests/src/TestKmpStr.cpp

diff --git a/openmp/runtime/CMakeLists.txt b/openmp/runtime/CMakeLists.txt
index 93eb14f10a50a..4597a03b0a255 100644
--- a/openmp/runtime/CMakeLists.txt
+++ b/openmp/runtime/CMakeLists.txt
@@ -469,6 +469,7 @@ endif()
 
 add_subdirectory(src)
 add_subdirectory(test)
+add_subdirectory(unittests)
 
 # make these variables available for tools:
 set(LIBOMP_LIBRARY_DIR ${LIBOMP_LIBRARY_DIR} PARENT_SCOPE)
diff --git a/openmp/runtime/src/CMakeLists.txt b/openmp/runtime/src/CMakeLists.txt
index 5dd7f4b33612d..44ddefcefa82f 100644
--- a/openmp/runtime/src/CMakeLists.txt
+++ b/openmp/runtime/src/CMakeLists.txt
@@ -174,17 +174,26 @@ if(NOT WIN32)
 endif()
 
 # Add the OpenMP library
+
+# First, create an OBJECT library with all the runtime sources.
+# This allows both the main library and unit tests to link against the same compiled objects.
+add_library(omp_objects OBJECT ${LIBOMP_SOURCE_FILES})
+set_property(TARGET omp_objects PROPERTY FOLDER "OpenMP/Libraries")
+set_property(TARGET omp_objects PROPERTY POSITION_INDEPENDENT_CODE ON)
+# Export the omp_objects target so unittests can use it
+set(LIBOMP_OBJECTS_TARGET omp_objects PARENT_SCOPE)
+
 libomp_get_ldflags(LIBOMP_CONFIGURED_LDFLAGS)
 
 libomp_get_libflags(LIBOMP_CONFIGURED_LIBFLAGS)
 # Build libomp library. Add LLVMSupport dependency if building in-tree with libomptarget profiling enabled.
 if(OPENMP_STANDALONE_BUILD OR (NOT OPENMP_ENABLE_LIBOMP_PROFILING))
-  add_library(omp ${LIBOMP_LIBRARY_KIND} ${LIBOMP_SOURCE_FILES})
+  add_library(omp ${LIBOMP_LIBRARY_KIND} $<TARGET_OBJECTS:omp_objects>)
   set_property(TARGET omp PROPERTY FOLDER "OpenMP/Libraries")
   # Linking command will include libraries in LIBOMP_CONFIGURED_LIBFLAGS
   target_link_libraries(omp ${LIBOMP_CONFIGURED_LIBFLAGS} ${LIBOMP_DL_LIBS})
 else()
-  add_llvm_library(omp ${LIBOMP_LIBRARY_KIND} ${LIBOMP_SOURCE_FILES} PARTIAL_SOURCES_INTENDED
+  add_llvm_library(omp ${LIBOMP_LIBRARY_KIND} $<TARGET_OBJECTS:omp_objects> PARTIAL_SOURCES_INTENDED
     LINK_LIBS ${LIBOMP_CONFIGURED_LIBFLAGS} ${LIBOMP_DL_LIBS}
     LINK_COMPONENTS Support
     BUILDTREE_ONLY
diff --git a/openmp/runtime/unittests/CMakeLists.txt b/openmp/runtime/unittests/CMakeLists.txt
new file mode 100644
index 0000000000000..14ddbfc827cbb
--- /dev/null
+++ b/openmp/runtime/unittests/CMakeLists.txt
@@ -0,0 +1,39 @@
+add_custom_target(OpenMPUnitTests)
+set_target_properties(OpenMPUnitTests PROPERTIES FOLDER "OpenMP/Tests")
+
+if (NOT TARGET llvm_gtest)
+  message(WARNING "OpenMP unittests disabled due to GTest being unavailable; "
+                  "Try LLVM_INSTALL_GTEST=ON for the LLVM build")
+  return ()
+endif ()
+
+function(add_openmp_unittest test_dirname)
+  add_unittest(OpenMPUnitTests ${test_dirname} ${ARGN})
+
+  # Link against the object library created in runtime/src
+  target_link_libraries(${test_dirname} PRIVATE
+    $<TARGET_OBJECTS:omp_objects>
+  )
+
+  target_include_directories(${test_dirname} PRIVATE
+    ${LIBOMP_INCLUDE_DIR}
+    ${LIBOMP_SRC_DIR}
+  )
+endfunction()
+
+configure_lit_site_cfg(
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
+  MAIN_CONFIG
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
+)
+
+add_openmp_testsuite(
+  check-libomp-unit
+  "Running libomp unit tests"
+  ${CMAKE_CURRENT_BINARY_DIR}
+  EXCLUDE_FROM_CHECK_ALL
+  DEPENDS OpenMPUnitTests omp
+)
+
+add_subdirectory(src)
diff --git a/openmp/runtime/unittests/README.md b/openmp/runtime/unittests/README.md
new file mode 100644
index 0000000000000..ad7dd9d716ceb
--- /dev/null
+++ b/openmp/runtime/unittests/README.md
@@ -0,0 +1,7 @@
+# libomp Unit Tests
+
+Usage:
+```
+cd <your-llvm-build-directory>/runtimes/runtimes-bins
+ninja check-libomp-unit
+```
\ No newline at end of file
diff --git a/openmp/runtime/unittests/lit.cfg.py b/openmp/runtime/unittests/lit.cfg.py
new file mode 100644
index 0000000000000..552ea8ef9854d
--- /dev/null
+++ b/openmp/runtime/unittests/lit.cfg.py
@@ -0,0 +1,22 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+import os
+import subprocess
+
+import lit.formats
+
+# name: The name of this test suite.
+config.name = "OpenMP-Unit"
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = []
+
+# test_source_root: The root path where tests are located.
+# test_exec_root: The root path where tests should be run.
+config.test_exec_root = config.openmp_unittests_dir
+config.test_source_root = config.test_exec_root
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, ".unittests")
diff --git a/openmp/runtime/unittests/lit.site.cfg.py.in b/openmp/runtime/unittests/lit.site.cfg.py.in
new file mode 100644
index 0000000000000..878c95f1d8e29
--- /dev/null
+++ b/openmp/runtime/unittests/lit.site.cfg.py.in
@@ -0,0 +1,9 @@
+ at AUTO_GEN_COMMENT@
+
+config.library_dir = "@LIBOMP_LIBRARY_DIR@"
+config.openmp_unittests_dir = "@CMAKE_CURRENT_BINARY_DIR@"
+config.llvm_build_mode = lit_config.substitute("@LLVM_BUILD_MODE@")
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg.py")
+
diff --git a/openmp/runtime/unittests/src/CMakeLists.txt b/openmp/runtime/unittests/src/CMakeLists.txt
new file mode 100644
index 0000000000000..455fbf0b92fc5
--- /dev/null
+++ b/openmp/runtime/unittests/src/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_openmp_unittest(libomp.unittests
+  TestKmpStr.cpp
+)
diff --git a/openmp/runtime/unittests/src/TestKmpStr.cpp b/openmp/runtime/unittests/src/TestKmpStr.cpp
new file mode 100644
index 0000000000000..a22a729da9272
--- /dev/null
+++ b/openmp/runtime/unittests/src/TestKmpStr.cpp
@@ -0,0 +1,239 @@
+//===- TestKmpStr.cpp - Tests for kmp_str utilities ----------------------===//
+//
+// 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 "kmp_str.h"
+#include "gtest/gtest.h"
+#include <cstring>
+
+namespace {
+
+// Test basic string buffer initialization
+TEST(KmpStrTest, BufferInit) {
+  kmp_str_buf_t buffer;
+  __kmp_str_buf_init(&buffer);
+
+  EXPECT_NE(buffer.str, nullptr);
+  EXPECT_GT(buffer.size, 0u);
+  EXPECT_EQ(buffer.used, 0);
+  EXPECT_EQ(buffer.str[0], '\0');
+}
+
+// Test string buffer clear
+TEST(KmpStrTest, BufferClear) {
+  kmp_str_buf_t buffer;
+  __kmp_str_buf_init(&buffer);
+  __kmp_str_buf_print(&buffer, "test string");
+
+  EXPECT_GT(buffer.used, 0);
+
+  __kmp_str_buf_clear(&buffer);
+  EXPECT_EQ(buffer.used, 0);
+  EXPECT_EQ(buffer.str[0], '\0');
+
+  __kmp_str_buf_free(&buffer);
+}
+
+// Test string buffer print
+TEST(KmpStrTest, BufferPrint) {
+  kmp_str_buf_t buffer;
+  __kmp_str_buf_init(&buffer);
+
+  __kmp_str_buf_print(&buffer, "Hello, %s!", "World");
+
+  EXPECT_STREQ(buffer.str, "Hello, World!");
+  EXPECT_EQ(buffer.used, 13);
+
+  __kmp_str_buf_free(&buffer);
+}
+
+// Test string buffer concatenation
+TEST(KmpStrTest, BufferCat) {
+  kmp_str_buf_t buffer;
+  __kmp_str_buf_init(&buffer);
+
+  __kmp_str_buf_cat(&buffer, "Hello", 5);
+  __kmp_str_buf_cat(&buffer, " ", 1);
+  __kmp_str_buf_cat(&buffer, "World", 5);
+
+  EXPECT_STREQ(buffer.str, "Hello World");
+
+  __kmp_str_buf_free(&buffer);
+}
+
+// Test string buffer reservation
+TEST(KmpStrTest, BufferReserve) {
+  kmp_str_buf_t buffer;
+  __kmp_str_buf_init(&buffer);
+
+  size_t large_size = 2048;
+  __kmp_str_buf_reserve(&buffer, large_size);
+
+  EXPECT_GE(buffer.size, large_size);
+
+  __kmp_str_buf_free(&buffer);
+}
+
+// Test basic string to int conversion
+TEST(KmpStrTest, BasicStrToInt) {
+  EXPECT_EQ(__kmp_basic_str_to_int("0"), 0);
+  EXPECT_EQ(__kmp_basic_str_to_int("1"), 1);
+  EXPECT_EQ(__kmp_basic_str_to_int("42"), 42);
+  EXPECT_EQ(__kmp_basic_str_to_int("123"), 123);
+}
+
+// Test string match
+TEST(KmpStrTest, StrMatch) {
+  const char *data = "Hello World";
+
+  // Test exact match (len == 0)
+  EXPECT_TRUE(__kmp_str_match("Hello World", 0, data));
+  EXPECT_FALSE(__kmp_str_match("Hello", 0, data)); // Not exact (data is longer)
+
+  // Test prefix match (len < 0)
+  EXPECT_TRUE(
+      __kmp_str_match("Hello", -1, data)); // "Hello" is prefix of "Hello World"
+  EXPECT_FALSE(__kmp_str_match("World", -1, data)); // "World" is not a prefix
+
+  // Test minimum length match (len > 0)
+  EXPECT_TRUE(__kmp_str_match("Hello", 5, data)); // At least 5 chars match
+  EXPECT_TRUE(__kmp_str_match("Hello", 3, data)); // At least 3 chars match
+  EXPECT_FALSE(__kmp_str_match("World", 5, data)); // First chars don't match
+}
+
+// Test string contains
+TEST(KmpStrTest, StrContains) {
+  const char *data = "Hello World";
+
+  EXPECT_TRUE(__kmp_str_contains("Hello", 5, data));
+  EXPECT_TRUE(__kmp_str_contains("World", 5, data));
+  EXPECT_TRUE(__kmp_str_contains("lo Wo", 5, data));
+  EXPECT_FALSE(__kmp_str_contains("Goodbye", 7, data));
+}
+
+// Test string match for true/false values
+TEST(KmpStrTest, MatchBool) {
+  // Test true values
+  EXPECT_TRUE(__kmp_str_match_true("true"));
+  EXPECT_TRUE(__kmp_str_match_true("TRUE"));
+  EXPECT_TRUE(__kmp_str_match_true("on"));
+  EXPECT_TRUE(__kmp_str_match_true("ON"));
+  EXPECT_TRUE(__kmp_str_match_true("1"));
+  EXPECT_TRUE(__kmp_str_match_true("yes"));
+  EXPECT_TRUE(__kmp_str_match_true("YES"));
+
+  // Test false values
+  EXPECT_TRUE(__kmp_str_match_false("false"));
+  EXPECT_TRUE(__kmp_str_match_false("FALSE"));
+  EXPECT_TRUE(__kmp_str_match_false("off"));
+  EXPECT_TRUE(__kmp_str_match_false("OFF"));
+  EXPECT_TRUE(__kmp_str_match_false("0"));
+  EXPECT_TRUE(__kmp_str_match_false("no"));
+  EXPECT_TRUE(__kmp_str_match_false("NO"));
+}
+
+// Test string replace
+TEST(KmpStrTest, StrReplace) {
+  char str[] = "Hello World";
+  __kmp_str_replace(str, ' ', '_');
+  EXPECT_STREQ(str, "Hello_World");
+
+  __kmp_str_replace(str, 'o', '0');
+  EXPECT_STREQ(str, "Hell0_W0rld");
+}
+
+// Test string split
+TEST(KmpStrTest, StrSplit) {
+  char str[] = "key=value";
+  char *head = nullptr;
+  char *tail = nullptr;
+
+  __kmp_str_split(str, '=', &head, &tail);
+
+  EXPECT_STREQ(head, "key");
+  EXPECT_STREQ(tail, "value");
+}
+
+// Test file name parsing
+TEST(KmpStrTest, FileNameInit) {
+  const char *path = "/path/to/file.txt";
+  kmp_str_fname_t fname;
+  __kmp_str_fname_init(&fname, path);
+
+  EXPECT_NE(fname.path, nullptr);
+  EXPECT_STREQ(fname.path, path);
+  EXPECT_NE(fname.base, nullptr);
+  EXPECT_STREQ(fname.base, "file.txt");
+
+  __kmp_str_fname_free(&fname);
+}
+
+// Test string format
+TEST(KmpStrTest, StrFormat) {
+  char *result = __kmp_str_format("Number: %d, String: %s", 42, "test");
+
+  EXPECT_NE(result, nullptr);
+  EXPECT_STREQ(result, "Number: 42, String: test");
+
+  __kmp_str_free(&result);
+  EXPECT_EQ(result, nullptr);
+}
+
+// Test string buffer concatenate buffers
+TEST(KmpStrTest, BufferCatBuf) {
+  kmp_str_buf_t buf1, buf2;
+  __kmp_str_buf_init(&buf1);
+  __kmp_str_buf_init(&buf2);
+
+  __kmp_str_buf_print(&buf1, "Hello");
+  __kmp_str_buf_print(&buf2, " World");
+
+  __kmp_str_buf_catbuf(&buf1, &buf2);
+
+  EXPECT_STREQ(buf1.str, "Hello World");
+
+  __kmp_str_buf_free(&buf1);
+  __kmp_str_buf_free(&buf2);
+}
+
+// Test size string parsing
+TEST(KmpStrTest, StrToSize) {
+  size_t result;
+  const char *error = nullptr;
+
+  __kmp_str_to_size("100", &result, 1, &error);
+  EXPECT_EQ(error, nullptr);
+  EXPECT_EQ(result, 100u);
+
+  __kmp_str_to_size("1K", &result, 1024, &error);
+  EXPECT_EQ(error, nullptr);
+  EXPECT_EQ(result, 1024u);
+
+  __kmp_str_to_size("2M", &result, 1024, &error);
+  EXPECT_EQ(error, nullptr);
+  EXPECT_EQ(result, 2u * 1024u * 1024u);
+}
+
+// Test uint string parsing
+TEST(KmpStrTest, StrToUint) {
+  kmp_uint64 result;
+  const char *error = nullptr;
+
+  __kmp_str_to_uint("0", &result, &error);
+  EXPECT_EQ(error, nullptr);
+  EXPECT_EQ(result, 0u);
+
+  __kmp_str_to_uint("42", &result, &error);
+  EXPECT_EQ(error, nullptr);
+  EXPECT_EQ(result, 42u);
+
+  __kmp_str_to_uint("1234567890", &result, &error);
+  EXPECT_EQ(error, nullptr);
+  EXPECT_EQ(result, 1234567890u);
+}
+
+} // namespace

>From d1d01d36af1a8adf4790b44184e34b9bdecfb9ff Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Mon, 17 Nov 2025 04:25:01 -0600
Subject: [PATCH 2/2] dynamic linking for unit tests

---
 openmp/runtime/src/CMakeLists.txt       | 35 ++++++++++++++++++++++---
 openmp/runtime/unittests/CMakeLists.txt | 17 +++++++-----
 openmp/runtime/unittests/README.md      |  4 ++-
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/openmp/runtime/src/CMakeLists.txt b/openmp/runtime/src/CMakeLists.txt
index 44ddefcefa82f..bd88c8b6c39e9 100644
--- a/openmp/runtime/src/CMakeLists.txt
+++ b/openmp/runtime/src/CMakeLists.txt
@@ -176,17 +176,19 @@ endif()
 # Add the OpenMP library
 
 # First, create an OBJECT library with all the runtime sources.
-# This allows both the main library and unit tests to link against the same compiled objects.
+# This allows both the main library and unit tests to link against the same
+# compiled objects.
 add_library(omp_objects OBJECT ${LIBOMP_SOURCE_FILES})
 set_property(TARGET omp_objects PROPERTY FOLDER "OpenMP/Libraries")
 set_property(TARGET omp_objects PROPERTY POSITION_INDEPENDENT_CODE ON)
-# Export the omp_objects target so unittests can use it
+# Export the omp_objects target so unit tests can use it
 set(LIBOMP_OBJECTS_TARGET omp_objects PARENT_SCOPE)
 
 libomp_get_ldflags(LIBOMP_CONFIGURED_LDFLAGS)
-
 libomp_get_libflags(LIBOMP_CONFIGURED_LIBFLAGS)
-# Build libomp library. Add LLVMSupport dependency if building in-tree with libomptarget profiling enabled.
+
+# Build libomp library. Add LLVMSupport dependency if building in-tree with
+# libomptarget profiling enabled.
 if(OPENMP_STANDALONE_BUILD OR (NOT OPENMP_ENABLE_LIBOMP_PROFILING))
   add_library(omp ${LIBOMP_LIBRARY_KIND} $<TARGET_OBJECTS:omp_objects>)
   set_property(TARGET omp PROPERTY FOLDER "OpenMP/Libraries")
@@ -209,6 +211,31 @@ if(${LIBOMP_USE_HWLOC})
   )
 endif()
 
+# Build a testing version of libomp that exports all symbols for unit tests.
+# This library uses the same compiled objects as libomp, but with all symbols
+# exported to allow testing internal functions.
+if(NOT WIN32 AND NOT STUBS_LIBRARY)
+  set(LIBOMP_TEST_LDFLAGS ${LIBOMP_CONFIGURED_LDFLAGS})
+  # Replace the libomp exports with the test exports exporting all symbols.
+  if(LIBOMP_HAVE_VERSION_SCRIPT_FLAG)
+    string(REPLACE "${LIBOMP_SRC_DIR}/exports_so.txt"
+                   "${LIBOMP_SRC_DIR}/exports_test_so.txt"
+                   LIBOMP_TEST_LDFLAGS "${LIBOMP_TEST_LDFLAGS}")
+  endif()
+
+  # Create the testing library from the same objects as libomp.
+  add_library(omp_testing SHARED $<TARGET_OBJECTS:omp_objects>)
+  set_property(TARGET omp_testing PROPERTY FOLDER "OpenMP/Libraries")
+  target_link_libraries(omp_testing ${LIBOMP_CONFIGURED_LIBFLAGS} ${LIBOMP_DL_LIBS})
+  set_target_properties(omp_testing PROPERTIES
+    PREFIX "" SUFFIX "" OUTPUT_NAME "libomp_testing${LIBOMP_LIBRARY_SUFFIX}"
+    LINK_FLAGS "${LIBOMP_TEST_LDFLAGS}"
+    LINKER_LANGUAGE ${LIBOMP_LINKER_LANGUAGE}
+    EXCLUDE_FROM_ALL TRUE  # Don't build by default, only when tests need it
+  )
+  add_dependencies(omp_testing libomp-needed-headers)
+endif()
+
 if(OPENMP_MSVC_NAME_SCHEME)
   if(uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
     set(LIBOMP_PDB_NAME ${LIBOMP_DEFAULT_LIB_NAME}${MSVC_TOOLS_VERSION}d.${LIBOMP_ARCH})
diff --git a/openmp/runtime/unittests/CMakeLists.txt b/openmp/runtime/unittests/CMakeLists.txt
index 14ddbfc827cbb..e44fda78fb804 100644
--- a/openmp/runtime/unittests/CMakeLists.txt
+++ b/openmp/runtime/unittests/CMakeLists.txt
@@ -1,19 +1,22 @@
 add_custom_target(OpenMPUnitTests)
 set_target_properties(OpenMPUnitTests PROPERTIES FOLDER "OpenMP/Tests")
 
-if (NOT TARGET llvm_gtest)
+if(NOT TARGET llvm_gtest)
   message(WARNING "OpenMP unittests disabled due to GTest being unavailable; "
                   "Try LLVM_INSTALL_GTEST=ON for the LLVM build")
-  return ()
-endif ()
+  return()
+endif()
+if(NOT TARGET omp_testing)
+  message(WARNING "OpenMP unittests disabled due to omp_testing library being unavailable")
+  return()
+endif()
 
 function(add_openmp_unittest test_dirname)
   add_unittest(OpenMPUnitTests ${test_dirname} ${ARGN})
 
-  # Link against the object library created in runtime/src
-  target_link_libraries(${test_dirname} PRIVATE
-    $<TARGET_OBJECTS:omp_objects>
-  )
+  # Link against the testing library which exports all symbols.
+  target_link_libraries(${test_dirname} PRIVATE omp_testing)
+  add_dependencies(${test_dirname} omp_testing)
 
   target_include_directories(${test_dirname} PRIVATE
     ${LIBOMP_INCLUDE_DIR}
diff --git a/openmp/runtime/unittests/README.md b/openmp/runtime/unittests/README.md
index ad7dd9d716ceb..974f877654776 100644
--- a/openmp/runtime/unittests/README.md
+++ b/openmp/runtime/unittests/README.md
@@ -4,4 +4,6 @@ Usage:
 ```
 cd <your-llvm-build-directory>/runtimes/runtimes-bins
 ninja check-libomp-unit
-```
\ No newline at end of file
+```
+
+Note: unit tests are currently not supported on Windows



More information about the Openmp-commits mailing list