[Bug fortran/30981] a ** exp fails for integer exponents if exp is -huge()-1 (endless loop)
--- 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)
--- 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)
--- 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)
--- 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)
--- 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)
--- 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)
--- 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)
--- 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)
--- 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)
--- 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)
--- 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)
--- 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