Skip to content

beta distribution clang M1 optimization short-circuit bug #826

@mckib2

Description

@mckib2

xref scipy/scipy#14901

When built with optimization level >1, Clang on Apple M1 platforms appears to generate incorrect code that does not short-circuit the following if statement from igamma_inverse.hpp:

      if((fabs(div) > 1) && (tools::max_value<T>() / fabs(div) < f2))

leading to a floating point exception as the right side will overflow if evaluated. This was observed through the Beta distribution with particular ranges of values (see an example below).

Reproducer built with -O2 on M1 Mac with clang:

% clang --version
Apple clang version 14.0.0 (clang-1400.0.29.102)
Target: arm64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
#include <iostream>
#include <cfenv>

#include "boost/math/distributions/beta.hpp"

#pragma STDC FENV_ACCESS ON

int main() {
    constexpr double q {0.999995};
    constexpr double a {2};
    constexpr double b {99999};
    std::feclearexcept(FE_ALL_EXCEPT);
    boost::math::beta_distribution<double> d {a, b};
    const auto ans = boost::math::quantile(d, q);
    if(std::fetestexcept(FE_OVERFLOW)) {
        std::cout << "overflow reported" << std::endl;
    } else {
        std::cout << "overflow not reported" << std::endl;
    }
    std::cout << std::setprecision(16) << "Ans is: " << ans << std::endl;
    return 0;
}
// overflow reported
// Ans is: 0.000149761910560502

Overflow is not reported when built with -O1 or when building with Mac Intel (or any other platform really).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions