Bug 50327 - [4.7 Regression] Front-end optimization generates wrong code for BLAS's srotmg
Summary: [4.7 Regression] Front-end optimization generates wrong code for BLAS's srotmg
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.7.0
: P3 major
Target Milestone: 4.7.0
Assignee: Thomas Koenig
URL: http://gcc.gnu.org/ml/gcc-patches/201...
Keywords: wrong-code
Depends on:
Blocks: 32834
  Show dependency treegraph
 
Reported: 2011-09-08 13:26 UTC by Tobias Burnus
Modified: 2011-09-11 20:49 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-09-08 00:00:00


Attachments
Netlib BLAS's srotmg.f (== lapack-3.3.1/BLAS/SRC/srotmg.f) (1.36 KB, text/plain)
2011-09-08 13:26 UTC, Tobias Burnus
Details
Tentative patch (1.03 KB, patch)
2011-09-09 21:59 UTC, Thomas Koenig
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2011-09-08 13:26:56 UTC
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
Comment 1 Tobias Burnus 2011-09-08 13:56:17 UTC
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)
Comment 2 Thomas Koenig 2011-09-08 21:21:58 UTC
Looking at it.
Comment 3 Thomas Koenig 2011-09-09 21:59:51 UTC
Created attachment 25236 [details]
Tentative patch

This one replaces a DO WHILE loop with its equivalent,
DO 
IF (.not. ...) EXIT

form.

Seems to work.
Comment 4 Thomas Koenig 2011-09-11 20:48:29 UTC
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
Comment 5 Thomas Koenig 2011-09-11 20:49:49 UTC
Fixed, closing.

Thanks for the bug report and the analysis!