Skip to content

[WIP] Bug in count_if for AVX-512: fall back to popcount where the int ABI does not exist - #56

Open
ax3l wants to merge 1 commit into
mattkretz:masterfrom
ax3l:fix-count_if-wide-abi
Open

[WIP] Bug in count_if for AVX-512: fall back to popcount where the int ABI does not exist#56
ax3l wants to merge 1 commit into
mattkretz:masterfrom
ax3l:fix-count_if-wide-abi

Conversation

@ax3l

@ax3l ax3l commented Aug 26, 2026

Copy link
Copy Markdown

Heads up: this is a Claude-written attempt at fixing the red GCC jobs. It is tested as described below, but please review it as such — the fallback changes how count_if accumulates on the affected configurations.

count_if accumulates one int per element:

using IV = detail::deduced_simd<int, TV::size()>;

which needs an int simd with as many lanes as the value type's. That ABI stops existing once TV is wider than simd_abi::max_fixed_size<int> allows — simd<char> is 64 lanes on AVX-512 and max_fixed_size<int> is 32, so deduce<int, 64> has no type and the function fails to substitute:

simd_execution.h:1506: error: no type named 'type' in 'struct simd_abi::deduce<int, 64>'

This reaches anyone calling count_if over a char range on an AVX-512 host. It also turned CI red on GCC 13 and 14 with nothing in the tree having changed: the testsuite builds -march=native, and the runner fleet moved to AVX-512 capable hardware.

Counting the bits of each mask instead when that ABI is unavailable. count_if already does exactly this where the lane counts do not line up, so this reuses the existing fallback rather than adding a second way to count.

Testing

  • GCC 13, -march=skylake-avx512: for_each.cc compiles clean for char, short, int, float and double. Before, char failed.
  • Correctness of the fallback checked by forcing it for every case (if constexpr (true)) at the native ISA so it actually executes: for_each passes 32/32.
  • Unforced, the ext testsuite passes 96/96, so the per-lane accumulator is unchanged where it exists.

Only char is affected at AVX-512. Separate from #55, which pins the Clang jobs below AVX-512 for an unrelated libstdc++ bug.

count_if accumulates one int per element:

  using IV = detail::deduced_simd<int, TV::size()>;

which needs an int simd as wide in lanes as the value type's. That ABI
stops existing once TV has more lanes than simd_abi::max_fixed_size<int>
allows. simd<char> is 64 lanes on AVX-512 and max_fixed_size<int> is 32,
so deduce<int, 64> has no type and the whole function fails to
substitute:

  simd_execution.h:1506: error: no type named 'type' in
                         'struct simd_abi::deduce<int, 64>'

It reaches anyone calling count_if over a char range on an AVX-512 host,
and it turned CI red on GCC 13 and 14 without a commit to blame, since
the testsuite builds -march=native and the runners moved to AVX-512
capable hardware.

Count the bits of each mask instead when that ABI is unavailable. The
function already does exactly this where the lane counts do not line up,
so the fallback is the existing one rather than a new way to count.

Only char is affected at AVX-512; short, int, float and double keep the
per-lane accumulator.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@ax3l ax3l changed the title count_if: fall back to popcount where the int ABI does not exist [WIP] Bug in count_if: fall back to popcount where the int ABI does not exist Aug 26, 2026
@ax3l ax3l changed the title [WIP] Bug in count_if: fall back to popcount where the int ABI does not exist [WIP] Bug in count_if: fall back to popcount where the int ABI does not exist Aug 26, 2026
@ax3l ax3l changed the title [WIP] Bug in count_if: fall back to popcount where the int ABI does not exist [WIP] Bug in count_if for AVX-512: fall back to popcount where the int ABI does not exist Aug 26, 2026
ax3l added a commit to ax3l/vir-simd that referenced this pull request Aug 26, 2026
The Clang jobs were not the only ones the runner fleet moved under.
simd_abi::max_fixed_size<int> is 32, so an AVX-512 simd<char>, which has
64 lanes, has no int ABI to match it. Two of the tests walk into that:

  for_each.cc     count_if wants deduced_simd<int, 64>, which has no type
  transform.cc    widening char to int asks for simd<int, fixed_size<64>>,
                  whose destructor libstdc++ deletes

transform fails the same way on GCC 11, 12 and 13, so this is not one
version's bug. And because the fleet is mixed, whether a job saw any of
it came down to which machine it landed on: GCC 11 passed one run and
failed the next on an unchanged tree.

Pin these jobs the same way, so what CI covers stops depending on the
runner. The AVX-512 coverage this gives up was never dependable -- where
a runner did offer it, these tests did not compile.

Fixing the algorithms is worthwhile separately; count_if is mattkretz#56. This is
only about CI reporting something reproducible.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant