Modify scalar pzero, ptrue, pselect, and p<binary> operations to avoid UB.

The memset function and bitwise manipulation only apply to POD types that do not require initialization, otherwise resulting in UB. We currently violate this in ptrue and pzero, we assume bitmasks for pselect, and bitwise operations are applied byte-by-byte in the generic implementations.

This is causing issues for scalar types that do require initialization or that contain non-POD info such as pointers (#2201 (closed)). We either break them, or force specializations of these functions for custom scalars, even if they are not vectorized.

Here we modify these functions for scalars only - instead using only scalar operations:

  • pzero: Scalar(0) for all scalars.
  • ptrue: Scalar(1) for non-trivial scalars, bitset to one bits for trivial scalars.
  • pselect: ternary select comparing mask to Scalar(0) for all scalars
  • pand, por, pxor, pnot: use operators &, |, ^, ~ for all integer or non-trivial scalars, otherwise apply bytewise.

For non-scalar types, the original implementations are used to maintain compatibility and minimize the number of changes.

Fixes #2201 (closed).

Merge request reports

Loading