Skip floating-point edge-case tests when using an x87
authorBenjamin Barenblat <bbaren@google.com>
Fri, 27 May 2022 20:58:38 +0000 (21:58 +0100)
committerBenjamin Barenblat <bbaren@debian.org>
Fri, 27 May 2022 20:58:38 +0000 (21:58 +0100)
Forwarded: yes
Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/311bbd2e50ea35e921a08186840d3b6ca279e880

32-bit Intel CPUs use 80-bit floats for intermediate values, which can
change the results of floating point computations from what we normally
expect. Identify tests that are sensitive to the x87, and skip them when
we’re on 32-bit Intel.

The author works at Google. Upstream applied this patch as Piper
revision 378722613 and exported it to GitHub; the Applied-Upstream URL
above points to the exported commit.

Gbp-Pq: Name float-tests-disable-i386.diff

absl/random/beta_distribution_test.cc
absl/random/distributions_test.cc
absl/random/exponential_distribution_test.cc
absl/random/uniform_real_distribution_test.cc
absl/time/duration_test.cc

index 44cdfdd0499d99ebabfdeb1ac234038f8297ac30..d980c969f7f1f6cc7cce7c85362ed2f326f1c2a5 100644 (file)
@@ -15,6 +15,7 @@
 #include "absl/random/beta_distribution.h"
 
 #include <algorithm>
+#include <cfloat>
 #include <cstddef>
 #include <cstdint>
 #include <iterator>
@@ -558,6 +559,14 @@ TEST(BetaDistributionTest, StabilityTest) {
 // dependencies of the distribution change, such as RandU64ToDouble, then this
 // is also likely to change.
 TEST(BetaDistributionTest, AlgorithmBounds) {
+#if (defined(__i386__) || defined(_M_IX86)) && FLT_EVAL_METHOD != 0
+  // We're using an x87-compatible FPU, and intermediate operations are
+  // performed with 80-bit floats. This produces slightly different results from
+  // what we expect below.
+  GTEST_SKIP()
+      << "Skipping the test because we detected x87 floating-point semantics";
+#endif
+
   {
     absl::random_internal::sequence_urbg urbg(
         {0x7fbe76c8b4395800ull, 0x8000000000000000ull});
index 5866a07257e58b88f4526d73f4020706a444233c..d3a5dd75e57b79956c9d477b83d4f27c9a259fce 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "absl/random/distributions.h"
 
+#include <cfloat>
 #include <cmath>
 #include <cstdint>
 #include <random>
@@ -224,6 +225,15 @@ TEST_F(RandomDistributionsTest, UniformNoBounds) {
 TEST_F(RandomDistributionsTest, UniformNonsenseRanges) {
   // The ranges used in this test are undefined behavior.
   // The results are arbitrary and subject to future changes.
+
+#if (defined(__i386__) || defined(_M_IX86)) && FLT_EVAL_METHOD != 0
+  // We're using an x87-compatible FPU, and intermediate operations can be
+  // performed with 80-bit floats. This produces slightly different results from
+  // what we expect below.
+  GTEST_SKIP()
+      << "Skipping the test because we detected x87 floating-point semantics";
+#endif
+
   absl::InsecureBitGen gen;
 
   // <uint>
index af11d61c156dc0da871da27a1cf906c55aa444e2..81a5d17bac6ebb329fd332edc0e11c160613a420 100644 (file)
@@ -15,6 +15,7 @@
 #include "absl/random/exponential_distribution.h"
 
 #include <algorithm>
+#include <cfloat>
 #include <cmath>
 #include <cstddef>
 #include <cstdint>
@@ -384,6 +385,15 @@ TEST(ExponentialDistributionTest, StabilityTest) {
 TEST(ExponentialDistributionTest, AlgorithmBounds) {
   // Relies on absl::uniform_real_distribution, so some of these comments
   // reference that.
+
+#if (defined(__i386__) || defined(_M_IX86)) && FLT_EVAL_METHOD != 0
+  // We're using an x87-compatible FPU, and intermediate operations can be
+  // performed with 80-bit floats. This produces slightly different results from
+  // what we expect below.
+  GTEST_SKIP()
+      << "Skipping the test because we detected x87 floating-point semantics";
+#endif
+
   absl::exponential_distribution<double> dist;
 
   {
index 18bcd3bce8852e31363df643b3d6efb5e73d804b..035bd284d18fb46e772643132ac21f38ec999719 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "absl/random/uniform_real_distribution.h"
 
+#include <cfloat>
 #include <cmath>
 #include <cstdint>
 #include <iterator>
@@ -70,6 +71,14 @@ using RealTypes =
 TYPED_TEST_SUITE(UniformRealDistributionTest, RealTypes);
 
 TYPED_TEST(UniformRealDistributionTest, ParamSerializeTest) {
+#if (defined(__i386__) || defined(_M_IX86)) && FLT_EVAL_METHOD != 0
+  // We're using an x87-compatible FPU, and intermediate operations are
+  // performed with 80-bit floats. This produces slightly different results from
+  // what we expect below.
+  GTEST_SKIP()
+      << "Skipping the test because we detected x87 floating-point semantics";
+#endif
+
   using param_type =
       typename absl::uniform_real_distribution<TypeParam>::param_type;
 
index a3617e744ae456a21769aca9c36bd4248f57db16..b7209e1c0afd282cf44b3e49682041ead936f5d9 100644 (file)
@@ -17,6 +17,7 @@
 #endif
 
 #include <chrono>  // NOLINT(build/c++11)
+#include <cfloat>
 #include <cmath>
 #include <cstdint>
 #include <ctime>
@@ -1390,6 +1391,14 @@ void VerifyApproxSameAsMul(double time_as_seconds, int* const misses) {
 // Seconds(point) returns a duration near point * Seconds(1.0). (They may
 // not be exactly equal due to fused multiply/add contraction.)
 TEST(Duration, ToDoubleSecondsCheckEdgeCases) {
+#if (defined(__i386__) || defined(_M_IX86)) && FLT_EVAL_METHOD != 0
+  // We're using an x87-compatible FPU, and intermediate operations can be
+  // performed with 80-bit floats. This means the edge cases are different than
+  // what we expect here, so just skip this test.
+  GTEST_SKIP()
+      << "Skipping the test because we detected x87 floating-point semantics";
+#endif
+
   constexpr uint32_t kTicksPerSecond = absl::time_internal::kTicksPerSecond;
   constexpr auto duration_tick = absl::time_internal::MakeDuration(0, 1u);
   int misses = 0;