Inline `(int)float_value` if `-1.0 < float_value < +2.0`
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
It is possible to turn `(int)float_value`/`(unsigned)float_value` into an add and shift if `+0.0 <= float_value < +2.0` and the `float_value` is positive (not negative zero).
Additionally, if `-1.0 < float_value < +2.0`, then all you need to do is to clear the sign-bit to transform it into the `+0.0 <= float_value < +2.0` case.
```c++
int32_t src_a(float x) {
if (__builtin_signbit(x) || x >= 2.0f) {
__builtin_unreachable();
}
return (int32_t)x;
}
// similar trick is possible with bfloat/half/double
int32_t tgt_a(float x) {
if (__builtin_signbit(x) || x >= 2.0f) {
__builtin_unreachable();
}
uint32_t bin;
__builtin_memcpy(&bin, &x, sizeof(x));
bin += 0x00800000;
bin >>= 30;
return (int32_t)bin;
}
int32_t src_b(float x) {
if (x <= -1.0 || x >= 2.0f) {
__builtin_unreachable();
}
return (int32_t)x;
}
// A similar trick is possible with bfloat/half/double.
int32_t tgt_b(float x) {
if (x <= -1.0 || x >= 2.0f) {
__builtin_unreachable();
}
uint32_t bin;
__builtin_memcpy(&bin, &x, sizeof(x));
bin += 0x00800000;
bin &= 0x7FFFFFFF;
bin >>= 30;
return (int32_t)bin;
}
// same as tgt_b
int32_t tgt_c(float x) {
if (x <= -1.0 || x >= 2.0f) {
__builtin_unreachable();
}
uint32_t bin;
__builtin_memcpy(&bin, &x, sizeof(x));
bin += 0x00800000;
bin <<= 1;
bin >>= 31;
return (int32_t)bin;
}
```
Godbolt: https://godbolt.org/z/hs148WMrq
Alive2: https://alive2.llvm.org/ce/z/xBCrXN
This transformation is mostly useful for software floats.
Since this emits 2-3 instructions, I am not sure if it would also be useful for SIMD vectors.
I am not currently aware of real world uses.
Contributor guide
Research direction
Start with the C++ examples and reproduce their current and target code on the linked Godbolt example. Use the Alive2 link to check the proposed transformations, including negative zero and the float, bfloat, half, and double cases. Done means the compiler recognizes the stated ranges and emits the add/shift form without changing semantics.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers, performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100