Ensure correct pthread flags and libraries are used

On most platforms, certain compiler and linker flags have to be passed
when using pthreads, otherwise linking against libomp.so might fail with
undefined references to several pthread functions.

Use CMake's `find_package(Threads)` to determine these for standalone
builds, or take them (and optionally modify them) from the top-level
LLVM cmake files.

Also, On FreeBSD, ensure that libomp.so is linked against libm.so,
similar to NetBSD.

Adjust test cases with hardcoded `-lpthread` flag to use the common
build flags, which should now have the required pthread flags.

Reviewers: emaste, jlpeyton, krytarowski, mgorny, protze.joachim, Hahnfeld

Reviewed By: Hahnfeld

Subscribers: AndreyChurbanov, tra, EricWF, Hahnfeld, jfb, jdoerfert, openmp-commits

Tags: #openmp

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


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@357618 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/cmake/DetectTestCompiler/CMakeLists.txt b/cmake/DetectTestCompiler/CMakeLists.txt
index c2f408c..1fd7cc7 100644
--- a/cmake/DetectTestCompiler/CMakeLists.txt
+++ b/cmake/DetectTestCompiler/CMakeLists.txt
@@ -18,8 +18,12 @@
   set(OpenMP_CXX_FLAGS "-fopenmp")
 endif()
 
-set(C_FLAGS ${flags} ${OpenMP_C_FLAGS})
-set(CXX_FLAGS ${flags} ${OpenMP_CXX_FLAGS})
+set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
+set(THREADS_PREFER_PTHREAD_FLAG TRUE)
+find_package(Threads REQUIRED)
+
+set(C_FLAGS "${OpenMP_C_FLAGS} ${CMAKE_THREAD_LIBS_INIT}")
+set(CXX_FLAGS "${OpenMP_CXX_FLAGS} ${CMAKE_THREAD_LIBS_INIT}")
 
 # TODO: Implement blockaddress in GlobalISel and remove this flag!
 if (CMAKE_C_COMPILER_ID STREQUAL "Clang")
diff --git a/cmake/OpenMPTesting.cmake b/cmake/OpenMPTesting.cmake
index 187c874..396460a 100644
--- a/cmake/OpenMPTesting.cmake
+++ b/cmake/OpenMPTesting.cmake
@@ -120,8 +120,16 @@
   set(OPENMP_TEST_COMPILER_VERSION "${LLVM_VERSION}")
   set(OPENMP_TEST_COMPILER_VERSION_MAJOR "${LLVM_MAJOR_VERSION}")
   set(OPENMP_TEST_COMPILER_VERSION_MAJOR_MINOR "${LLVM_MAJOR_VERSION}.${LLVM_MINOR_VERSION}")
+  # Unfortunately the top-level cmake/config-ix.cmake file mangles CMake's
+  # CMAKE_THREAD_LIBS_INIT variable from the FindThreads package, so work
+  # around that, until it is fixed there.
+  if(${CMAKE_THREAD_LIBS_INIT} STREQUAL "-lpthread")
+    set(OPENMP_TEST_COMPILER_THREAD_FLAGS "-pthread")
+  else()
+    set(OPENMP_TEST_COMPILER_THREAD_FLAGS "${CMAKE_THREAD_LIBS_INIT}")
+  endif()
   # TODO: Implement blockaddress in GlobalISel and remove this flag!
-  set(OPENMP_TEST_COMPILER_OPENMP_FLAGS "-fopenmp -fno-experimental-isel")
+  set(OPENMP_TEST_COMPILER_OPENMP_FLAGS "-fopenmp ${OPENMP_TEST_COMPILER_THREAD_FLAGS} -fno-experimental-isel")
 endif()
 
 # Function to set compiler features for use in lit.
diff --git a/runtime/cmake/LibompHandleFlags.cmake b/runtime/cmake/LibompHandleFlags.cmake
index 1690b2b..86f6294 100644
--- a/runtime/cmake/LibompHandleFlags.cmake
+++ b/runtime/cmake/LibompHandleFlags.cmake
@@ -158,14 +158,13 @@
   if(${IA32})
     libomp_append(libflags_local -lirc_pic LIBOMP_HAVE_IRC_PIC_LIBRARY)
   endif()
-  IF(${CMAKE_SYSTEM_NAME} MATCHES "DragonFly")
+  if(${CMAKE_SYSTEM_NAME} MATCHES "DragonFly")
     libomp_append(libflags_local "-Wl,--no-as-needed" LIBOMP_HAVE_AS_NEEDED_FLAG)
     libomp_append(libflags_local "-lm")
     libomp_append(libflags_local "-Wl,--as-needed" LIBOMP_HAVE_AS_NEEDED_FLAG)
-  ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "DragonFly")
-  IF(${CMAKE_SYSTEM_NAME} MATCHES "NetBSD")
+  elseif(${CMAKE_SYSTEM_NAME} MATCHES "(Free|Net)BSD")
     libomp_append(libflags_local -lm)
-  ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "NetBSD")
+  endif()
   set(libflags_local ${libflags_local} ${LIBOMP_LIBFLAGS})
   libomp_setup_flags(libflags_local)
   set(${libflags} ${libflags_local} PARENT_SCOPE)
diff --git a/runtime/cmake/LibompMicroTests.cmake b/runtime/cmake/LibompMicroTests.cmake
index 38f4486..2fde724 100644
--- a/runtime/cmake/LibompMicroTests.cmake
+++ b/runtime/cmake/LibompMicroTests.cmake
@@ -170,7 +170,7 @@
 add_custom_target(libomp-test-deps DEPENDS test-deps/.success)
 set(libomp_expected_library_deps)
 if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
-  set(libomp_expected_library_deps libc.so.7 libthr.so.3)
+  set(libomp_expected_library_deps libc.so.7 libthr.so.3 libm.so.5)
   libomp_append(libomp_expected_library_deps libhwloc.so.5 LIBOMP_USE_HWLOC)
 elseif(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
   set(libomp_expected_library_deps libc.so.12 libpthread.so.1 libm.so.0)
diff --git a/runtime/test/misc_bugs/omp_foreign_thread_team_reuse.c b/runtime/test/misc_bugs/omp_foreign_thread_team_reuse.c
index 4d70d47..a8400e4 100644
--- a/runtime/test/misc_bugs/omp_foreign_thread_team_reuse.c
+++ b/runtime/test/misc_bugs/omp_foreign_thread_team_reuse.c
@@ -1,4 +1,4 @@
-// RUN: %libomp-compile -lpthread && %libomp-run
+// RUN: %libomp-compile-and-run
 #include <stdio.h>
 #include "omp_testsuite.h"
 
diff --git a/runtime/test/tasking/bug_nested_proxy_task.c b/runtime/test/tasking/bug_nested_proxy_task.c
index 84e4dfd..3f0a015 100644
--- a/runtime/test/tasking/bug_nested_proxy_task.c
+++ b/runtime/test/tasking/bug_nested_proxy_task.c
@@ -1,4 +1,4 @@
-// RUN: %libomp-compile -lpthread && %libomp-run
+// RUN: %libomp-compile-and-run
 // REQUIRES: openmp-4.5
 // The runtime currently does not get dependency information from GCC.
 // UNSUPPORTED: gcc
diff --git a/runtime/test/tasking/bug_proxy_task_dep_waiting.c b/runtime/test/tasking/bug_proxy_task_dep_waiting.c
index fe8f18d..03e18a6 100644
--- a/runtime/test/tasking/bug_proxy_task_dep_waiting.c
+++ b/runtime/test/tasking/bug_proxy_task_dep_waiting.c
@@ -1,4 +1,4 @@
-// RUN: %libomp-compile -lpthread && %libomp-run
+// RUN: %libomp-compile-and-run
 // REQUIRES: openmp-4.5
 // The runtime currently does not get dependency information from GCC.
 // UNSUPPORTED: gcc