[Bug fortran/96711] Internal Compiler Error on NINT() Function

2021-07-23 Thread anlauf at gcc dot gnu.org via Gcc-bugs
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

2021-05-20 Thread bernd.eggen at gmail dot com via Gcc-bugs
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

2021-05-20 Thread burnus at gcc dot gnu.org via Gcc-bugs
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

2020-10-07 Thread anlauf at gcc dot gnu.org via Gcc-bugs
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

2020-10-07 Thread schwab--- via Gcc-bugs
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

2020-10-07 Thread kargl at gcc dot gnu.org via Gcc-bugs
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

2020-10-07 Thread schwab--- via Gcc-bugs
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

2020-10-07 Thread sgk at troutmask dot apl.washington.edu via Gcc-bugs
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

2020-10-07 Thread schwab--- via Gcc-bugs
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

2020-09-07 Thread cvs-commit at gcc dot gnu.org
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

2020-08-25 Thread anlauf at gcc dot gnu.org
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

2020-08-20 Thread sgk at troutmask dot apl.washington.edu
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

2020-08-20 Thread bre08 at eggen dot co.uk
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

2020-08-20 Thread sgk at troutmask dot apl.washington.edu
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

2020-08-20 Thread bre08 at eggen dot co.uk
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

2020-08-19 Thread sgk at troutmask dot apl.washington.edu
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

2020-08-19 Thread anlauf at gcc dot gnu.org
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

2020-08-19 Thread toon at moene dot org
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

2020-08-19 Thread anlauf at gcc dot gnu.org
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

2020-08-19 Thread kargl at gcc dot gnu.org
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

2020-08-19 Thread kargl at gcc dot gnu.org
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

2020-08-19 Thread bre08 at eggen dot co.uk
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

2020-08-19 Thread bre08 at eggen dot co.uk
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

2020-08-19 Thread bre08 at eggen dot co.uk
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.