Skip to content

Commit 7706945

Browse files
authored
[libc] Work around incorrect fmin/fmax results for +/-x (#83158)
Summary: The IEEE 754 standard as of the 2019 revision states that for fmin -0.0 is always less than 0.0 and for fmax 0.0 is always greater than 0.0. These are currently not respected by the builtin value and thus cause the tests to fail. This patch works around it in the implementation for now by explicitly modifying the sign bit.
1 parent 9106b58 commit 7706945

File tree

9 files changed

+152
-99
lines changed

9 files changed

+152
-99
lines changed

libc/src/math/amdgpu/fmax.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/math/fmax.h"
10+
11+
#include "src/__support/CPP/bit.h"
1012
#include "src/__support/common.h"
13+
#include "src/__support/macros/optimization.h"
1114

1215
namespace LIBC_NAMESPACE {
1316

1417
LLVM_LIBC_FUNCTION(double, fmax, (double x, double y)) {
18+
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
19+
if (LIBC_UNLIKELY(x == y))
20+
return cpp::bit_cast<double>(cpp::bit_cast<uint64_t>(x) &
21+
cpp::bit_cast<uint64_t>(y));
1522
return __builtin_fmax(x, y);
1623
}
1724

libc/src/math/amdgpu/fmaxf.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/math/fmaxf.h"
10+
11+
#include "src/__support/CPP/bit.h"
1012
#include "src/__support/common.h"
13+
#include "src/__support/macros/optimization.h"
1114

1215
namespace LIBC_NAMESPACE {
1316

1417
LLVM_LIBC_FUNCTION(float, fmaxf, (float x, float y)) {
18+
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
19+
if (LIBC_UNLIKELY(x == y))
20+
return cpp::bit_cast<float>(cpp::bit_cast<uint32_t>(x) &
21+
cpp::bit_cast<uint32_t>(y));
1522
return __builtin_fmaxf(x, y);
1623
}
1724

libc/src/math/amdgpu/fmin.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/math/fmin.h"
10+
11+
#include "src/__support/CPP/bit.h"
1012
#include "src/__support/common.h"
13+
#include "src/__support/macros/optimization.h"
1114

1215
namespace LIBC_NAMESPACE {
1316

1417
LLVM_LIBC_FUNCTION(double, fmin, (double x, double y)) {
18+
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
19+
if (LIBC_UNLIKELY(x == y))
20+
return cpp::bit_cast<double>(cpp::bit_cast<uint64_t>(x) |
21+
cpp::bit_cast<uint64_t>(y));
1522
return __builtin_fmin(x, y);
1623
}
1724

libc/src/math/amdgpu/fminf.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/math/fminf.h"
10+
11+
#include "src/__support/CPP/bit.h"
1012
#include "src/__support/common.h"
13+
#include "src/__support/macros/optimization.h"
1114

1215
namespace LIBC_NAMESPACE {
1316

1417
LLVM_LIBC_FUNCTION(float, fminf, (float x, float y)) {
18+
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
19+
if (LIBC_UNLIKELY(x == y))
20+
return cpp::bit_cast<float>(cpp::bit_cast<uint32_t>(x) |
21+
cpp::bit_cast<uint32_t>(y));
1522
return __builtin_fminf(x, y);
1623
}
1724

libc/src/math/nvptx/fmax.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/math/fmax.h"
10+
11+
#include "src/__support/CPP/bit.h"
1012
#include "src/__support/common.h"
13+
#include "src/__support/macros/optimization.h"
1114

1215
namespace LIBC_NAMESPACE {
1316

1417
LLVM_LIBC_FUNCTION(double, fmax, (double x, double y)) {
18+
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
19+
if (LIBC_UNLIKELY(x == y))
20+
return cpp::bit_cast<double>(cpp::bit_cast<uint64_t>(x) &
21+
cpp::bit_cast<uint64_t>(y));
1522
return __builtin_fmax(x, y);
1623
}
1724

libc/src/math/nvptx/fmaxf.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/math/fmaxf.h"
10+
11+
#include "src/__support/CPP/bit.h"
1012
#include "src/__support/common.h"
13+
#include "src/__support/macros/optimization.h"
1114

1215
namespace LIBC_NAMESPACE {
1316

1417
LLVM_LIBC_FUNCTION(float, fmaxf, (float x, float y)) {
18+
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
19+
if (LIBC_UNLIKELY(x == y))
20+
return cpp::bit_cast<float>(cpp::bit_cast<uint32_t>(x) &
21+
cpp::bit_cast<uint32_t>(y));
1522
return __builtin_fmaxf(x, y);
1623
}
1724

libc/src/math/nvptx/fmin.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/math/fmin.h"
10+
11+
#include "src/__support/CPP/bit.h"
1012
#include "src/__support/common.h"
13+
#include "src/__support/macros/optimization.h"
1114

1215
namespace LIBC_NAMESPACE {
1316

1417
LLVM_LIBC_FUNCTION(double, fmin, (double x, double y)) {
18+
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
19+
if (LIBC_UNLIKELY(x == y))
20+
return cpp::bit_cast<double>(cpp::bit_cast<uint64_t>(x) |
21+
cpp::bit_cast<uint64_t>(y));
1522
return __builtin_fmin(x, y);
1623
}
1724

libc/src/math/nvptx/fminf.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/math/fminf.h"
10+
11+
#include "src/__support/CPP/bit.h"
1012
#include "src/__support/common.h"
13+
#include "src/__support/macros/optimization.h"
1114

1215
namespace LIBC_NAMESPACE {
1316

1417
LLVM_LIBC_FUNCTION(float, fminf, (float x, float y)) {
18+
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
19+
if (LIBC_UNLIKELY(x == y))
20+
return cpp::bit_cast<float>(cpp::bit_cast<uint32_t>(x) |
21+
cpp::bit_cast<uint32_t>(y));
1522
return __builtin_fminf(x, y);
1623
}
1724

libc/test/src/math/smoke/CMakeLists.txt

Lines changed: 96 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,112 +1092,109 @@ add_fp_unittest(
10921092
libc.src.__support.FPUtil.fp_bits
10931093
)
10941094

1095-
# FIXME: These tests are currently broken on the GPU.
1096-
if(NOT LIBC_TARGET_OS_IS_GPU)
1097-
add_fp_unittest(
1098-
fminf_test
1099-
SUITE
1100-
libc-math-smoke-tests
1101-
SRCS
1102-
fminf_test.cpp
1103-
HDRS
1104-
FMinTest.h
1105-
DEPENDS
1106-
libc.src.math.fminf
1107-
libc.src.__support.FPUtil.fp_bits
1108-
)
1095+
add_fp_unittest(
1096+
fminf_test
1097+
SUITE
1098+
libc-math-smoke-tests
1099+
SRCS
1100+
fminf_test.cpp
1101+
HDRS
1102+
FMinTest.h
1103+
DEPENDS
1104+
libc.src.math.fminf
1105+
libc.src.__support.FPUtil.fp_bits
1106+
)
11091107

1110-
add_fp_unittest(
1111-
fmin_test
1112-
SUITE
1113-
libc-math-smoke-tests
1114-
SRCS
1115-
fmin_test.cpp
1116-
HDRS
1117-
FMinTest.h
1118-
DEPENDS
1119-
libc.src.math.fmin
1120-
libc.src.__support.FPUtil.fp_bits
1121-
)
1108+
add_fp_unittest(
1109+
fmin_test
1110+
SUITE
1111+
libc-math-smoke-tests
1112+
SRCS
1113+
fmin_test.cpp
1114+
HDRS
1115+
FMinTest.h
1116+
DEPENDS
1117+
libc.src.math.fmin
1118+
libc.src.__support.FPUtil.fp_bits
1119+
)
11221120

1123-
add_fp_unittest(
1124-
fminl_test
1125-
SUITE
1126-
libc-math-smoke-tests
1127-
SRCS
1128-
fminl_test.cpp
1129-
HDRS
1130-
FMinTest.h
1131-
DEPENDS
1132-
libc.src.math.fminl
1133-
libc.src.__support.FPUtil.fp_bits
1134-
)
1121+
add_fp_unittest(
1122+
fminl_test
1123+
SUITE
1124+
libc-math-smoke-tests
1125+
SRCS
1126+
fminl_test.cpp
1127+
HDRS
1128+
FMinTest.h
1129+
DEPENDS
1130+
libc.src.math.fminl
1131+
libc.src.__support.FPUtil.fp_bits
1132+
)
11351133

1136-
add_fp_unittest(
1137-
fminf128_test
1138-
SUITE
1139-
libc-math-smoke-tests
1140-
SRCS
1141-
fminf128_test.cpp
1142-
HDRS
1143-
FMinTest.h
1144-
DEPENDS
1145-
libc.src.math.fminf128
1146-
libc.src.__support.FPUtil.fp_bits
1147-
)
1134+
add_fp_unittest(
1135+
fminf128_test
1136+
SUITE
1137+
libc-math-smoke-tests
1138+
SRCS
1139+
fminf128_test.cpp
1140+
HDRS
1141+
FMinTest.h
1142+
DEPENDS
1143+
libc.src.math.fminf128
1144+
libc.src.__support.FPUtil.fp_bits
1145+
)
11481146

1149-
add_fp_unittest(
1150-
fmaxf_test
1151-
SUITE
1152-
libc-math-smoke-tests
1153-
SRCS
1154-
fmaxf_test.cpp
1155-
HDRS
1156-
FMaxTest.h
1157-
DEPENDS
1158-
libc.src.math.fmaxf
1159-
libc.src.__support.FPUtil.fp_bits
1160-
)
1147+
add_fp_unittest(
1148+
fmaxf_test
1149+
SUITE
1150+
libc-math-smoke-tests
1151+
SRCS
1152+
fmaxf_test.cpp
1153+
HDRS
1154+
FMaxTest.h
1155+
DEPENDS
1156+
libc.src.math.fmaxf
1157+
libc.src.__support.FPUtil.fp_bits
1158+
)
11611159

1162-
add_fp_unittest(
1163-
fmax_test
1164-
SUITE
1165-
libc-math-smoke-tests
1166-
SRCS
1167-
fmax_test.cpp
1168-
HDRS
1169-
FMaxTest.h
1170-
DEPENDS
1171-
libc.src.math.fmax
1172-
libc.src.__support.FPUtil.fp_bits
1173-
)
1160+
add_fp_unittest(
1161+
fmax_test
1162+
SUITE
1163+
libc-math-smoke-tests
1164+
SRCS
1165+
fmax_test.cpp
1166+
HDRS
1167+
FMaxTest.h
1168+
DEPENDS
1169+
libc.src.math.fmax
1170+
libc.src.__support.FPUtil.fp_bits
1171+
)
11741172

1175-
add_fp_unittest(
1176-
fmaxl_test
1177-
SUITE
1178-
libc-math-smoke-tests
1179-
SRCS
1180-
fmaxl_test.cpp
1181-
HDRS
1182-
FMaxTest.h
1183-
DEPENDS
1184-
libc.src.math.fmaxl
1185-
libc.src.__support.FPUtil.fp_bits
1186-
)
1173+
add_fp_unittest(
1174+
fmaxl_test
1175+
SUITE
1176+
libc-math-smoke-tests
1177+
SRCS
1178+
fmaxl_test.cpp
1179+
HDRS
1180+
FMaxTest.h
1181+
DEPENDS
1182+
libc.src.math.fmaxl
1183+
libc.src.__support.FPUtil.fp_bits
1184+
)
11871185

1188-
add_fp_unittest(
1189-
fmaxf128_test
1190-
SUITE
1191-
libc-math-smoke-tests
1192-
SRCS
1193-
fmaxf128_test.cpp
1194-
HDRS
1195-
FMaxTest.h
1196-
DEPENDS
1197-
libc.src.math.fmaxf128
1198-
libc.src.__support.FPUtil.fp_bits
1199-
)
1200-
endif()
1186+
add_fp_unittest(
1187+
fmaxf128_test
1188+
SUITE
1189+
libc-math-smoke-tests
1190+
SRCS
1191+
fmaxf128_test.cpp
1192+
HDRS
1193+
FMaxTest.h
1194+
DEPENDS
1195+
libc.src.math.fmaxf128
1196+
libc.src.__support.FPUtil.fp_bits
1197+
)
12011198

12021199
add_fp_unittest(
12031200
sqrtf_test

0 commit comments

Comments
 (0)