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; }
