Skip to content

Conversation

mstorsjo
Copy link
Member

@mstorsjo mstorsjo commented Oct 2, 2025

We install a (or in practice, update a preexisting) copy of Clang, in order to get a specific version that we want. At that point in the procedure, this is the only version of Clang in the PATH.

However, the step of adding the MSVC build tools to the environment also ends up adding another copy of Clang, bundled with MSVC, into the PATH.

Due to this, CMake ends up finding and preferring the older version of Clang bundled with MSVC, rather than the one we intend to be used.

Manually add the directory of the version of Clang we want to use at the head of the search path, after initializing the MSVC build tool environment.

The directory name we add is a hardcoded guess of where it is installed - this is not ideal, but seems like the most straightforward solution for now.

@mstorsjo mstorsjo requested a review from philnik777 October 2, 2025 21:12
@llvmbot llvmbot added libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. github:workflow labels Oct 2, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 2, 2025

@llvm/pr-subscribers-libcxx

@llvm/pr-subscribers-github-workflow

Author: Martin Storsjö (mstorsjo)

Changes

We install a (or in practice, update a preexisting) copy of Clang, in order to get a specific version that we want. At that point in the procedure, this is the only version of Clang in the PATH.

However, the step of adding the MSVC build tools to the environment also ends up adding another copy of Clang, bundled with MSVC, into the PATH.

Due to this, CMake ends up finding and preferring the older version of Clang bundled with MSVC, rather than the one we intend to be used.

Manually add the directory of the version of Clang we want to use at the head of the search path, after initializing the MSVC build tool environment.

The directory name we add is a hardcoded guess of where it is installed - this is not ideal, but seems like the most straightforward solution for now.


Full diff: https://github.com/llvm/llvm-project/pull/161736.diff

1 Files Affected:

  • (modified) .github/workflows/libcxx-build-and-test.yaml (+4)
diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml
index 1c07a0adc6e99..77f79a85a0a2f 100644
--- a/.github/workflows/libcxx-build-and-test.yaml
+++ b/.github/workflows/libcxx-build-and-test.yaml
@@ -281,6 +281,10 @@ jobs:
       - name: Set up the MSVC dev environment
         if: ${{ matrix.mingw != true }}
         uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
+      - name: Add the installed Clang at the start of the path
+        if: ${{ matrix.mingw != true }}
+        run: |
+          echo "c:\Program Files\LLVM\bin" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf8 -Append
       - name: Build and test
         run: |
           bash libcxx/utils/ci/run-buildbot ${{ matrix.config }}

Copy link
Contributor

@philnik777 philnik777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@mstorsjo
Copy link
Member Author

mstorsjo commented Oct 3, 2025

Unfortunately, this change can't be landed as is; this breaks the libcxx/system_reserved_names.gen.py test in all the clang-cl configurations:

2025-10-02T22:06:18.5198506Z # | In file included from D:\a\llvm-project\llvm-project\build\clang-cl-dll\libcxx\test\libcxx\system_reserved_names.gen.py\vector.compile.pass.cpp:166:
2025-10-02T22:06:18.5203380Z # | In file included from D:/a/llvm-project/llvm-project/build/clang-cl-dll/libcxx/test-suite-install/include/c++/v1\vector:312:
2025-10-02T22:06:18.6188414Z # | In file included from D:/a/llvm-project/llvm-project/build/clang-cl-dll/libcxx/test-suite-install/include/c++/v1\__vector/comparison.h:13:
2025-10-02T22:06:18.6195056Z # | In file included from D:/a/llvm-project/llvm-project/build/clang-cl-dll/libcxx/test-suite-install/include/c++/v1\__algorithm/lexicographical_compare.h:30:
2025-10-02T22:06:18.6201844Z # | In file included from D:/a/llvm-project/llvm-project/build/clang-cl-dll/libcxx/test-suite-install/include/c++/v1\cwchar:118:
2025-10-02T22:06:18.6242316Z # | In file included from D:/a/llvm-project/llvm-project/build/clang-cl-dll/libcxx/test-suite-install/include/c++/v1\wchar.h:116:
2025-10-02T22:06:18.6248276Z # | In file included from C:\Program Files (x86)\Windows Kits\10\include\10.0.26100.0\ucrt\wchar.h:29:
2025-10-02T22:06:18.6340279Z # | In file included from C:\Program Files\LLVM\lib\clang\20\include\intrin.h:22:
2025-10-02T22:06:18.6357937Z # | In file included from C:\Program Files\LLVM\lib\clang\20\include\x86intrin.h:15:
2025-10-02T22:06:18.6363418Z # | In file included from C:\Program Files\LLVM\lib\clang\20\include\immintrin.h:712:
2025-10-02T22:06:18.6405287Z # | C:\Program Files\LLVM\lib\clang\20\include\avx10_2bf16intrin.h:522:69: error: expected ')'
2025-10-02T22:06:18.6425064Z # |   522 | static __inline__ int __DEFAULT_FN_ATTRS128 _mm_comieq_sbh(__m128bh A,
2025-10-02T22:06:18.6452224Z # |       |                                                                     ^
2025-10-02T22:06:18.6469942Z # | D:\a\llvm-project\llvm-project\build\clang-cl-dll\libcxx\test\libcxx\system_reserved_names.gen.py\vector.compile.pass.cpp:106:11: note: expanded from macro 'A'
2025-10-02T22:06:18.6497033Z # |   106 | #define A SYSTEM_RESERVED_NAME
2025-10-02T22:06:18.6516120Z # |       |           ^

The issue seems to be that Clang in 20.x has added more AVX10 intrinsics headers, and these use unreserved parameter names such as A directly in the intrinsics headers; this is prone to break user code, exactly which the libcxx test here tries to check for. CC @FreddyLeaf @phoebewang. This issue is already existent in all Clang 20.x releases, and all 21.x releases so far (but we have a chance to have it fixed there at least). See 6f04f46 for a similar earlier issue fix.

Action point to Clang: CC @erichkeane (feel free to delegate) and @phoebewang - This is at least the second case when the Intel intrinsics headers expose this kind of issue. Can Clang set up some kind of similar test as libcxx has, to make sure we don't add more similar issues in the Clang bundled resource headers (in particular, the intrinsics headers which are a pain to wade through).

The libcxx CI is already on Clang 20.x for the mingw build configurations (and likewise for the Linux test configurations, I would presume), but those don't seem to pull in the Clang intrinsics headers. The fact that intrinsics headers are included here seems to be a specific quirk in the MS UCRT headers; since version 10.0.26100.0 of those headers, wchar.h seems to pull in intrin.h - otherwise this would have been found much sooner.

Aside from this, it seems like at least the clang-cl-dll test config also fails std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp. No idea why that happens; we'll see if that's a fluke if we get the other issues sorted out.

@philnik777 As Clang 20.x (and early 21.x) intrinsics headers seem to be broken wrt this, what's the best way forward here do you think? Explicitly skip this test for e.g. clang-20 && msvc or something like that, and make sure it's fixed in 21.x before we'd try to upgrade to that in CI?

@mstorsjo
Copy link
Member Author

mstorsjo commented Oct 3, 2025

I filed #161808 for the new issue in the Clang headers.

mstorsjo added a commit to mstorsjo/llvm-project that referenced this pull request Oct 3, 2025
… msvc

Clang 20 (and early 21 versions; let's hope it can be fixed
before the later versions before such versions become relevant
for libcxx CI) have got an issue with its intrinsics headers,
where they use unreserved names, that users are allowed to override.

See llvm#161808 for the
issue report.

This only crops up in the MSVC build configurations, as recent
versions of some MSVC/UCRT headers include `<intrin.h>`, which
ends up pulling in most intrinsics headers, exposing this issue
in the Clang headers.

This should unblock llvm#161736
from being merged.
phoebewang added a commit to phoebewang/llvm-project that referenced this pull request Oct 3, 2025
@phoebewang
Copy link
Contributor

@mstorsjo sorry for the inconvenience and thanks for the fix!

The libcxx CI is already on Clang 20.x for the mingw build configurations (and likewise for the Linux test configurations, I would presume), but those don't seem to pull in the Clang intrinsics headers. The fact that intrinsics headers are included here seems to be a specific quirk in the MS UCRT headers; since version 10.0.26100.0 of those headers, wchar.h seems to pull in intrin.h - otherwise this would have been found much sooner.

I think fe42d34 may be another reason, we include all intrinsics after it. Does it mean we have covered it?

@mstorsjo
Copy link
Member Author

mstorsjo commented Oct 3, 2025

@mstorsjo sorry for the inconvenience and thanks for the fix!

The libcxx CI is already on Clang 20.x for the mingw build configurations (and likewise for the Linux test configurations, I would presume), but those don't seem to pull in the Clang intrinsics headers. The fact that intrinsics headers are included here seems to be a specific quirk in the MS UCRT headers; since version 10.0.26100.0 of those headers, wchar.h seems to pull in intrin.h - otherwise this would have been found much sooner.

I think fe42d34 may be another reason, we include all intrinsics after it.

I don't think that commit is related here. It's in 21.x only, and I was hitting this on 20.x. And that commit is a no-op if __SCE__ wasn't defined before.

Does it mean we have covered it?

I don't understand what you mean by this question here.

@phoebewang
Copy link
Contributor

@mstorsjo sorry for the inconvenience and thanks for the fix!

The libcxx CI is already on Clang 20.x for the mingw build configurations (and likewise for the Linux test configurations, I would presume), but those don't seem to pull in the Clang intrinsics headers. The fact that intrinsics headers are included here seems to be a specific quirk in the MS UCRT headers; since version 10.0.26100.0 of those headers, wchar.h seems to pull in intrin.h - otherwise this would have been found much sooner.

I think fe42d34 may be another reason, we include all intrinsics after it.

I don't think that commit is related here. It's in 21.x only, and I was hitting this on 20.x. And that commit is a no-op if __SCE__ wasn't defined before.

Does it mean we have covered it?

I don't understand what you mean by this question here.

I mean with fe42d34, these intrinsics should be tested on Windows environment since they are included through intrin.h.

@mstorsjo
Copy link
Member Author

mstorsjo commented Oct 3, 2025

I mean with fe42d34, these intrinsics should be tested on Windows environment since they are included through intrin.h.

That commit does not make any difference - it is unrelated. It removed ifdefs like #if !defined(__SCE__) || __has_feature(modules) || defined(__BMI__). If !defined(__SCE__) (on non-playstation targets), this was an #if 1, so the ifdef had no effect before. So the commit, removing the ifdefs doesn't change anything.

@phoebewang
Copy link
Contributor

I mean with fe42d34, these intrinsics should be tested on Windows environment since they are included through intrin.h.

That commit does not make any difference - it is unrelated. It removed ifdefs like #if !defined(__SCE__) || __has_feature(modules) || defined(__BMI__). If !defined(__SCE__) (on non-playstation targets), this was an #if 1, so the ifdef had no effect before. So the commit, removing the ifdefs doesn't change anything.

Oh, I see. I mixed up with removing _MSC_VER. That change was in 20.x already.

mstorsjo added a commit that referenced this pull request Oct 3, 2025
… msvc (#161811)

Clang 20 (and early 21 versions; let's hope it can be fixed before the
later versions before such versions become relevant for libcxx CI) have
got an issue with its intrinsics headers, where they use unreserved
names, that users are allowed to override.

See #161808 for the issue
report.

This only crops up in the MSVC build configurations, as recent versions
of some MSVC/UCRT headers include `<intrin.h>`, which ends up pulling in
most intrinsics headers, exposing this issue in the Clang headers.

This should unblock #161736
from being merged.
We install a (or in practice, update a preexisting) copy of Clang,
in order to get a specific version that we want. At that point
in the procedure, this is the only version of Clang in the PATH.

However, the step of adding the MSVC build tools to the environment
also ends up adding another copy of Clang, bundled with MSVC, into
the PATH.

Due to this, CMake ends up finding and preferring the older version
of Clang bundled with MSVC, rather than the one we intend to be
used.

Manually add the directory of the version of Clang we want to use at
the head of the search path, after initializing the MSVC build tool
environment.

The directory name we add is a hardcoded guess of where it is
installed - this is not ideal, but seems like the most
straightforward solution for now.
@mstorsjo mstorsjo force-pushed the libcxx-ci-clang-path branch from 99d68f9 to 36b1451 Compare October 3, 2025 14:46
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Oct 3, 2025
…clang-20 && msvc (#161811)

Clang 20 (and early 21 versions; let's hope it can be fixed before the
later versions before such versions become relevant for libcxx CI) have
got an issue with its intrinsics headers, where they use unreserved
names, that users are allowed to override.

See llvm/llvm-project#161808 for the issue
report.

This only crops up in the MSVC build configurations, as recent versions
of some MSVC/UCRT headers include `<intrin.h>`, which ends up pulling in
most intrinsics headers, exposing this issue in the Clang headers.

This should unblock llvm/llvm-project#161736
from being merged.
@mstorsjo
Copy link
Member Author

mstorsjo commented Oct 3, 2025

Aside from this, it seems like at least the clang-cl-dll test config also fails std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp. No idea why that happens; we'll see if that's a fluke if we get the other issues sorted out.

That did indeed seem to be a fluke; now all the Windows builds succeeded again - so I'll merge this, to unblock #134330.

@mstorsjo mstorsjo merged commit f5dc553 into llvm:main Oct 3, 2025
60 of 66 checks passed
@mstorsjo mstorsjo deleted the libcxx-ci-clang-path branch October 3, 2025 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
github:workflow libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants