[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-03-04 Thread tkoenig at gcc dot gnu dot org


--- Comment #15 from tkoenig at gcc dot gnu dot org  2007-03-04 08:03 
---
Subject: Bug 30981

Author: tkoenig
Date: Sun Mar  4 08:03:34 2007
New Revision: 122522

URL: http://gcc.gnu.org/viewcvs?root=gccview=revrev=122522
Log:
2007-03-04  Thomas Koenig  [EMAIL PROTECTED]

PR libfortran/30981
* m4/pow_m4: Use appropriate unsigned int type for u.
* generated/pow_c10_i16.c: Regenerated.
* generated/pow_c10_i4.c: Regenerated.
* generated/pow_c10_i8.c: Regenerated.
* generated/pow_c16_i16.c: Regenerated.
* generated/pow_c16_i4.c: Regenerated.
* generated/pow_c16_i8.c: Regenerated.
* generated/pow_c4_i16.c: Regenerated.
* generated/pow_c4_i4.c: Regenerated.
* generated/pow_c4_i8.c: Regenerated.
* generated/pow_c8_i16.c: Regenerated.
* generated/pow_c8_i4.c: Regenerated.
* generated/pow_c8_i8.c: Regenerated.
* generated/pow_i16_i16.c: Regenerated.
* generated/pow_i16_i4.c: Regenerated.
* generated/pow_i16_i8.c: Regenerated.
* generated/pow_i4_i16.c: Regenerated.
* generated/pow_i4_i4.c: Regenerated.
* generated/pow_i4_i8.c: Regenerated.
* generated/pow_i8_i16.c: Regenerated.
* generated/pow_i8_i4.c: Regenerated.
* generated/pow_i8_i8.c: Regenerated.
* generated/pow_r10_i16.c: Regenerated.
* generated/pow_r10_i4.c: Regenerated.
* generated/pow_r10_i8.c: Regenerated.
* generated/pow_r16_i16.c: Regenerated.
* generated/pow_r16_i4.c: Regenerated.
* generated/pow_r16_i8.c: Regenerated.
* generated/pow_r4_i16.c: Regenerated.
* generated/pow_r4_i4.c: Regenerated.
* generated/pow_r4_i8.c: Regenerated.
* generated/pow_r8_i16.c: Regenerated.
* generated/pow_r8_i4.c: Regenerated.
* generated/pow_r8_i8.c: Regenerated.

2007-03-04  Thomas Koenig  [EMAIL PROTECTED]

PR libfortran/30981
* gfortran.dg/integer_exponentiation_1.f90:  New test.


Added:
trunk/gcc/testsuite/gfortran.dg/integer_exponentiation_1.f90
Modified:
trunk/gcc/testsuite/ChangeLog
trunk/libgfortran/ChangeLog
trunk/libgfortran/generated/pow_c10_i16.c
trunk/libgfortran/generated/pow_c10_i4.c
trunk/libgfortran/generated/pow_c10_i8.c
trunk/libgfortran/generated/pow_c16_i16.c
trunk/libgfortran/generated/pow_c16_i4.c
trunk/libgfortran/generated/pow_c16_i8.c
trunk/libgfortran/generated/pow_c4_i16.c
trunk/libgfortran/generated/pow_c4_i4.c
trunk/libgfortran/generated/pow_c4_i8.c
trunk/libgfortran/generated/pow_c8_i16.c
trunk/libgfortran/generated/pow_c8_i4.c
trunk/libgfortran/generated/pow_c8_i8.c
trunk/libgfortran/generated/pow_i16_i16.c
trunk/libgfortran/generated/pow_i16_i4.c
trunk/libgfortran/generated/pow_i16_i8.c
trunk/libgfortran/generated/pow_i4_i16.c
trunk/libgfortran/generated/pow_i4_i4.c
trunk/libgfortran/generated/pow_i4_i8.c
trunk/libgfortran/generated/pow_i8_i16.c
trunk/libgfortran/generated/pow_i8_i4.c
trunk/libgfortran/generated/pow_i8_i8.c
trunk/libgfortran/generated/pow_r10_i16.c
trunk/libgfortran/generated/pow_r10_i4.c
trunk/libgfortran/generated/pow_r10_i8.c
trunk/libgfortran/generated/pow_r16_i16.c
trunk/libgfortran/generated/pow_r16_i4.c
trunk/libgfortran/generated/pow_r16_i8.c
trunk/libgfortran/generated/pow_r4_i16.c
trunk/libgfortran/generated/pow_r4_i4.c
trunk/libgfortran/generated/pow_r4_i8.c
trunk/libgfortran/generated/pow_r8_i16.c
trunk/libgfortran/generated/pow_r8_i4.c
trunk/libgfortran/generated/pow_r8_i8.c
trunk/libgfortran/m4/pow.m4


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981



[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-03-01 Thread tkoenig at gcc dot gnu dot org


--- Comment #14 from tkoenig at gcc dot gnu dot org  2007-03-01 19:43 
---
At least this is not a regression wrt g77.

Interestingly enough, the following program sends g77 into
a tailspin of increasing memory usage during compilation:

  program test
  a = 3.0
  print *,a**(-2147483647-1)
  end


-- 

tkoenig at gcc dot gnu dot org changed:

   What|Removed |Added

 AssignedTo|unassigned at gcc dot gnu   |tkoenig at gcc dot gnu dot
   |dot org |org
 Status|NEW |ASSIGNED
   Last reconfirmed|2007-02-27 19:35:04 |2007-03-01 19:43:36
   date||


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981



[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-02-28 Thread tkoenig at gcc dot gnu dot org


--- Comment #9 from tkoenig at gcc dot gnu dot org  2007-02-28 22:04 ---
In principle, this is easy to fix:  Use
an unsigned variable for u.  In practice, this
means we have to delve into iparm.m4.  Yuck :-)

I'll look at this, but if somebody else has a
good suggestion, please go ahead.


-- 

tkoenig at gcc dot gnu dot org changed:

   What|Removed |Added

 CC||tkoenig at gcc dot gnu dot
   ||org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981



[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-02-28 Thread pinskia at gcc dot gnu dot org


--- Comment #10 from pinskia at gcc dot gnu dot org  2007-02-28 22:39 
---
Yes declare this as undefined code and close the bug :).


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981



[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-02-28 Thread Thomas dot Koenig at online dot de


--- Comment #11 from Thomas dot Koenig at online dot de  2007-02-28 23:13 
---
Subject: Re:  a ** exp fails for integer exponents if exp is -huge()-1
(endless loop)

 --- Comment #10 from pinskia at gcc dot gnu dot org  2007-02-28 22:39 
 ---
 Yes declare this as undefined code and close the bug :).

Alternatively, attach this patch :-)

Thomas


--- Comment #12 from Thomas dot Koenig at online dot de  2007-02-28 23:13 
---
Created an attachment (id=13127)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=13127action=view)


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981



[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-02-28 Thread kargl at gcc dot gnu dot org


--- Comment #13 from kargl at gcc dot gnu dot org  2007-02-28 23:25 ---
(In reply to comment #12)
 Created an attachment (id=13127)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=13127action=view) [edit]
 

Patch looks ok to me.  Note, I haven't tested.


-- 

kargl at gcc dot gnu dot org changed:

   What|Removed |Added

 CC||kargl at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981



[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-02-27 Thread burnus at gcc dot gnu dot org


--- Comment #3 from burnus at gcc dot gnu dot org  2007-02-27 19:35 ---
Hi,

  Could you post an example?

With example I mean something which actually compiles and runs. Here, I have
two problems: 
  include '$(where)/amos/include/essential.ecm'
is missing as well as the main program which calls the routine. And as always:
The smaller the better.

In addition, please attach such long files, they clutter the bug report page
quite a bit if they are put into the comment field.

   if ( n_normal .ge. 10.-eps .and. n_normal .le. 10+eps ) then

   PS. Notice the eps in the last segment of code. This is 
   really a bug also. It originally was 
   If ( n_normal .eq. 10. ) then
   But in some cases it missed the proper branch.

If you do:
  n_normal = 10.0
then  if(n_normal == 10.0)  should work. If you do
  n_normal = 500.0/100.0*2.0
then it might not work due to rounding errors and representation problems of a
decimal number as binary number. Therefore, one should almost always use
something like  if ( abs(n_normal - 10.0)  eps),  where eps is sensibly
chosen, it could be e.g. eps = epsilon(n_normal), but this might be even too
small. For irrational numbers such as 3.14159 it is more obvious that one
should use, e.g. (abs(myNumber - 3.14159)  1e-4) instead of  if (myNumber ==
3.14159).


Back to the problem:

The calculation goes only into an endless loop if the exponent is
-huge(integer)-1.

Test case:
  program test
  implicit none
  print *, 5.0**(-huge(i)-1)
  end program

The problem is that in pow_r4_i4 the following operation is done:

  if (n  0)
{
  n = -n;

The problem is: For n == -huge(n) - 1 exists no positive number. Thus
 n == -n == -2147483648  (for integer(4))


-- 

burnus at gcc dot gnu dot org changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
 Ever Confirmed|0   |1
   Keywords||wrong-code
   Last reconfirmed|-00-00 00:00:00 |2007-02-27 19:35:04
   date||
Summary|Program Hangs |a ** exp fails for integer
   ||exponents if exp is -
   ||huge()-1 (endless loop)


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981



[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-02-27 Thread ray at ultramarine dot com


--- Comment #4 from ray at ultramarine dot com  2007-02-27 19:52 ---
Subject: Re:  a ** exp fails for integer exponents if exp
 is -huge()-1 (endless loop)

On Tue, 27 Feb 2007, burnus at gcc dot gnu dot org wrote:

 
 
 --- Comment #3 from burnus at gcc dot gnu dot org  2007-02-27 19:35 
 ---
 Hi,
 
   Could you post an example?
 
 With example I mean something which actually compiles and runs. Here, I have
 two problems: 
   include '$(where)/amos/include/essential.ecm'
 is missing as well as the main program which calls the routine. And as always:
 The smaller the better.


  I really try to do this, but I am an old fortran programer and 
  I do not know how to set +Infinity. Yes, of course, I have a case
  that computes it and then hangs, but my code is over 500,000 lines
  long and I did not think it is appropriate.

 In addition, please attach such long files, they clutter the bug report page
 quite a bit if they are put into the comment field.
 
if ( n_normal .ge. 10.-eps .and. n_normal .le. 10+eps ) then
 
PS. Notice the eps in the last segment of code. This is 
really a bug also. It originally was 
If ( n_normal .eq. 10. ) then
But in some cases it missed the proper branch.
 
 If you do:
   n_normal = 10.0
 then  if(n_normal == 10.0)  should work. If you do
   n_normal = 500.0/100.0*2.0
 then it might not work due to rounding errors and representation problems of a
 decimal number as binary number. Therefore, one should almost always use
 something like  if ( abs(n_normal - 10.0)  eps),  where eps is sensibly
 chosen, it could be e.g. eps = epsilon(n_normal), but this might be even too
 small. For irrational numbers such as 3.14159 it is more obvious that one
 should use, e.g. (abs(myNumber - 3.14159)  1e-4) instead of  if (myNumber ==
 3.14159).

  This is not as silly as it sounds. All I care about is to handle
  the special case of 10 (exactly). I have seen cases where the
  equality fails, but the number is really 10. It probably has
  something to do with how this is done. I never could get a 
  small case to fail.

 Back to the problem:
 
 The calculation goes only into an endless loop if the exponent is
 -huge(integer)-1.
 
 Test case:
   program test
   implicit none
   print *, 5.0**(-huge(i)-1)
   end program
 
 The problem is that in pow_r4_i4 the following operation is done:
 
   if (n  0)
 {
   n = -n;
 
 The problem is: For n == -huge(n) - 1 exists no positive number. Thus
  n == -n == -2147483648  (for integer(4))
 
 
 -- 
 
 burnus at gcc dot gnu dot org changed:
 
What|Removed |Added
 
  Status|UNCONFIRMED |NEW
  Ever Confirmed|0   |1
Keywords||wrong-code
Last reconfirmed|-00-00 00:00:00 |2007-02-27 19:35:04
date||
 Summary|Program Hangs |a ** exp fails for integer
||exponents if exp is -
||huge()-1 (endless loop)
 
 
 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981
 
 --- You are receiving this mail because: ---
 You reported the bug, or are watching the reporter.
 
 ---+  Spam Scoring Results   +
 Content analysis details:   (-2.6 hits, 5.0 required)
 -2.6 BAYES_00   BODY: Bayesian spam probability is 0 to 1%
 [score: 0.0033]
 
 ---+ End Spam Scoring Results +---
 


Ultramarine, Inc.
http://www.ultramarine.com
Phone: 713-975-8146
Fax:   713-975-8179


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981



[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-02-27 Thread pinskia at gcc dot gnu dot org


--- Comment #5 from pinskia at gcc dot gnu dot org  2007-02-27 19:54 ---
Also isn't -huge()-1 undefined code for Fortran?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981



[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-02-27 Thread ray at ultramarine dot com


--- Comment #6 from ray at ultramarine dot com  2007-02-27 19:57 ---
Subject: Re:  a ** exp fails for integer exponents if exp
 is -huge()-1 (endless loop)

On Tue, 27 Feb 2007, pinskia at gcc dot gnu dot org wrote:

 
 
 --- Comment #5 from pinskia at gcc dot gnu dot org  2007-02-27 19:54 
 ---
 Also isn't -huge()-1 undefined code for Fortran?
 
 
 -- 

  I am not familiar with the new standards, but it was
  in the past.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981



[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-02-27 Thread kargl at gcc dot gnu dot org


--- Comment #7 from kargl at gcc dot gnu dot org  2007-02-27 20:46 ---
(In reply to comment #5)
 Also isn't -huge()-1 undefined code for Fortran?

-huge()-1 can be defined in Fortran.  The problem
comes when one tries to use that value in, e.g.,
IABS() because the standard prohibits calling an
intrinsic that must return a value outside of its
defined range.

I'll also note that -pedantic will reject -huge()-1
as being outside the symmetric range of the model
numbers.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981



[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)

2007-02-27 Thread burnus at gcc dot gnu dot org


--- Comment #8 from burnus at gcc dot gnu dot org  2007-02-27 22:04 ---
  Also isn't -huge()-1 undefined code for Fortran?
 -huge()-1 can be defined in Fortran.  [...]
 I'll also note that -pedantic will reject -huge()-1

Just for completeness: In the original example (the very long, incomplete F77
code) the problem was due to an overflow of:

integer :: exponent
! temp very large or +INF
exponent = log10(temp)

Thus as long as such -huge()-1 and (for floating point numbers) INF, NAN and
denormal numbers exists, the intrinsics have to deal with it somehow.


(In reply to comment #4)
  With example I mean something which actually compiles and runs. Here, I have
  two problems: 
include '$(where)/amos/include/essential.ecm'
  is missing as well as the main program which calls the routine.
 
   I really try to do this, but I am an old fortran programer and 
   I do not know how to set +Infinity. Yes, of course, I have a case
   that computes it and then hangs, but my code is over 500,000 lines
   long and I did not think it is appropriate.

Well, given that you have 500,000+ lines, it was already quite short and I was
able to reproduce the problem even without the essential.ecm file. (Actually,
reproducing was easier than I initially feared.)

In any case: Thanks for reporting this bug.

[Comparison with 10.0]
   This is not as silly as it sounds. All I care about is to handle
   the special case of 10 (exactly). I have seen cases where the
   equality fails, but the number is really 10.

I'm sure that the two numbers are then not exactly the same (bitwise) though;
nonetheless I'm not good at predicting when an operation will cause an
off-by-one (bit) and when not. I also failed to cook up a small example for
10.0

To create infinity etc. one can simply do:
  real :: zero, r
  zero = 0.0
  r = 1.0/zero ! = +INF
  r = zero/zero ! = NaN
  r = -1.0/zero ! = -INF


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981