This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4238. simd_mask<complex<double>>::operator+/-/~ return a disabled simd specialization

Section: 29.10.8.4 [simd.mask.unary] Status: New Submitter: Matthias Kretz Opened: 2025-03-27 Last modified: 2025-03-29

Priority: Not Prioritized

View all issues with New status.

Discussion:

Consider:

simd<complex<double>> c = {};
simd_mask<complex<double>> k = (c == c); // sizeof(complex<double>) == 16
auto i = -k; // simd<__int128> !

basic_simd_mask unary +, -, and ~ return basic_simd<integer-from<Bytes, Abi>>. 29.10.2.1 [simd.expos.defn]/2 says:

integer-from<Bytes> is an alias for a signed integer type T such that sizeof(T) equals Bytes.

But __int128 isn't a vectorizable type. Consequently, simd<__int128> currently is a disabled specialization. So it seems simd<complex<double>> wants __int128 to be added to the list of vectorizable types.

Options:

  1. "Specialize" basic_simd_mask<16, Abi> to return rebind_t<integer-from<8>, basic_simd_mask<integer-from<16>, Abi>> (reduces a 128-bit value of a vector-mask to a 64-bit value in the simd)

  2. "Specialize" basic_simd_mask<16, Abi> to return resize_t<size() * 2, rebind_t<integer-from<8>, basic_simd_mask<integer-from<16>, Abi>>> (duplicates a 128-bit value of a vector-mask to two 64-bit values in the simd)

  3. delete unary +, -, and ~ for basic_simd_mask<16, Abi> (closest to the status quo)

Proposed resolution:

This wording is relative to N5008.

  1. Modify 29.10.8.4 [simd.mask.unary] as indicated:

    constexpr basic_simd_mask operator!() const noexcept;
    constexpr basic_simd<integer-from<Bytes>, Abi> operator+() const noexcept;
    constexpr basic_simd<integer-from<Bytes>, Abi> operator-() const noexcept;
    constexpr basic_simd<integer-from<Bytes>, Abi> operator~() const noexcept;
    

    -1- Let op be the operator.

    -2- Returns: A data-parallel object where the ith element is initialized to the results of applying op to operator[](i) for all i in the range of [0, size()).

    -?- Remarks: If Bytes is greater than 8, operator+(), operator-(), and operator~() are deleted.