Turn floating-point comparisons into integer comparisons (when the FPU is not available).
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
It is possible to turn floating point comparisons into integer comparisons. For example, turning `x == 1.0f` into `x == 0x3F800000`. Or turning `x >= 1.0f && x < 2.0f` into `x >= 0x3F800000 && x < 0x40000000`.
This would be beneficial for targets without a floating point unit.
Some things to consider include:
- NaN handling
- Signaling NaN handling
- Does comparing to infinity raise flags or etc
- Denormal flushing
- When do `__aeabi_fcmpeq`, `__aeabi_fcmplt`, `__aeabi_fcmpge` have other side effects?
Godbolt: https://godbolt.org/z/z66dzqcsr
Alive2: https://alive2.llvm.org/ce/z/7V58kE
```c
bool src_a(float x) {
return x == 1.0f;
}
bool tgt_a(float x) {
uint32_t bin;
__builtin_memcpy(&bin, &x, sizeof(x));
return bin == UINT32_C(0x3F800000);
}
bool src_b(float x) {
return x >= 1.0f && x < 2.0f;
}
bool tgt_b(float x) {
uint32_t bin;
__builtin_memcpy(&bin, &x, sizeof(x));
return bin >= UINT32_C(0x3F800000) && bin < UINT32_C(0x40000000);
}
bool src_c(float x) {
if (__builtin_isnan(x)) {
__builtin_unreachable();
}
return x < -1.0f;
}
bool tgt_c(float x) {
if (__builtin_isnan(x)) {
__builtin_unreachable();
}
uint32_t bin;
__builtin_memcpy(&bin, &x, sizeof(x));
return bin > UINT32_C(0xBF800000);
}
```
`x == 0.0f` can also be done by doing `x == 0 || x == 0x80000000` or `(x << 1) == 0` or `x == -x` or `(x & 0x7FFFFFFF) == 0`
Contributor guide
Research direction
Run the Godbolt example and Alive2 proof linked in the issue first, then locate the LLVM optimization handling the shown floating-point comparisons. Define and test the transformation against the listed NaN, signaling-NaN, infinity, denormal, and __aeabi_fcmp side-effect cases; done means integer comparisons are emitted only when their semantics are preserved for targets without an FPU.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers, performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100