Skip to content

Commit 7456a1c

Browse files
committed
[libc] Make FPUtils' rounding_mode.h functions constexpr.
1 parent 92c55a3 commit 7456a1c

File tree

2 files changed

+45
-23
lines changed

2 files changed

+45
-23
lines changed

libc/src/__support/FPUtil/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ add_header_library(
1616
rounding_mode.h
1717
DEPENDS
1818
libc.hdr.fenv_macros
19+
libc.src.__support.CPP.type_traits
1920
libc.src.__support.macros.attributes
2021
libc.src.__support.macros.properties.architectures
2122
libc.src.__support.macros.sanitizer

libc/src/__support/FPUtil/rounding_mode.h

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_ROUNDING_MODE_H
1111

1212
#include "hdr/fenv_macros.h"
13+
#include "src/__support/CPP/type_traits.h" // is_constant_evaluated
1314
#include "src/__support/macros/attributes.h" // LIBC_INLINE
1415
#include "src/__support/macros/config.h"
1516

@@ -20,18 +21,26 @@ namespace fputil {
2021
// Using the following observation:
2122
// 1.0f + 2^-25 = 1.0f for FE_TONEAREST, FE_DOWNWARD, FE_TOWARDZERO
2223
// = 0x1.000002f for FE_UPWARD.
23-
LIBC_INLINE bool fenv_is_round_up() {
24-
volatile float x = 0x1.0p-25f;
25-
return (1.0f + x != 1.0f);
24+
LIBC_INLINE static constexpr bool fenv_is_round_up() {
25+
if (cpp::is_constant_evaluated()) {
26+
return false;
27+
} else {
28+
volatile float x = 0x1.0p-25f;
29+
return (1.0f + x != 1.0f);
30+
}
2631
}
2732

2833
// Quick free-standing test whether fegetround() == FE_DOWNWARD.
2934
// Using the following observation:
3035
// -1.0f - 2^-25 = -1.0f for FE_TONEAREST, FE_UPWARD, FE_TOWARDZERO
3136
// = -0x1.000002f for FE_DOWNWARD.
32-
LIBC_INLINE bool fenv_is_round_down() {
33-
volatile float x = 0x1.0p-25f;
34-
return (-1.0f - x != -1.0f);
37+
LIBC_INLINE static constexpr bool fenv_is_round_down() {
38+
if (cpp::is_constant_evaluated()) {
39+
return false;
40+
} else {
41+
volatile float x = 0x1.0p-25f;
42+
return (-1.0f - x != -1.0f);
43+
}
3544
}
3645

3746
// Quick free-standing test whether fegetround() == FE_TONEAREST.
@@ -40,10 +49,14 @@ LIBC_INLINE bool fenv_is_round_down() {
4049
// = 0x1.100002p0f for FE_UPWARD,
4150
// 1.5f - 2^-24 = 1.5f for FE_TONEAREST, FE_UPWARD
4251
// = 0x1.0ffffep-1f for FE_DOWNWARD, FE_TOWARDZERO
43-
LIBC_INLINE bool fenv_is_round_to_nearest() {
44-
static volatile float x = 0x1.0p-24f;
45-
float y = x;
46-
return (1.5f + y == 1.5f - y);
52+
LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() {
53+
if (cpp::is_constant_evaluated()) {
54+
return true;
55+
} else {
56+
volatile float x = 0x1.0p-24f;
57+
float y = 1.5f + x;
58+
return (y == 1.5f - x);
59+
}
4760
}
4861

4962
// Quick free-standing test whether fegetround() == FE_TOWARDZERO.
@@ -56,23 +69,31 @@ LIBC_INLINE bool fenv_is_round_to_nearest() {
5669
// (0x1.000002p0f + 2^-24) + (-1.0f - 2^-24) = 2^-23 for FE_TOWARDZERO
5770
// = 2^-22 for FE_TONEAREST, FE_UPWARD
5871
// = 0 for FE_DOWNWARD
59-
LIBC_INLINE bool fenv_is_round_to_zero() {
60-
static volatile float x = 0x1.0p-24f;
61-
float y = x;
62-
return ((0x1.000002p0f + y) + (-1.0f - y) == 0x1.0p-23f);
72+
LIBC_INLINE static constexpr bool fenv_is_round_to_zero() {
73+
if (cpp::is_constant_evaluated()) {
74+
return false;
75+
} else {
76+
volatile float x = 0x1.0p-24f;
77+
volatile float y = 0x1.000002p0f + x;
78+
return (y + (-1.0f - x) == 0x1.0p-23f);
79+
}
6380
}
6481

6582
// Quick free standing get rounding mode based on the above observations.
66-
LIBC_INLINE int quick_get_round() {
67-
static volatile float x = 0x1.0p-24f;
68-
float y = x;
69-
float z = (0x1.000002p0f + y) + (-1.0f - y);
83+
LIBC_INLINE static constexpr int quick_get_round() {
84+
if (cpp::is_constant_evaluated()) {
85+
return FE_TONEAREST;
86+
} else {
87+
volatile float x = 0x1.0p-24f;
88+
volatile float y = 0x1.000002p0f + x;
89+
float z = y + (-1.0f - x);
7090

71-
if (z == 0.0f)
72-
return FE_DOWNWARD;
73-
if (z == 0x1.0p-23f)
74-
return FE_TOWARDZERO;
75-
return (2.0f + y == 2.0f) ? FE_TONEAREST : FE_UPWARD;
91+
if (z == 0.0f)
92+
return FE_DOWNWARD;
93+
if (z == 0x1.0p-23f)
94+
return FE_TOWARDZERO;
95+
return (2.0f + x == 2.0f) ? FE_TONEAREST : FE_UPWARD;
96+
}
7697
}
7798

7899
} // namespace fputil

0 commit comments

Comments
 (0)