[llvm-bugs] [Bug 51143] New: Strange likely, unlikely work, bad auto in lambda

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Jul 20 06:31:59 PDT 2021


https://bugs.llvm.org/show_bug.cgi?id=51143

            Bug ID: 51143
           Summary: Strange likely, unlikely work, bad auto in lambda
           Product: clang
           Version: 12.0
          Hardware: PC
                OS: FreeBSD
            Status: NEW
          Keywords: build-problem, compile-fail
          Severity: normal
          Priority: P
         Component: C++2a
          Assignee: unassignedclangbugs at nondot.org
          Reporter: mathleonid at gmail.com
                CC: blitzrakete at gmail.com, erik.pilkington at gmail.com,
                    llvm-bugs at lists.llvm.org, richard-llvm at metafoo.co.uk

The example from cppreference:
#include <chrono>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <random>

namespace with_attributes {
constexpr double pow(double x, long long n) noexcept {
    if (n > 0) [[likely]]
        return x * pow(x, n - 1);
    else [[unlikely]]
        return 1;
}
constexpr long long fact(long long n) noexcept {
    if (n > 1) [[likely]]
        return n * fact(n - 1);
    else [[unlikely]]
        return 1;
}
constexpr double cos(double x) noexcept {
    constexpr long long precision{16LL};
    double y{};
    for (auto n{0LL}; n < precision; n += 2LL) {
        [[likely]] y += pow(x, n) / (n & 2LL ? -fact(n) : fact(n));
    }
    return y;
}
}  // namespace with_attributes

namespace no_attributes {
constexpr double pow(double x, long long n) noexcept {
    if (n > 0)
        return x * pow(x, n - 1);
    else
        return 1;
}
constexpr long long fact(long long n) noexcept {
    if (n > 1)
        return n * fact(n - 1);
    else
        return 1;
}
constexpr double cos(double x) noexcept {
    constexpr long long precision{16LL};
    double y{};
    for (auto n{0LL}; n < precision; n += 2LL) {
        y += pow(x, n) / (n & 2LL ? -fact(n) : fact(n));
    }
    return y;
}
}  // namespace no_attributes

double gen_random() noexcept {
    static std::random_device rd;
    static std::mt19937 gen(rd());
    static std::uniform_real_distribution<double> dis(-1.0, 1.0);
    return dis(gen);
}

volatile double sink{}; // ensures a side effect

int main() {
    for (const auto x : {0.125, 0.25, 0.5, 1. / (2 << 25)}) {
        std::cout
            << std::setprecision(53)
            << "x = " << x << '\n'
            << std::cos(x) << '\n'
            << with_attributes::cos(x) << '\n'
            << (std::cos(x) == with_attributes::cos(x) ? "equal" : "differ") <<
'\n';
    }

    auto benchmark = [](auto fun, auto rem) {
        const auto start = std::chrono::high_resolution_clock::now();
        for (auto size{1ULL}; size != 10'000'000ULL; ++size) {
            sink = fun(gen_random());
        }
        const std::chrono::duration<double> diff =
            std::chrono::high_resolution_clock::now() - start;
        std::cout << "Time: " << std::fixed << std::setprecision(6) <<
diff.count()
                  << " sec " << rem << std::endl;
    };

    benchmark(with_attributes::cos, "(with attributes:)");
    benchmark(no_attributes::cos, "(without attributes)");
    benchmark(cos, "(std::cos)");
}
Cannot be compiled: constexpr with likely/inlikely does not work properly, cos
cannot be passed to benchmark (but with_atributes::cos or no_attributes::cos
can be).

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210720/a97c0ba2/attachment.html>


More information about the llvm-bugs mailing list