Skip to content

GH-51492: [C++] Do not left shift a bpacking lane by its full width - #51493

Open
domibel wants to merge 1 commit into
apache:mainfrom
domibel:bpacking-portable-lshift
Open

domibel wants to merge 1 commit into
apache:mainfrom
domibel:bpacking-portable-lshift

Conversation

@domibel

@domibel domibel commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Rationale for this change

When a packed value starts on a byte boundary its high part contributes nothing, but LargeKernelPlan::Build still asks for a left shift, and on 8 bit lanes that shift is the whole lane width. Some backends saturate and give zero, others use the low bits of the shift amount and return the lane unchanged, so its bits survive the mask.

So affected values decode incorrectly with no error reported, that can lead to silent data corruption.

What changes are included in this PR?

Point the high swizzle back at the low byte instead and set the shift to zero. So the plan never asks for the shift at all.

This is a compile-time change to the kernel plan. The emitted kernel is unchanged.

Are these changes tested?

Yes
I also added a new assert that fails to compile on main.

Are there any user-facing changes?

No

Was AI used for this PR?

PR code and description written by:

  • Human
  • AI

Reviewed before submission by:

  • Human
  • AI
  • Not reviewed

@github-actions github-actions Bot added the awaiting review Awaiting review label Sep 25, 2026
@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #51492 has been automatically assigned in GitHub to PR creator.

@domibel

domibel commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

FYI, I stumbled upon this while working on xtensor-stack/xsimd#1417.

…idth

When a packed value starts on a byte boundary its high part contributes
nothing, but LargeKernelPlan::Build still asks for a left shift, and on 8 bit
lanes that shift is the whole lane width. Some backends saturate and give
zero, others use the low bits of the shift amount and return the lane
unchanged, so its bits survive the mask.

Point the high swizzle back at the low byte instead and set the shift to zero.

The emitted kernel is unchanged and arrow-bpacking-benchmark shows no
difference.
@domibel
domibel force-pushed the bpacking-portable-lshift branch from 4a0f393 to 40cd578 Compare September 25, 2026 04:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant