This is an archive of the discontinued LLVM Phabricator instance.

[OpenMP] Fix clang-cl build error regarding TSX intrinsics
ClosedPublic

Authored by jlpeyton on Feb 24 2021, 1:37 PM.

Details

Summary

Fix for https://bugs.llvm.org/show_bug.cgi?id=49339

The CMake check for the RTM intrinsics needs the -mrtm flag to be set during the test. This way clang-cl correctly detects it has the _xbegin() intrinsic. Otherwise, the CMake check fails.

Diff Detail

Event Timeline

jlpeyton created this revision.Feb 24 2021, 1:37 PM
jlpeyton requested review of this revision.Feb 24 2021, 1:37 PM
hans added a comment.Feb 25 2021, 2:17 AM

I tried this, and it didn't fix the build error for me.

In the CMake log I see this:

-- Performing Test LIBOMP_HAVE_MRTM_FLAG
-- Performing Test LIBOMP_HAVE_MRTM_FLAG - Success
[..]
-- Performing Test LIBOMP_HAVE_RTM_INTRINSICS
-- Performing Test LIBOMP_HAVE_RTM_INTRINSICS - Failed

And in CMakeError.log:

Performing C++ SOURCE FILE Test LIBOMP_HAVE_RTM_INTRINSICS failed with the following output:
Change Dir: C:/src/llvm.monorepo/build.32selfhost/CMakeFiles/CMakeTmp

Run Build Command(s):C:/src/depot_tools/ninja.exe cmTC_fb778 && [1/2] Building CXX object CMakeFiles\cmTC_fb778.dir\src.cxx.obj
FAILED: CMakeFiles/cmTC_fb778.dir/src.cxx.obj 
c:\src\llvm.monorepo\build.32\bin\clang-cl.exe  /nologo -TP -DATTRIBUTE_RTM -DATTRIBUTE_WAITPKG -DIMMINTRIN_H  /DWIN32 /D_WINDOWS   /Zc:inline /Zc:__cplusplus /Zc:strictStrings /Oi /Zc:rvalueCast /Brepro /bigobj /W4  -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion /Gw -Wcast-qual -Wformat-pedantic -Wimplicit-fallthrough -Wsign-compare -Wno-extra -Wno-pedantic -DLIBOMP_HAVE_RTM_INTRINSICS  -Werror=unguarded-availability-new /MTd /Zi /Ob0 /Od /RTC1   -std:c++14 /showIncludes /FoCMakeFiles\cmTC_fb778.dir\src.cxx.obj /FdCMakeFiles\cmTC_fb778.dir\ -c src.cxx
src.cxx(12,16): error: use of undeclared identifier '_xbegin'
        return _xbegin();
               ^
1 error generated.
ninja: build stopped: subcommand failed.


Source file was:
// check for attribute rtm and rtm intrinsics
      #ifdef IMMINTRIN_H
      #include <immintrin.h>
      #endif
      #ifdef INTRIN_H
      #include <intrin.h>
      #endif
      #ifdef ATTRIBUTE_RTM
      __attribute__((target("rtm")))
      #endif
      static inline int __kmp_xbegin() {
        return _xbegin();
      }
      int main() { int a = __kmp_xbegin(); return a; }

It seems the -mrtm flag was never passed to clang-cl.

But if I change the patch to do

set(CMAKE_REQUIRED_FLAGS)
libomp_append(CMAKE_REQUIRED_FLAGS -mrtm LIBOMP_HAVE_MRTM_FLAG)

It works.

I'm not familiar with libomp's cmake stuff, but maybe libomp_append doesn't work if the variable is previously not defined?
My tweak should maybe not be taken as-is, since it would overwrite CMAKE_REQUIRED_FLAGS if it was non-empty.

hans added a comment.Feb 25 2021, 2:24 AM

Oh, and I just realized: just because my machine supports RTM doesn't necessarily mean we want to use it, since these builds will then be used on all kinds of machines. This might be a bigger problem with the runtime's build config though.

jlpeyton updated this revision to Diff 326424.Feb 25 2021, 9:21 AM

Since CMake's documentation states that the CMAKE_REQURIED_FLAGS variable is a string rather than a list, use simple set() to assign it.

Oh, and I just realized: just because my machine supports RTM doesn't necessarily mean we want to use it, since these builds will then be used on all kinds of machines. This might be a bigger problem with the runtime's build config though.

I think only the build compiler needs to support the instructions, not your machine.
This shouldn't cause a problem since the RTM instrinsics are only used inside a specific lock kind which the user must select using an environment variable.

hans accepted this revision.Mar 1 2021, 4:39 AM

Oh, and I just realized: just because my machine supports RTM doesn't necessarily mean we want to use it, since these builds will then be used on all kinds of machines. This might be a bigger problem with the runtime's build config though.

I think only the build compiler needs to support the instructions, not your machine.
This shouldn't cause a problem since the RTM instrinsics are only used inside a specific lock kind which the user must select using an environment variable.

I see. Thanks for clarifying!

openmp/runtime/cmake/config-ix.cmake
179

I looked for how CMAKE_REQUIRED_FLAGS is used in other places, and this pattern seems common:

set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")

Maybe that is safer, in case CMAKE_REQUIRED_FLAGS already holds some flag that is important for the build.

This revision is now accepted and ready to land.Mar 1 2021, 4:39 AM
jlpeyton updated this revision to Diff 327291.Mar 1 2021, 2:22 PM

Ok, I see what you're saying. I've copied the exact idiom used in the LLVM CMake where CMAKE_REQUIRED_FLAGS is temporarily stored in OLD_CMAKE_REQUIRED_FLAGS and then restored after the check.

jlpeyton updated this revision to Diff 327292.Mar 1 2021, 2:25 PM

Ok, this actually restores using OLD_CMAKE_REQUIRED_FLAGS

hans accepted this revision.Mar 2 2021, 4:45 AM

Looks good to me. Thanks!