C++ Logo

std-proposals

Advanced search

Re: [std-proposals] D3666R0 Bit-precise integers

From: Bjorn Reese <breese_at_[hidden]>
Date: Sun, 7 Sep 2025 16:01:58 +0200
On 9/4/25 23:02, David Brown via Std-Proposals wrote:

> No, you have not. What you have shown is that in code that does not use
> bool types, you may or may not need casts, depending on how the types
> you use are defined.

That is only the case if the type has the appropriate conversion
operators or converting constructors. std::simd does so, but not
other types do not. There are types that uses overloading instead of
conversion, and they will not work when adding explicit casts.

Consider SWAR (software-emulated SIMD) types and the max0() function
I listed earlier.

   template <typename T>
   T max0(T x) {
      // max(0, x)
      return x * (x > T(0));
   }

The relational operators return a mask type that holds multiple results.
These are not bit-masks, but an "array" of unsigned values where each
element is either 0 (all zeros) or ~0 (all ones.) The multiplication of
T and its mask type is therefore basically a bitwise-and. This is
normally implemented using operator overloading of T and its mask type.

Suppose we add a converting constructor and insert an explicit cast in
the above code. Normally explicit casts adds useful type information,
but in this case it removes useful type information. A SWAR
multiplication is so complicated that compilers do not optimize the
above code to the desired bitwise-and. This is not simply a missed
optimization opportunity; the generated code attempting to do N parallel
operations is even slower than doing N sequential operations, which
eliminates the reason for doing SWAR to begin with. For that reason
there are SWAR types without converting constructors to ensure that the
proper overloads are used.

Received on 2025-09-07 14:02:02