https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118984

--- Comment #17 from Maxim Egorushkin <maxim.yegorushkin at gmail dot com> ---
More example code. The assembly outputs are available at
https://godbolt.org/z/74YGKbM1j

#include <type_traits>

template<class T> concept S = std::is_arithmetic_v<T>;
template<class T, int...>  struct V;
template<S T, int n_bytes> struct V<T, n_bytes> { typedef T type
__attribute__((__vector_size__(n_bytes))); };
template<S T, int n_elem>  struct V<T[n_elem]> : V<T, sizeof(T[n_elem])> {};
template<class T, int... I> using vector_t = V<T, I...>::type;

using v2df = vector_t<double[2]>; // aka __v2df in <immintrin.h>
using v4df = vector_t<double[4]>; // aka __v4df in <immintrin.h>

// Non-ideal machine code with anything.
double horizontal_sum_naive_cxx14(v4df v) noexcept {
    return v[0] + v[1] + v[2] + v[3];
}

// Same as above, with C++17 structured bindings.
// Non-ideal machine code with anything.
double horizontal_sum_naive(v4df v4) noexcept {
    auto [a, b, c, d] = v4;
    return a + b + c + d;
}

// Ideal machine code with clang-20.
// Non-ideal machine code with gcc-14.
double horizontal_sum_naive2(v4df v4) noexcept {
    auto [a, b, c, d] = v4;
    return (a + c) + (b + d);
}

// Ideal machine code with clang-20.
// 2x superflous vmovapd with gcc-14:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118984
double horizontal_sum_naive3(v4df v4) noexcept {
    auto [a, b] = v2df{v4[0], v4[1]} + v2df{v4[2], v4[3]};
    return a + b; 
}

// Ideal machine code with clang-20.
// Ideal machine code with gcc-14.
double horizontal_sum_ideal_asm(v4df v4) noexcept {
    auto [a, b] = v2df{v4[2], v4[3]} + v2df{v4[0], v4[1]};
    return b + a;
}

Reply via email to