Created attachment 25227 [details] Netlib BLAS's srotmg.f (== lapack-3.3.1/BLAS/SRC/srotmg.f) Compiling BLAS' srotmg.f with -ffrontend-optimize causes an endless loop: $ gfortran -ffrontend-optimize -c srotmg.f; gfortran -O0 test.f90 srotmg.o \ && ./a.out CALLING: SROTMG Without, it works: $ gfortran -fno-frontend-optimize -c srotmg.f; gfortran -O0 test.f90 srotmg.o \ && ./a.out CALLING: SROTMG DONE CALLING: SROTMG FAILING: 2011-09-08, 2011-08-25-r178053, 05-28-r174379, 2011-05-10, WORKING: 2010-09-28-r164677 (with -O3, -ffrontend-optimize didn't exist yet) Seemingly also working: Current 4.6 branch. implicit none real DTEMP(9) EXTERNAL SROTMG DTEMP(1) = 2.00000003E-10 DTEMP(2) = 3.99999991E-02 DTEMP(3) = 100000.000 DTEMP(4) = 10.0000000 DTEMP(5) = 0.00000000 WRITE (*,*)' CALLING: SROTMG' CALL SROTMG(DTEMP(1),DTEMP(2),DTEMP(3),DTEMP(4),DTEMP(5)) WRITE (*,*)' DONE CALLING: SROTMG' end
The problem is the replacement of "ABS(SD2)" by "tmp = ABS(SD2)" in the following DO WHILE LOOP: DO WHILE ( (ABS(SD2).LE.RGAMSQ) .OR. (ABS(SD2).GE.GAMSQ) ) IF (SFLAG.EQ.ZERO) THEN While it is OK to evaluate it only once, it needs to be evaluated every time and not once before the loop! Working: while (1) { if (!(ABS_EXPR <*sd2> <= rgamsq) && !(ABS_EXPR <*sd2> >= gamsq)) goto L.13; if (sflag == zero) Failing: real(kind=4) __var_1; __var_1 = ABS_EXPR <*sd2>; while (1) { if (!(__var_1 <= rgamsq) && !(__var_1 >= gamsq)) goto L.14; if (sflag == zero)
Looking at it.
Created attachment 25236 [details] Tentative patch This one replaces a DO WHILE loop with its equivalent, DO IF (.not. ...) EXIT form. Seems to work.
Author: tkoenig Date: Sun Sep 11 20:48:26 2011 New Revision: 178768 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=178768 Log: 2011-09-11 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/50327 * frontend-passes.c (dummy_expr_callback): New function. (convert_do_while): New function. (optimize_namespace): Call code walker to convert do while loops. 2011-09-11 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/50327 * gfortran.dg/do_while_1.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/do_while_1.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/frontend-passes.c trunk/gcc/testsuite/ChangeLog
Fixed, closing. Thanks for the bug report and the analysis!