Files
clang-p2996/flang/lib/Optimizer/CodeGen/CodeGen.cpp
Asher Mancinelli 982527eef0 [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.
2025-03-12 08:14:46 -07:00

180 KiB