[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 anlauf at gcc dot gnu.org changed: What|Removed |Added Status|ASSIGNED|NEW Assignee|anlauf at gcc dot gnu.org |unassigned at gcc dot gnu.org
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #23 from bernd.eggen at gmail dot com --- Many thanks Tobias, noted - bw, Bernd On Thu, 20 May 2021 at 09:12, burnus at gcc dot gnu.org < [email protected]> wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 > > Tobias Burnus changed: > >What|Removed |Added > > > CC||burnus at gcc dot gnu.org > > --- Comment #22 from Tobias Burnus --- > (In reply to anlauf from comment #21) > > Please see PR96983 for the fallout. > > Note: That fallout PR is now fixed (at least for GCC 12, one of the three > patches might still need backporting to GCC 11). > > -- > You are receiving this mail because: > You are on the CC list for the bug. > You reported the bug.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 Tobias Burnus changed: What|Removed |Added CC||burnus at gcc dot gnu.org --- Comment #22 from Tobias Burnus --- (In reply to anlauf from comment #21) > Please see PR96983 for the fallout. Note: That fallout PR is now fixed (at least for GCC 12, one of the three patches might still need backporting to GCC 11).
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #21 from anlauf at gcc dot gnu.org --- Please see PR96983 for the fallout. Note that my bandaid fix was rejected in favor of a "real solution" for powerpc*. See the other PR and the Fortran ML for background.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #20 from Andreas Schwab --- Any ICE is a bug.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #19 from kargl at gcc dot gnu.org --- (In reply to Andreas Schwab from comment #18) > Any ICE is a bug. If powerpc64 does not have REAL(16), then you'll need to xfail the test.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #18 from Andreas Schwab --- Any ICE is a bug.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #17 from Steve Kargl --- On Wed, Oct 07, 2020 at 07:19:18AM +, [email protected] wrote: > > --- Comment #16 from Andreas Schwab --- > On powerpc64: > > FAIL: gfortran.dg/pr96711.f90 -O0 (internal compiler error) > FAIL: gfortran.dg/pr96711.f90 -O0 (test for excess errors) > Excess errors: > f951: internal compiler error: Could not find real kind with at least 128 bits > If powerpc64 does not have REAL(16), then you'll need to xfail the test.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #16 from Andreas Schwab --- On powerpc64: FAIL: gfortran.dg/pr96711.f90 -O0 (internal compiler error) FAIL: gfortran.dg/pr96711.f90 -O0 (test for excess errors) Excess errors: f951: internal compiler error: Could not find real kind with at least 128 bits
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #15 from CVS Commits --- The master branch has been updated by Harald Anlauf : https://gcc.gnu.org/g:9164caf25cb210ad0a69357b226e39913aff00d1 commit r11-3042-g9164caf25cb210ad0a69357b226e39913aff00d1 Author: Harald Anlauf Date: Mon Sep 7 21:41:45 2020 +0200 PR fortran/96711 - ICE with NINT() for integer(16) result When rounding a real to the nearest integer, temporarily convert the real argument to a longer real kind when the result is of type/kind integer(16). gcc/fortran/ChangeLog: * trans-intrinsic.c (build_round_expr): Use temporary with appropriate kind for conversion before rounding to nearest integer when the result precision is 128 bits. gcc/testsuite/ChangeLog: * gfortran.dg/pr96711.f90: New test.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 anlauf at gcc dot gnu.org changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |anlauf at gcc dot gnu.org Status|NEW |ASSIGNED Priority|P3 |P4 --- Comment #14 from anlauf at gcc dot gnu.org --- Patch: https://gcc.gnu.org/pipermail/fortran/2020-August/054920.html
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #13 from Steve Kargl --- On Thu, Aug 20, 2020 at 03:54:44PM +, bre08 at eggen dot co.uk wrote: > > PS (and maybe I need to post this separately as a suggestion) - will > there be a fast "octuple-precision floating point / integer" library > (i.e. 256 bit) for C, C++ and Fortran, or is using something like > GMP the only way forward ? I'm not aware of any effort to offer an octuple-precision library. If you need this level of accuracy, then you probably want to use David Bailey's libraries or GMP/MPFR.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #12 from B Eggen --- Thanks for your explanations, and for reminding me of the excellent library etc by David Bailey. My original quest was to have a fast method to decide for large integers quickly whether they are perfect squares. I prob need to do something different to avoid the rounding pitfalls (:-) PS (and maybe I need to post this separately as a suggestion) - will there be a fast "octuple-precision floating point / integer" library (i.e. 256 bit) for C, C++ and Fortran, or is using something like GMP the only way forward ? BW, Bernd
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #11 from Steve Kargl --- On Thu, Aug 20, 2020 at 01:47:58PM +, bre08 at eggen dot co.uk wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 > > --- Comment #10 from B Eggen --- > I've been experimenting with the suggested work-around > > m = anint(y) > > This works for larger numbers, even in quad precision, however, it breaks down > a long way before the integer*16 range is exhausted, consider the code below, > which starts with 2^113 and tries to double it, minus 1. The minus 1 is not > taking effect: > Of course, that is going to fail if you want an exact result. REAL(16) is a floating point format, which has 113 digits of precision. This means that integers less than 2**113 are exactly representable as REAL(16) floating point numbers. When you double (2._16)**113 to (2._16)**114, that is a prefectly fine REAL(16) floating point number. Subtracting 1._16 from (2._16)**114 is a valid floating point operation. Your problem lies in that result is rounded, and 1._16 is less than epsilon(1._16) in comparison to (2._16)**114. > I guess at some point NINT() will be fixed, can anyone suggest a robust > workaround that is valid until 2^127-1 ? If you're trying to use floating point arithmetic in computations and you need exact integral values up to 2**127-1, then there isn't a REAL type that works. If you're looking for arbitrary precision arithmetic and you want to use Fortran, I suggest that you google "David Bailey arithmetic".
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #10 from B Eggen --- I've been experimenting with the suggested work-around m = anint(y) This works for larger numbers, even in quad precision, however, it breaks down a long way before the integer*16 range is exhausted, consider the code below, which starts with 2^113 and tries to double it, minus 1. The minus 1 is not taking effect: -> ./aint_working.e 10384593717069655257060992658440192.00 the next two lines should end in ...83 20769187434139310514121985316880384.00 20769187434139310514121985316880384.00 20769187434139310514121985316880383 The source code is: program aint_working ! does not work in quad precision (real*16) ! -> echo '2^113' | bc = 10384593717069655257060992658440192 ! -> echo '2^114' | bc = 20769187434139310514121985316880384 integer(kind=16) :: i, j, k integer, parameter :: idp=selected_real_kind(9,99) integer, parameter :: iqp=selected_real_kind(19,199) integer, parameter :: i16=selected_int_kind(38) real(kind=iqp) :: x, y, z x=10384593717069655257060992658440192.0q0 ! that is 2^113 i=10384593717069655257060992658440192_16 ! as above, but integer k=20769187434139310514121985316880384_16 ! that is 2^114 write(*,'(1x,f50.10)') x write(*,*) 'the next two lines should end in ...83' write(*,*) y=(x+x)-1.0q0 write(*,'(1x,f50.10)') y z=(x-1.0q0)+x ! see if this helps write(*,'(1x,f50.10)') z j=(i+i)-1_16 write(*,*) write(*,'(1x,i39)') j ! this is correct result (2^114-1) stop end program aint_working I guess at some point NINT() will be fixed, can anyone suggest a robust workaround that is valid until 2^127-1 ? Thanks, Bernd
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711
--- Comment #9 from Steve Kargl ---
On Wed, Aug 19, 2020 at 09:36:32PM +, anlauf at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711
>
> --- Comment #8 from anlauf at gcc dot gnu.org ---
> A very quick hack seems to solve the issue for me. For some reason the
> final fold_convert seems to create a problem. Does anybody know why?
> It there a shorter solution?
>
> diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
> index 2483f016d8e..deb3030b75d 100644
> --- a/gcc/fortran/trans-intrinsic.c
> +++ b/gcc/fortran/trans-intrinsic.c
> @@ -395,11 +395,26 @@ build_round_expr (tree arg, tree restype)
> fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec);
>else if (resprec <= LONG_LONG_TYPE_SIZE)
> fn = builtin_decl_for_precision (BUILT_IN_LLROUND, argprec);
> + else if (resprec >= argprec && resprec == 128)
> +{
> + /* Search for a real kind suitable as temporary for conversion. */
> + int kind = -1;
> + for (int i = 0; kind < 0 && gfc_real_kinds[i].kind != 0; i++)
> + if (gfc_real_kinds[i].mode_precision >= resprec)
> + kind = gfc_real_kinds[i].kind;
> + if (kind < 0)
> + gfc_internal_error ("Could not find real kind with at least %d bits",
> + resprec);
> + arg = fold_convert (gfc_float128_type_node, arg);
> + fn = gfc_builtin_decl_for_float_kind (BUILT_IN_ROUND, kind);
> +}
>else
> gcc_unreachable ();
>
> - return fold_convert (restype, build_call_expr_loc (input_location,
> -fn, 1, arg));
> + return convert (restype, build_call_expr_loc (input_location,
> + fn, 1, arg));
> + /* return fold_convert (restype, build_call_expr_loc (input_location, */
> + /*fn, 1, arg)); */
> }
I tried an even uglier hack, and also got stumped by GIMPLE.
Jakub can probably shed some light on how to handle
quad precision and GIMPLE.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711
--- Comment #8 from anlauf at gcc dot gnu.org ---
A very quick hack seems to solve the issue for me. For some reason the
final fold_convert seems to create a problem. Does anybody know why?
It there a shorter solution?
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 2483f016d8e..deb3030b75d 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -395,11 +395,26 @@ build_round_expr (tree arg, tree restype)
fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec);
else if (resprec <= LONG_LONG_TYPE_SIZE)
fn = builtin_decl_for_precision (BUILT_IN_LLROUND, argprec);
+ else if (resprec >= argprec && resprec == 128)
+{
+ /* Search for a real kind suitable as temporary for conversion. */
+ int kind = -1;
+ for (int i = 0; kind < 0 && gfc_real_kinds[i].kind != 0; i++)
+ if (gfc_real_kinds[i].mode_precision >= resprec)
+ kind = gfc_real_kinds[i].kind;
+ if (kind < 0)
+ gfc_internal_error ("Could not find real kind with at least %d bits",
+ resprec);
+ arg = fold_convert (gfc_float128_type_node, arg);
+ fn = gfc_builtin_decl_for_float_kind (BUILT_IN_ROUND, kind);
+}
else
gcc_unreachable ();
- return fold_convert (restype, build_call_expr_loc (input_location,
-fn, 1, arg));
+ return convert (restype, build_call_expr_loc (input_location,
+ fn, 1, arg));
+ /* return fold_convert (restype, build_call_expr_loc (input_location, */
+ /*fn, 1, arg)); */
}
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 Toon Moene changed: What|Removed |Added CC||toon at moene dot org --- Comment #7 from Toon Moene --- *** Bug 96712 has been marked as a duplicate of this bug. ***
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 anlauf at gcc dot gnu.org changed: What|Removed |Added CC||anlauf at gcc dot gnu.org --- Comment #6 from anlauf at gcc dot gnu.org --- (In reply to kargl from comment #5) > m = anint(y) > > This will use libquadmath to round y to a quad precision > floating point integral number, and then the rounded value > will assigned to m where type conversion occurs. gfc_conv_intrinsic_aint has the following comment: /* Round a real value using the specified rounding mode. We use a temporary integer of that same kind size as the result. ... This seems not to be done in gfc_conv_intrinsic_int, which is invoked for nint.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #5 from kargl at gcc dot gnu.org --- Trivial workaround. program nint_error implicit none integer(kind=16) :: m real(8) :: x, y x = 1 y = x - 1 m = anint(y) print *, m end This will use libquadmath to round y to a quad precision floating point integral number, and then the rounded value will assigned to m where type conversion occurs.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
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.000 2147483647 33 4294967296 4294967296.000 -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.
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #3 from B Eggen --- 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
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 --- Comment #2 from B Eggen --- adding the compiler flag -fdefault-integer-8 extends the range somewhat, but I really require NINT() to work for whole range (up to 2^127-1): -> ./nint_error.e i16= 16 170141183460469231731687303715884105727 1 1 1. 0 2 2 2. 1 3 4 4. 3 4 8 8. 7 5 16 16.000 15 6 32 32.000 31 [...] 61 1152921504606846976 0.11529215046068470E+019 1152921504606846976 62 2305843009213693952 0.23058430092136940E+019 2305843009213693952 63 4611686018427387904 0.46116860184273879E+019 4611686018427387904 64 9223372036854775808 0.92233720368547758E+019 -9223372036854775808
[Bug fortran/96711] Internal Compiler Error on NINT() Function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 B Eggen changed: What|Removed |Added CC||bre08 at eggen dot co.uk --- Comment #1 from B Eggen --- Comment on attachment 49082 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49082 This recreates the error, either the internal compiler error (line 18), or, if the previous line is activated instead, the incorrect behaviour For some reason an older f90 file was attached, even with m moved to the line below, the error continues to exist.
