llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.84k stars 11.47k forks source link

[compiler-rt] __truncXfYf2 functions ignore the current rounding mode and always round to nearest, ties to even #100413

Open overmighty opened 1 month ago

overmighty commented 1 month ago

https://godbolt.org/z/dchq7rxe7

C code:

#include <fenv.h>
#include <stdio.h>

_Float16 bar(float x) {
  return (_Float16)x;
}

int main() {
  volatile float x = 0x1.0p-25f;
  fesetround(FE_UPWARD);
  printf("%a\n", (double)bar(x));
  fesetround(FE_DOWNWARD);
  printf("%a\n", (double)bar(x));
}

Output with libgcc:

0x1p-24
0x0p+0

Output with compiler-rt:

0x0p+0
0x0p+0

Relevant compiler-rt source:

https://github.com/llvm/llvm-project/blob/046a17717d9c5b5385ecd914621b48bdd91524d0/compiler-rt/lib/builtins/truncsfhf2.c#L15-L17

https://github.com/llvm/llvm-project/blob/046a17717d9c5b5385ecd914621b48bdd91524d0/compiler-rt/lib/builtins/fp_trunc_impl.inc#L9-L12

cc @lntue

llvmbot commented 1 month ago

@llvm/issue-subscribers-libc

Author: OverMighty (overmighty)

https://godbolt.org/z/dchq7rxe7 C code: ```c #include <fenv.h> #include <stdio.h> _Float16 bar(float x) { return (_Float16)x; } int main() { volatile float x = 0x1.0p-25f; fesetround(FE_UPWARD); printf("%a\n", (double)bar(x)); fesetround(FE_DOWNWARD); printf("%a\n", (double)bar(x)); } ``` Output with libgcc: ``` 0x1p-24 0x0p+0 ``` Output with compiler-rt: ``` 0x0p+0 0x0p+0 ``` Relevant compiler-rt source: https://github.com/llvm/llvm-project/blob/046a17717d9c5b5385ecd914621b48bdd91524d0/compiler-rt/lib/builtins/truncsfhf2.c#L15-L17 https://github.com/llvm/llvm-project/blob/046a17717d9c5b5385ecd914621b48bdd91524d0/compiler-rt/lib/builtins/fp_trunc_impl.inc#L9-L12 cc @lntue
overmighty commented 1 month ago

Added libc label as this impacts development of LLVM libc math functions.

jhuber6 commented 3 weeks ago

Isn't it undefined to change the fpenv without setting #pragma STDC FENV_ACCESS?