aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorAsher Mancinelli <ashermancinelli@gmail.com>2025-03-12 08:14:46 -0700
committerGitHub <noreply@github.com>2025-03-12 08:14:46 -0700
commit982527eef0f284161dd5e09a9b4fc952b332ec92 (patch)
tree558a2c54520c71c21bd490e67aef7ece49735ca6 /clang/lib/CodeGen/CodeGenModule.cpp
parent8be1d1235d58d5b2711295dbd9b36abe4b2401d0 (diff)
downloadllvm-982527eef0f284161dd5e09a9b4fc952b332ec92.zip
llvm-982527eef0f284161dd5e09a9b4fc952b332ec92.tar.gz
llvm-982527eef0f284161dd5e09a9b4fc952b332ec92.tar.bz2
[flang] Use saturated intrinsics for floating point to integer conversions (#130686)
The saturated floating point conversion intrinsics match the semantics in the standard more closely than the fptosi/fptoui instructions. Case 2 of 16.9.100 is > INT (A [, KIND]) > If A is of type real, there are two cases: if |A| < 1, INT (A) has the value 0; if |A| ≥ 1, INT (A) is the integer whose magnitude is the largest integer that does not exceed the magnitude of A and whose sign is the same as the sign of A. Currently, converting a floating point value into an integer type too small to hold the constant will be converted to poison in opt, leaving us with garbage: ``` > cat t.f90 program main real(kind=16) :: f integer(kind=4) :: i f=huge(f) i=f print *, i end program main # current upstream > for i in `seq 10`; do; ./a.out; done -862156992 -1497393344 -739096768 -1649494208 1761228608 -1959270592 -746244288 -1629194432 -231217344 382322496 ``` With the saturated fptoui/fptosi intrinsics, we get the appropriate values ``` # mine > flang -O2 ./t.f90 && ./a.out 2147483647 > perl -e 'printf "%d\n", (2 ** 31) - 1' 2147483647 ``` One notable difference: NaNs being converted to ints will become zero, unlike current flang (and some other compilers). Newer versions of GCC have this behavior.
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
0 files changed, 0 insertions, 0 deletions