summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@google.com>2021-03-05 12:19:32 -0500
committerGravatar Benjamin Barenblat <bbaren@google.com>2021-03-05 12:19:32 -0500
commit0159f87cfaf679f55bcc99f375a772ea3374d272 (patch)
treecadea424b91ebdf52e2b2a0c0932717f4f0f91a3
parent006b28a982e3938d29952341a2ebdeae77b42b16 (diff)
Disable double-double unit tests
Compiler bugs make unit tests flaky on double-double platforms. Apply a patch from upstream to disable the relevant tests on those platforms.
-rw-r--r--debian/changelog1
-rw-r--r--debian/patches/disable-double-double-tests.diff489
-rw-r--r--debian/patches/series1
3 files changed, 491 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
index e3f4e909..500ef137 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,7 @@ abseil (0~20200923.3-3) UNRELEASED; urgency=medium
* Fix "ftbfs with -march=x86-64-v3" by correcting the relevant unit
tests. (Closes: #983936)
+ * Disable double-double unit tests due to compiler bugs.
-- Benjamin Barenblat <bbaren@debian.org> Thu, 04 Mar 2021 14:37:45 -0500
diff --git a/debian/patches/disable-double-double-tests.diff b/debian/patches/disable-double-double-tests.diff
new file mode 100644
index 00000000..e80a8a78
--- /dev/null
+++ b/debian/patches/disable-double-double-tests.diff
@@ -0,0 +1,489 @@
+From: Benjamin Barenblat <bbaren@google.com>
+Subject: Stop testing with double-double random variables
+Forwarded: yes
+Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/ab21820d47e4f83875dda008b600514d3520fd35
+
+On POWER, long double is often represented as a pair of doubles added
+together (double-double arithmetic). We’ve already special-cased
+double-double arithmetic in a number of tests, but compiler
+bugs [1, 2, 3] have now triggered both false positives and false
+negatives, which suggests testing with double doubles is unlikely to
+yield useful signal. Remove the special casing and detect if we’re on a
+double-double system; if so, just don’t test long doubles.
+
+[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048
+[2] https://bugs.llvm.org/show_bug.cgi?id=49131
+[3] https://bugs.llvm.org/show_bug.cgi?id=49132
+
+The author works at Google. Upstream applied this patch as Piper
+revision 360793161 and exported it to GitHub; the the Applied-Upstream
+URL above points to the exported commit.
+
+--- a/CMake/AbseilDll.cmake
++++ b/CMake/AbseilDll.cmake
+@@ -126,6 +126,7 @@ set(ABSL_INTERNAL_DLL_FILES
+ "meta/type_traits.h"
+ "numeric/int128.cc"
+ "numeric/int128.h"
++ "numeric/internal/representation.h"
+ "random/bernoulli_distribution.h"
+ "random/beta_distribution.h"
+ "random/bit_gen_ref.h"
+--- a/absl/numeric/BUILD.bazel
++++ b/absl/numeric/BUILD.bazel
+@@ -72,3 +72,15 @@
+ "@com_github_google_benchmark//:benchmark_main",
+ ],
+ )
++
++cc_library(
++ name = "representation",
++ hdrs = [
++ "internal/representation.h",
++ ],
++ copts = ABSL_DEFAULT_COPTS,
++ linkopts = ABSL_DEFAULT_LINKOPTS,
++ deps = [
++ "//absl/base:config",
++ ],
++)
+--- a/absl/numeric/CMakeLists.txt
++++ b/absl/numeric/CMakeLists.txt
+@@ -59,3 +59,15 @@
+ absl::int128
+ PUBLIC
+ )
++
++absl_cc_library(
++ NAME
++ numeric_representation
++ HDRS
++ "internal/representation.h"
++ COPTS
++ ${ABSL_DEFAULT_COPTS}
++ DEPS
++ absl::config
++ PUBLIC
++)
+--- /dev/null
++++ b/absl/numeric/internal/representation.h
+@@ -0,0 +1,55 @@
++// Copyright 2021 The Abseil Authors
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// https://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++
++#ifndef ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_
++#define ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_
++
++#include <limits>
++
++#include "absl/base/config.h"
++
++namespace absl {
++ABSL_NAMESPACE_BEGIN
++namespace numeric_internal {
++
++// Returns true iff long double is represented as a pair of doubles added
++// together.
++inline constexpr bool IsDoubleDouble() {
++ // A double-double value always has exactly twice the precision of a double
++ // value--one double carries the high digits and one double carries the low
++ // digits. This property is not shared with any other common floating-point
++ // representation, so this test won't trigger false positives. For reference,
++ // this table gives the number of bits of precision of each common
++ // floating-point representation:
++ //
++ // type precision
++ // IEEE single 24 b
++ // IEEE double 53
++ // x86 long double 64
++ // double-double 106
++ // IEEE quadruple 113
++ //
++ // Note in particular that a quadruple-precision float has greater precision
++ // than a double-double float despite taking up the same amount of memory; the
++ // quad has more of its bits allocated to the mantissa than the double-double
++ // has.
++ return std::numeric_limits<long double>::digits ==
++ 2 * std::numeric_limits<double>::digits;
++}
++
++} // namespace numeric_internal
++ABSL_NAMESPACE_END
++} // namespace absl
++
++#endif // ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_
+--- a/absl/random/BUILD.bazel
++++ b/absl/random/BUILD.bazel
+@@ -187,6 +187,7 @@ cc_test(name = "beta_distribution_test",
+ ":distributions",
+ ":random",
+ "//absl/base:raw_logging_internal",
++ "//absl/numeric:representation",
+ "//absl/random/internal:distribution_test_util",
+ "//absl/random/internal:pcg_engine",
+ "//absl/random/internal:sequence_urbg",
+@@ -307,6 +308,7 @@ cc_test(name = "exponential_distribution_test",
+ ":random",
+ "//absl/base:core_headers",
+ "//absl/base:raw_logging_internal",
++ "//absl/numeric:representation",
+ "//absl/random/internal:distribution_test_util",
+ "//absl/random/internal:pcg_engine",
+ "//absl/random/internal:sequence_urbg",
+@@ -330,6 +332,7 @@ cc_test(name = "gaussian_distribution_test",
+ ":random",
+ "//absl/base:core_headers",
+ "//absl/base:raw_logging_internal",
++ "//absl/numeric:representation",
+ "//absl/random/internal:distribution_test_util",
+ "//absl/random/internal:sequence_urbg",
+ "//absl/strings",
+@@ -376,6 +379,7 @@ cc_test(name = "uniform_real_distribution_test",
+ ":distributions",
+ ":random",
+ "//absl/base:raw_logging_internal",
++ "//absl/numeric:representation",
+ "//absl/random/internal:distribution_test_util",
+ "//absl/random/internal:pcg_engine",
+ "//absl/random/internal:sequence_urbg",
+--- a/absl/random/CMakeLists.txt
++++ b/absl/random/CMakeLists.txt
+@@ -259,6 +259,7 @@ absl_cc_test(NAME random_beta_distribution_test
+ LINKOPTS
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
++ absl::numeric_representation
+ absl::random_distributions
+ absl::random_random
+ absl::random_internal_distribution_test_util
+@@ -381,6 +382,7 @@ absl_cc_test(NAME random_exponential_distribution_test
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
+ absl::core_headers
++ absl::numeric_representation
+ absl::random_distributions
+ absl::random_internal_distribution_test_util
+ absl::random_internal_pcg_engine
+@@ -404,6 +406,7 @@ absl_cc_test(NAME random_gaussian_distribution_test
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
+ absl::core_headers
++ absl::numeric_representation
+ absl::random_distributions
+ absl::random_internal_distribution_test_util
+ absl::random_internal_sequence_urbg
+@@ -446,6 +449,7 @@ absl_cc_test(NAME random_uniform_real_distribution_test
+ LINKOPTS
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
++ absl::numeric_representation
+ absl::random_distributions
+ absl::random_internal_distribution_test_util
+ absl::random_internal_pcg_engine
+--- a/absl/random/beta_distribution_test.cc
++++ b/absl/random/beta_distribution_test.cc
+@@ -21,12 +21,14 @@
+ #include <random>
+ #include <sstream>
+ #include <string>
++#include <type_traits>
+ #include <unordered_map>
+ #include <vector>
+
+ #include "gmock/gmock.h"
+ #include "gtest/gtest.h"
+ #include "absl/base/internal/raw_logging.h"
++#include "absl/numeric/internal/representation.h"
+ #include "absl/random/internal/chi_square.h"
+ #include "absl/random/internal/distribution_test_util.h"
+ #include "absl/random/internal/pcg_engine.h"
+@@ -42,7 +44,15 @@
+ template <typename IntType>
+ class BetaDistributionInterfaceTest : public ::testing::Test {};
+
+-using RealTypes = ::testing::Types<float, double, long double>;
++// double-double arithmetic is not supported well by either GCC or Clang; see
++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
++// https://bugs.llvm.org/show_bug.cgi?id=49131, and
++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
++// with double doubles until compiler support is better.
++using RealTypes =
++ std::conditional<absl::numeric_internal::IsDoubleDouble(),
++ ::testing::Types<float, double>,
++ ::testing::Types<float, double, long double>>::type;
+ TYPED_TEST_CASE(BetaDistributionInterfaceTest, RealTypes);
+
+ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest) {
+@@ -53,9 +63,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest {
+ const TypeParam kLargeA =
+ std::exp(std::log((std::numeric_limits<TypeParam>::max)()) -
+ std::log(std::log((std::numeric_limits<TypeParam>::max)())));
+- const TypeParam kLargeAPPC = std::exp(
+- std::log((std::numeric_limits<TypeParam>::max)()) -
+- std::log(std::log((std::numeric_limits<TypeParam>::max)())) - 10.0f);
+ using param_type = typename absl::beta_distribution<TypeParam>::param_type;
+
+ constexpr int kCount = 1000;
+@@ -76,9 +83,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest {
+ kLargeA, //
+ std::nextafter(kLargeA, TypeParam(0)), //
+ std::nextafter(kLargeA, std::numeric_limits<TypeParam>::max()),
+- kLargeAPPC, //
+- std::nextafter(kLargeAPPC, TypeParam(0)),
+- std::nextafter(kLargeAPPC, std::numeric_limits<TypeParam>::max()),
+ // Boundary cases.
+ std::numeric_limits<TypeParam>::max(),
+ std::numeric_limits<TypeParam>::epsilon(),
+@@ -125,28 +129,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest {
+
+ ss >> after;
+
+-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
+- defined(__ppc__) || defined(__PPC__)
+- if (std::is_same<TypeParam, long double>::value) {
+- // Roundtripping floating point values requires sufficient precision
+- // to reconstruct the exact value. It turns out that long double
+- // has some errors doing this on ppc.
+- if (alpha <= std::numeric_limits<double>::max() &&
+- alpha >= std::numeric_limits<double>::lowest()) {
+- EXPECT_EQ(static_cast<double>(before.alpha()),
+- static_cast<double>(after.alpha()))
+- << ss.str();
+- }
+- if (beta <= std::numeric_limits<double>::max() &&
+- beta >= std::numeric_limits<double>::lowest()) {
+- EXPECT_EQ(static_cast<double>(before.beta()),
+- static_cast<double>(after.beta()))
+- << ss.str();
+- }
+- continue;
+- }
+-#endif
+-
+ EXPECT_EQ(before.alpha(), after.alpha());
+ EXPECT_EQ(before.beta(), after.beta());
+ EXPECT_EQ(before, after) //
+--- a/absl/random/exponential_distribution_test.cc
++++ b/absl/random/exponential_distribution_test.cc
+@@ -30,6 +30,7 @@
+ #include "gtest/gtest.h"
+ #include "absl/base/internal/raw_logging.h"
+ #include "absl/base/macros.h"
++#include "absl/numeric/internal/representation.h"
+ #include "absl/random/internal/chi_square.h"
+ #include "absl/random/internal/distribution_test_util.h"
+ #include "absl/random/internal/pcg_engine.h"
+@@ -50,7 +51,15 @@
+ #if defined(__EMSCRIPTEN__)
+ using RealTypes = ::testing::Types<float, double>;
+ #else
+-using RealTypes = ::testing::Types<float, double, long double>;
++// double-double arithmetic is not supported well by either GCC or Clang; see
++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
++// https://bugs.llvm.org/show_bug.cgi?id=49131, and
++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
++// with double doubles until compiler support is better.
++using RealTypes =
++ std::conditional<absl::numeric_internal::IsDoubleDouble(),
++ ::testing::Types<float, double>,
++ ::testing::Types<float, double, long double>>::type;
+ #endif // defined(__EMSCRIPTEN__)
+ TYPED_TEST_CASE(ExponentialDistributionTypedTest, RealTypes);
+
+@@ -130,23 +139,6 @@ TYPED_TEST(ExponentialDistributionTypedTest, SerializeTest) {
+
+ ss >> after;
+
+-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
+- defined(__ppc__) || defined(__PPC__)
+- if (std::is_same<TypeParam, long double>::value) {
+- // Roundtripping floating point values requires sufficient precision to
+- // reconstruct the exact value. It turns out that long double has some
+- // errors doing this on ppc, particularly for values
+- // near {1.0 +/- epsilon}.
+- if (lambda <= std::numeric_limits<double>::max() &&
+- lambda >= std::numeric_limits<double>::lowest()) {
+- EXPECT_EQ(static_cast<double>(before.lambda()),
+- static_cast<double>(after.lambda()))
+- << ss.str();
+- }
+- continue;
+- }
+-#endif
+-
+ EXPECT_EQ(before.lambda(), after.lambda()) //
+ << ss.str() << " " //
+ << (ss.good() ? "good " : "") //
+--- a/absl/random/gaussian_distribution_test.cc
++++ b/absl/random/gaussian_distribution_test.cc
+@@ -21,12 +21,14 @@
+ #include <iterator>
+ #include <random>
+ #include <string>
++#include <type_traits>
+ #include <vector>
+
+ #include "gmock/gmock.h"
+ #include "gtest/gtest.h"
+ #include "absl/base/internal/raw_logging.h"
+ #include "absl/base/macros.h"
++#include "absl/numeric/internal/representation.h"
+ #include "absl/random/internal/chi_square.h"
+ #include "absl/random/internal/distribution_test_util.h"
+ #include "absl/random/internal/sequence_urbg.h"
+@@ -43,7 +45,15 @@
+ template <typename RealType>
+ class GaussianDistributionInterfaceTest : public ::testing::Test {};
+
+-using RealTypes = ::testing::Types<float, double, long double>;
++// double-double arithmetic is not supported well by either GCC or Clang; see
++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
++// https://bugs.llvm.org/show_bug.cgi?id=49131, and
++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
++// with double doubles until compiler support is better.
++using RealTypes =
++ std::conditional<absl::numeric_internal::IsDoubleDouble(),
++ ::testing::Types<float, double>,
++ ::testing::Types<float, double, long double>>::type;
+ TYPED_TEST_CASE(GaussianDistributionInterfaceTest, RealTypes);
+
+ TYPED_TEST(GaussianDistributionInterfaceTest, SerializeTest) {
+@@ -129,32 +139,6 @@ TYPED_TEST(GaussianDistributionInterfaceTest, SerializeTest) {
+
+ ss >> after;
+
+-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
+- defined(__ppc__) || defined(__PPC__) || defined(__EMSCRIPTEN__)
+- if (std::is_same<TypeParam, long double>::value) {
+- // Roundtripping floating point values requires sufficient precision
+- // to reconstruct the exact value. It turns out that long double
+- // has some errors doing this on ppc, particularly for values
+- // near {1.0 +/- epsilon}.
+- //
+- // Emscripten is even worse, implementing long double as a 128-bit
+- // type, but shipping with a strtold() that doesn't support that.
+- if (mean <= std::numeric_limits<double>::max() &&
+- mean >= std::numeric_limits<double>::lowest()) {
+- EXPECT_EQ(static_cast<double>(before.mean()),
+- static_cast<double>(after.mean()))
+- << ss.str();
+- }
+- if (stddev <= std::numeric_limits<double>::max() &&
+- stddev >= std::numeric_limits<double>::lowest()) {
+- EXPECT_EQ(static_cast<double>(before.stddev()),
+- static_cast<double>(after.stddev()))
+- << ss.str();
+- }
+- continue;
+- }
+-#endif
+-
+ EXPECT_EQ(before.mean(), after.mean());
+ EXPECT_EQ(before.stddev(), after.stddev()) //
+ << ss.str() << " " //
+--- a/absl/random/uniform_real_distribution_test.cc
++++ b/absl/random/uniform_real_distribution_test.cc
+@@ -20,11 +20,13 @@
+ #include <random>
+ #include <sstream>
+ #include <string>
++#include <type_traits>
+ #include <vector>
+
+ #include "gmock/gmock.h"
+ #include "gtest/gtest.h"
+ #include "absl/base/internal/raw_logging.h"
++#include "absl/numeric/internal/representation.h"
+ #include "absl/random/internal/chi_square.h"
+ #include "absl/random/internal/distribution_test_util.h"
+ #include "absl/random/internal/pcg_engine.h"
+@@ -58,7 +60,15 @@
+ #if defined(__EMSCRIPTEN__)
+ using RealTypes = ::testing::Types<float, double>;
+ #else
+-using RealTypes = ::testing::Types<float, double, long double>;
++// double-double arithmetic is not supported well by either GCC or Clang; see
++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
++// https://bugs.llvm.org/show_bug.cgi?id=49131, and
++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
++// with double doubles until compiler support is better.
++using RealTypes =
++ std::conditional<absl::numeric_internal::IsDoubleDouble(),
++ ::testing::Types<float, double>,
++ ::testing::Types<float, double, long double>>::type;
+ #endif // defined(__EMSCRIPTEN__)
+
+ TYPED_TEST_SUITE(UniformRealDistributionTest, RealTypes);
+--- a/absl/strings/BUILD.bazel
++++ b/absl/strings/BUILD.bazel
+@@ -645,6 +645,7 @@ cc_library(name = "str_format_internal",
+ "//absl/functional:function_ref",
+ "//absl/meta:type_traits",
+ "//absl/numeric:int128",
++ "//absl/numeric:representation",
+ "//absl/types:optional",
+ "//absl/types:span",
+ ],
+--- a/absl/strings/CMakeLists.txt
++++ b/absl/strings/CMakeLists.txt
+@@ -396,6 +396,7 @@ absl_cc_library(NAME str_format_internal
+ absl::strings
+ absl::config
+ absl::core_headers
++ absl::numeric_representation
+ absl::type_traits
+ absl::int128
+ absl::span
+--- a/absl/strings/internal/str_format/float_conversion.cc
++++ b/absl/strings/internal/str_format/float_conversion.cc
+@@ -15,6 +15,7 @@
+ #include "absl/functional/function_ref.h"
+ #include "absl/meta/type_traits.h"
+ #include "absl/numeric/int128.h"
++#include "absl/numeric/internal/representation.h"
+ #include "absl/strings/numbers.h"
+ #include "absl/types/optional.h"
+ #include "absl/types/span.h"
+@@ -25,6 +26,8 @@
+
+ namespace {
+
++using ::absl::numeric_internal::IsDoubleDouble;
++
+ // The code below wants to avoid heap allocations.
+ // To do so it needs to allocate memory on the stack.
+ // `StackArray` will allocate memory on the stack in the form of a uint32_t
+@@ -98,13 +101,6 @@
+ return next_carry % divisor;
+ }
+
+-constexpr bool IsDoubleDouble() {
+- // This is the `double-double` representation of `long double`.
+- // We do not handle it natively. Fallback to snprintf.
+- return std::numeric_limits<long double>::digits ==
+- 2 * std::numeric_limits<double>::digits;
+-}
+-
+ using MaxFloatType =
+ typename std::conditional<IsDoubleDouble(), double, long double>::type;
+
+@@ -1391,6 +1387,8 @@
+ bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv,
+ FormatSinkImpl *sink) {
+ if (IsDoubleDouble()) {
++ // This is the `double-double` representation of `long double`. We do not
++ // handle it natively. Fallback to snprintf.
+ return FallbackToSnprintf(v, conv, sink);
+ }
+
diff --git a/debian/patches/series b/debian/patches/series
index c07c5a22..efe60449 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -8,3 +8,4 @@ endian-hash.diff
endian-random.diff
ppc-float-conversion.diff
fma-contraction.diff
+disable-double-double-tests.diff