https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711
kargl at gcc dot gnu.org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |kargl at gcc dot gnu.org
Ever confirmed|0 |1
Last reconfirmed| |2020-08-19
Status|UNCONFIRMED |NEW
--- Comment #4 from kargl at gcc dot gnu.org ---
(In reply to B Eggen from comment #3)
> Here is the latest f90 file:
>
> program nint_error
>
> integer :: n, m
> integer(kind=16) :: i, j, nint
>
> integer, parameter :: idp=selected_real_kind(9,99)
> integer, parameter :: i16=selected_int_kind(38)
>
> real(kind=idp) :: x, y
>
> write(*,'(*(g0:" "))') 'i16=', i16, huge(i)
> i=1_16
> x=1.0d0
> do n=1, 128, 1
> j=i-1_16
> y=x-1.0d0
> m=nint(y) ! this compiles, but gives wrong results
> ! m=nint(y,i16) ! this will generate an internal compiler error
> write(*,'(*(g0:" "))') n, i, x, m
> i=i+i
> x=x+x
> if ( (m<1) .and. (n>3)) exit
> end do
>
> do i=2147483647_16-10_16, 2147483648_16+10_16, 1_16
> x=dble(i)
> m=nint(x)
> write(*,'(*(g0:" "))') i, x, m
> end do
>
>
> stop
> end program nint_error
It is somewhat hard to decipher what the problem. You have conflated
correct behavior with that of an apparent. First,
m = nint(y)
will return a default integer. From 16.9.141
Result Characteristics. Integer. If KIND is present, the kind type
parameter is that specified by the value of KIND; otherwise, the
kind type parameter is that of default integer type.
on your target the default integer kind is 4 (i.e., a 32-bit signed
integer). This means that
32 2147483648 2147483648.0000000 2147483647
33 4294967296 4294967296.0000000 -1
your program becomes nonconforming for n = 33. The Fortran standard
contains
A program shall not invoke an intrinsic procedure under circumstances
where a value to be assigned to a subroutine argument or returned as
a function result is not representable by objects of the specified
type and type parameters.
The function result of 4294967296 is technically not representable
(except that you're getting twos-complement wrap around).
As to your observation about IDNINT. It is a specific name for
the generic intrinsic NINT. It has one double precision argument.
It does not have a kind argument.
Now, onto the bug. It can be distilled down to
program nint_error
implicit none
integer(kind=16) :: m
real(8) :: x, y
x = 1
y = x - 1
m = nint(y,16)
end program nint_error
% gfcx -o z a.f90 && ./z
a.f90:9:0:
9 | m = nint(y,16)
|
internal compiler error: in build_round_expr, at fortran/trans-intrinsic.c:396
0x5bd9fa build_round_expr
../../gccx/gcc/fortran/trans-intrinsic.c:396
0x5bd9fa build_fix_expr
../../gccx/gcc/fortran/trans-intrinsic.c:420
0x8c7bf2 gfc_conv_intrinsic_int
../../gccx/gcc/fortran/trans-intrinsic.c:550
It would seem that a fold_convert to an appropriate kind is missing.