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

            Bug ID: 109029
           Summary: std::signbit(double) generiert sehr ineffizienten code
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: g.peterh...@t-online.de
  Target Milestone: ---

Hallo,
std::signbit(double) generiert sehr ineffizienten code und kann somit nicht
vektorisiert werden (https://godbolt.org/z/se6Ea8bo9).

thx
Gero

-std=c++20 -march=x86-64-v3 -O3 -mno-vzeroupper

#include <cmath>
#include <array>
#include <numbers>
#include <algorithm>

static constexpr size_t Size = 1024;

using float80_t = long double;
using float64_t = double;
using float32_t = float;

template <typename Type>
inline constexpr bool   foo(const Type x)   noexcept
{
    return std::signbit(x);
}

template <typename Type>
inline constexpr Type   bar(const Type x)   noexcept
{
   return std::signbit(x) ? std::numbers::pi_v<Type> : 0;
}

template <typename Container, typename Function>
inline constexpr void for_all(Container& cnt, Function&& f)     noexcept
{
        std::transform(cnt.begin(), cnt.end(), cnt.begin(), f);
}

template <typename ContainerRes, typename ContainerArg, typename Function>
inline constexpr void for_all(ContainerRes& res, const ContainerArg& arg,
Function&& f) noexcept
{
        std::transform(arg.begin(), arg.end(), res.begin(), f);
}

float64_t foo64(const float64_t x)   noexcept { return foo(x); }
float32_t foo32(const float32_t x)   noexcept { return foo(x); }

float64_t bar64(const float64_t x)   noexcept { return bar(x); }
float32_t bar32(const float32_t x)   noexcept { return bar(x); }

void foos64(std::array<bool, Size>& res, const std::array<float64_t, Size>&
arg)   noexcept { for_all(res, arg, foo<float64_t>); }
void foos32(std::array<bool, Size>& res, const std::array<float32_t, Size>&
arg)   noexcept { for_all(res, arg, foo<float32_t>); }

void bars64(std::array<float64_t, Size>& cnt)   noexcept { for_all(cnt,
bar<float64_t>); }
void bars32(std::array<float32_t, Size>& cnt)   noexcept { for_all(cnt,
bar<float32_t>); }

Reply via email to