Skip to content

Fix missing bytesize check for safe find vectorization with LLVM#6298

Open
mgovers wants to merge 2 commits into
microsoft:mainfrom
mgovers:GH006294-llvm-vectorization-is-safe
Open

Fix missing bytesize check for safe find vectorization with LLVM#6298
mgovers wants to merge 2 commits into
microsoft:mainfrom
mgovers:GH006294-llvm-vectorization-is-safe

Conversation

@mgovers
Copy link
Copy Markdown

@mgovers mgovers commented May 27, 2026

Fixes #6294

Here's my attempt at excluding odd-sized and large-sized structs from the vectorization in xutility.

Design approach

I have tried to follow all the conventions used elsewhere as much as possible, in particular:

  • for the implementation, I followed what was already there and the changes from Vectorize find-like algorithms for Clang for more types #5767
  • for the tests, following 3da7d27
    • NOTE: I explicitly scoped out equivalent tests as for _Equal_memcmp_is_safe as the current main implementation of _Vector_alg_in_find_is_safe was not tested in the first place. I still opted to add a couple more tests than for _Vector_alg_in_search_is_safe to at the very least show that there's vectorization for MSVC and not only for Clang
  • Since _Vector_alg_in_search_is_safe already had a similar check as what was needed here, I re-used that one (had to move it outside the #ifdef statement, though)
    • I did multiple searches for strings like _VECTORIZED_FIND, static_assert(false, "unexpected size");, _vectorized( and _Nx <= 8 && (_Nx & (_Nx - 1)) == 0 to see if there were other cases that I missed. I believe (and hope) I got them all (at least in algorithm and xutility).
    • I intentionally did not include MINMAX-like things, because they are independently explicitly guarded where the vectorized versions are used.

Additional remarks/open questions

  • I am re-running all tests locally once more as we speak, but it seems like some unrelated tests are failing on my device, also on main, so those are not an issue with my branch.
    • I will compare the failed scenarios once I'm finished running.
    • I am already opening this PR in the hope that CI will tell me for sure.
  • What is the best way (if any) to add the test case from <xutility>: std::find no longer compiles with structs with defaulted equality comparison with Clang-CL #6294 ?
    • Is it worth the effort to create a very small test file that contains exactly that edge case?
    • Or should I add it to the one I already added?
  • Should I benchmark? Or will that be done on your end?
    • (cfr. For performance-sensitive code (e.g. containers and algorithms) you may wish to write and/or run benchmarks, and the STL team will likely run any benchmarks we do have in our PR process.)
    • It is touching sensitive code (very common algorithms with high performance demands) and explicitly disabling vectorization (which is, in fact, a bugfix and it should only be excluding things that never compiled in the first place, but still...)

Despite my questions, I think (and hope) that my contribution is in a good state anyways.

… LLVM

Signed-off-by: Martijn Govers <Martijn.Govers@Alliander.com>
Copilot AI review requested due to automatic review settings May 27, 2026 06:44
@mgovers mgovers requested a review from a team as a code owner May 27, 2026 06:44
@github-project-automation github-project-automation Bot moved this to Initial Review in STL Code Reviews May 27, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds coverage and refines internal gating for vectorized algorithms by centralizing “allowed element sizes” and tightening _Vector_alg_in_find_is_safe eligibility.

Changes:

  • Introduces _Is_vector_element_size and reuses it across reverse/reverse_copy implementations.
  • Tightens _Vector_alg_in_find_is_safe_elem by requiring element sizes of 1/2/4/8.
  • Adds a new compile-only test for _Vector_alg_in_find_is_safe and extends existing _Equal_memcmp_is_safe/_Vector_alg_in_search_is_safe coverage.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/std/tests/GH_006294_vectorized_find_is_safe/test.compile.pass.cpp New compile-time assertions for _Vector_alg_in_find_is_safe across scalar/pointer/custom types.
tests/std/tests/GH_006294_vectorized_find_is_safe/env.lst Wires the new test directory into the usual test matrix.
tests/std/tests/GH_000431_equal_memcmp_is_safe/test.compile.pass.cpp Adds a larger default-comparison type and validates memcmp/search safety expectations.
tests/std/test.lst Registers the new GH_006294 test in the overall test list.
stl/inc/xutility Centralizes size gating via _Is_vector_element_size; tightens find safety; reuses gating in reverse.
stl/inc/algorithm Reuses _Is_vector_element_size gating in ranges::reverse, reverse_copy, and ranges::reverse_copy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/std/tests/GH_006294_vectorized_find_is_safe/test.compile.pass.cpp Outdated
Comment on lines +12 to +16
#ifdef __clang__
constexpr bool vectorized_trivial_comparison = true;
#else
constexpr bool vectorized_trivial_comparison = false;
#endif
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I don't think there's such a trait. Instead, since the actual implementation uses #ifdef __clang__, I believe that this approach is the correct one. It also aligns with #5767

Signed-off-by: Martijn Govers <Martijn.Govers@Alliander.com>
@StephanTLavavej
Copy link
Copy Markdown
Member

/azp run STL-CI

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@StephanTLavavej StephanTLavavej added the bug Something isn't working label May 27, 2026
@mgovers
Copy link
Copy Markdown
Author

mgovers commented May 27, 2026

The failing tests are x86_86-only:

Failed Tests (14):
  libc++ :: std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp:0
  libc++ :: std/containers/container.adaptors/flat.set/flat.set.capacity/size.pass.cpp:2
  libc++ :: std/containers/container.adaptors/queue/queue.cons/move_noexcept.pass.cpp:2
  libc++ :: std/time/time.cal/time.cal.mwdlast/types.pass.cpp:2
  libc++ :: std/time/weeks.pass.cpp:0
  std :: tests/Dev11_0732166_unordered_strong_guarantee:41
  std :: tests/P0009R18_mdspan_layout_right:21
  std :: tests/P1206R7_unordered_multiset_from_range:27
  std :: tests/P2286R8_text_formatting_range_formatter:21
  std :: tests/P2321R2_views_zip_transform:027
  std :: tests/P2321R2_views_zip_transform:077
  std :: tests/P3349R1_contiguous_iterators_to_pointers:28
  std :: tests/VSO_0000000_vector_algorithms:037
  std :: tests/VSO_0961751_hash_range_erase:25

However, I do not have an x86 machine. How can I investigate what went wrong?

Regarding the CLA, I did not forget about it, I'm on it.

@AlexGuteniev
Copy link
Copy Markdown
Contributor

However, I do not have an x86 machine. How can I investigate what went wrong?

x64 OS can still execute x86 program using Wow64. You don't need to do anything special for that, just run x86 executables.

Specifically, you just need to follow x86 instructions from README.md on x64 machine.

@mgovers
Copy link
Copy Markdown
Author

mgovers commented May 27, 2026

However, I do not have an x86 machine. How can I investigate what went wrong?

x64 OS can still execute x86 program using Wow64. You don't need to do anything special for that, just run x86 executables.

Specifically, you just need to follow x86 instructions from README.md on x64 machine.

I am now able to run the x86 tests but don't seem to be able to reproduce the error...

from an x86 native tools command prompt, running for all failing tests in the above:

<...>\STL\out\x86> python tests\utils\stl-lit\stl-lit.py -Dnotags=ASAN ..\..\tests\<test_dir>\

yields

PASS: std :: tests/Dev11_0732166_unordered_strong_guarantee:41 (32 of 46)
PASS: std :: tests/P0009R18_mdspan_layout_right:21 (27 of 30)
PASS: std :: tests/P1206R7_unordered_multiset_from_range:27 (28 of 30)
PASS: std :: tests/P2286R8_text_formatting_range_formatter:21 (26 of 30)
PASS: std :: tests/P2321R2_views_zip_transform:027 (52 of 116)
PASS: std :: tests/P2321R2_views_zip_transform:077 (98 of 116)
PASS: std :: tests/P3349R1_contiguous_iterators_to_pointers:28 (62 of 64)
PASS: std :: tests/VSO_0000000_vector_algorithms:037 (112 of 138)
PASS: std :: tests/VSO_0961751_hash_range_erase:25 (37 of 46)

I am still running the libc++ tests (for reference; will update once i have the results):

PASS: libc++ :: std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp:0 (2444 of 24345)
PASS: libc++ :: std/containers/container.adaptors/flat.set/flat.set.capacity/size.pass.cpp:2 (3239 of 24345)
PASS: libc++ :: std/containers/container.adaptors/queue/queue.cons/move_noexcept.pass.cpp:2 (3534 of 24345)
PASS: libc++ :: std/time/time.cal/time.cal.mwdlast/types.pass.cpp:2 (19371 of 24345)
PASS: libc++ :: std/time/weeks.pass.cpp:0 (20511 of 24345)

@AlexGuteniev
Copy link
Copy Markdown
Contributor

from an x86 native tools command prompt, running for all failing tests in the above:

Then I suspect it is a spurious CI failure.

Observe that only one shard has failed tests, whereas I'd expect them to be distributed across 10 of them.

Let's assume it passed, and you only owe CLA here.

@mgovers
Copy link
Copy Markdown
Author

mgovers commented May 27, 2026

from an x86 native tools command prompt, running for all failing tests in the above:

Then I suspect it is a spurious CI failure.

Observe that only one shard has failed tests, whereas I'd expect them to be distributed across 10 of them.

Let's assume it passed, and you only owe CLA here.

OK, awesome, thank you!

Yes, I am working with the OSPO to get the paperwork for the CLA finished at my company internally. We expect that process to be finished tomorrow.

After that, I will start the process here and make sure the appropriate people take the right follow-up steps to finish it (should not take long).

Do we need to run the benchmarks as well?

@AlexGuteniev
Copy link
Copy Markdown
Contributor

Do we need to run the benchmarks as well?

I assume that you don't need to write your own benchmark, but it would be good to run existing benchmarks before and after your changes, for find, just to make sure the vectorization code path is still enabled after your changes.

Observe that out of all #5479 PRs I only added a new benchmark in #5591, to see if adding odd size support really helps

I'm not a maintainer though, I only contributed a part of the vectorization here.

@StephanTLavavej
Copy link
Copy Markdown
Member

I reran the failed shard and it passed; it looked like the machine got corrupted and it wasn't our test suite's fault (much less yours).

I am not terribly concerned about running benchmarks for a fix like this; the benchmarks are useful when making tuning decisions.

I am severely overloaded at the moment (half of my time is going to non-STL work - not my choice, sorry!) but your PR is on my radar and I'll review it when I get a chance. The only feedback I have right now is to remove the bug number from the PR title, where it provides no value. (The PR description saying Fixes #nnnn is perfect.)

@mgovers mgovers changed the title Fix #6294 missing bytesize check for safe find vectorization with LLVM Fix missing bytesize check for safe find vectorization with LLVM May 28, 2026
@mgovers
Copy link
Copy Markdown
Author

mgovers commented May 28, 2026

I reran the failed shard and it passed; it looked like the machine got corrupted and it wasn't our test suite's fault (much less yours).

I am not terribly concerned about running benchmarks for a fix like this; the benchmarks are useful when making tuning decisions.

Great! Thanks for the input

I am severely overloaded at the moment (half of my time is going to non-STL work - not my choice, sorry!) but your PR is on my radar and I'll review it when I get a chance.

No worries, same for me and the project I'm working on

The only feedback I have right now is to remove the bug number from the PR title, where it provides no value. (The PR description saying Fixes #nnnn is perfect.)

Done ✅

@mgovers
Copy link
Copy Markdown
Author

mgovers commented May 28, 2026

@microsoft-github-policy-service agree company="Alliander"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Status: Initial Review

Development

Successfully merging this pull request may close these issues.

<xutility>: std::find no longer compiles with structs with defaulted equality comparison with Clang-CL

4 participants