This program demonstrates a problem with Fortran EQUIVALENCE in 32-bit compilations. The equivalenced value in variable rteps gets set correctly (as evidenced by the write statement) but too late - an incorrect value has already been used in the earlier comparison statement. Moving the statement write (*,*) 'rteps = ', rteps to just before the comparison avoids the problem. Compiling with a level of optimization lower than -O2 also avoids the problem. The problem does not show up in 64-bit compiles. program main double precision rteps integer irt(2) equivalence (rteps,irt) c This bit pattern sets rteps = 1.0d0 irt(1) = Z'00000000' irt(2) = Z'3FF00000' if (rteps.gt.0.99d0 .and. rteps.lt.1.1d0) then write (*,*) '0.99 < rteps < 1.1 : rteps OK' else write (*,*) 'rteps <= 0.99 or rteps >= 1.1 : rteps BAD' end if write (*,*) 'rteps = ', rteps end % gfortran -v Using built-in specs. Target: x86_64-unknown-linux-gnu Configured with: ../gcc/configure --prefix=/var/tmp/gfortran-20051007/irun --enable-languages=c,f95 Thread model: posix gcc version 4.1.0 20051007 (experimental) % gfortran -Wall -m32 -O0 equiv.f % ./a.out 0.99 < rteps < 1.1 : rteps OK rteps = 1.00000000000000 % gfortran -Wall -m32 -O2 equiv.f % ./a.out rteps <= 0.99 or rteps >= 1.1 : rteps BAD rteps = 1.00000000000000
Hmm: li r2,0 lfd f13,56(r1) addis r27,r31,ha16(L__gfortran_filename$non_lazy_ptr-"L00000000001$pb") stw r0,56(r1) addis r28,r31,ha16(L__gfortran_line$non_lazy_ptr-"L00000000001$pb") fcmpu cr7,f13,f0 stw r2,60(r1) We are loading from 56(r1) before storing to it. We have an aliasing issue. The union looks correct.
-O2 -fno-strict-aliasing works .
The code is illegal, and therefore gfortran can do anything it wants (including start WW III). (1) rteps is never defined, so it can't be reference in the IF statement. (2) Even if rteps was defined prior to the assignments of irt(1) and irt(2), rteps would become undefined via 14.7.6(1) of the standard. (3) The use of BOZ literal constants here is nonstandard although gfortran may permit its use in this manner (I haven't checked).
Forgot to add myself to the CC list.
Confirmed, fortran front-end needs to do something similar to the C front-end in c-common.c/c_common_get_alias_set: /* Permit type-punning when accessing a union, provided the access is directly through the union. For example, this code does not permit taking the address of a union member and then storing through it. Even the type-punning allowed here is a GCC extension, albeit a common and useful one; the C standard says that such accesses have implementation-defined behavior. */ for (u = t; TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF; u = TREE_OPERAND (u, 0)) if (TREE_CODE (u) == COMPONENT_REF && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) return 0;
(In reply to comment #3) > The code is illegal, and therefore gfortran can do anything > it wants (including start WW III). > > (1) rteps is never defined, so it can't be reference in the IF > statement. > > (2) Even if rteps was defined prior to the assignments of irt(1) and > irt(2), rteps would become undefined via 14.7.6(1) of the standard. > > (3) The use of BOZ literal constants here is nonstandard although > gfortran may permit its use in this manner (I haven't checked). Using equivalences this way is a common extension, and we actually use this in a number of testcases ourselves, so if we decided to start WWIII in this case, we probably wouldn't live much longer than our testsuite runs take.
Note that http://www.netlib.org/blas/d1mach.f has code INTEGER SMALL(2) INTEGER LARGE(2) INTEGER RIGHT(2) INTEGER DIVER(2) INTEGER LOG10(2) INTEGER SC, CRAY1(38), J COMMON /D9MACH/ CRAY1 SAVE SMALL, LARGE, RIGHT, DIVER, LOG10, SC DOUBLE PRECISION DMACH(5) EQUIVALENCE (DMACH(1),SMALL(1)) EQUIVALENCE (DMACH(2),LARGE(1)) EQUIVALENCE (DMACH(3),RIGHT(1)) EQUIVALENCE (DMACH(4),DIVER(1)) EQUIVALENCE (DMACH(5),LOG10(1)) ... IF (SC .NE. 987) THEN DMACH(1) = 1.D13 IF ( SMALL(1) .EQ. 1117925532 * .AND. SMALL(2) .EQ. -448790528) THEN * *** IEEE BIG ENDIAN *** SMALL(1) = 1048576 SMALL(2) = 0 LARGE(1) = 2146435071 LARGE(2) = -1 RIGHT(1) = 1017118720 RIGHT(2) = 0 DIVER(1) = 1018167296 DIVER(2) = 0 LOG10(1) = 1070810131 LOG10(2) = 1352628735 So, if we don't support this extension, we will potentially break BLAS (at least the vanilla version distributed with netlib).
Moving this to the rtl-optimization component, the final tree dump looks correct.
Subject: Re: EQUIVALENCE broken in 32-bit code with optimization -O2 On Mon, Feb 06, 2006 at 08:33:39PM -0000, tkoenig at gcc dot gnu dot org wrote: > > ------- Comment #7 from tkoenig at gcc dot gnu dot org 2006-02-06 20:33 ------- > Note that http://www.netlib.org/blas/d1mach.f has code > The version of blas that is bundled with lapack from netlib does not include this routine. A grep on lapack sources shows no nonconforming uses of equivalence. I certainly won't object to someone hacking gfortran to do what the programmer wants, but I think the effort could be spent on other parts of gfortran that actually broken with respect to the standard.
(In reply to comment #8) > Moving this to the rtl-optimization component, the final tree dump looks > correct. Even though the final tree dump looks correct this is a still a front-end issue as the front-end communicates the aliasing sets to the rtl optimizers. I am going to take it too.
> Even though the final tree dump looks correct this is a still a front-end issue > as the front-end communicates the aliasing sets to the rtl optimizers. > I am going to take it too. I have either missed something, the PR has fixed itself or it is not a front-end problem. See below. Paul THOMASP@PC-THOMAS-P /cygdrive/d/svn/prs $ /irun/bin/gfortran --version GNU Fortran 95 (GCC) 4.2.0 20060301 (experimental) Copyright (C) 2006 Free Software Foundation, Inc. THOMASP@PC-THOMAS-P /cygdrive/d/svn/prs $ uname -a CYGWIN_NT-5.0 PC-THOMAS-P 1.5.7(0.109/3/2) 2004-01-30 19:32 i686 unknown unknown Cygwin THOMASP@PC-THOMAS-P /cygdrive/d/svn/prs $ /irun/bin/gfortran -m32 -O3 -Wall -std=f95 -pedantic -fdump-tree-gimple pr244 06.f THOMASP@PC-THOMAS-P /cygdrive/d/svn/prs $ ./a 0.99 < rteps < 1.1 : rteps OK rteps = 1.00000000000000 THOMASP@PC-THOMAS-P /cygdrive/d/svn/prs $ cat *pr24406*le MAIN__ () { real8 D.906; logical4 D.907; logical4 D.908; logical4 D.909; logical4 D.910; union { int4 irt[2]; real8 rteps; } equiv.0; int4 irt[2] [value-expr: equiv.0.irt]; real8 rteps [value-expr: equiv.0.rteps]; _gfortran_set_std (2, 11, 1); equiv.0.irt[0] = 0; equiv.0.irt[1] = 1072693248; D.906 = equiv.0.rteps; D.907 = D.906 > 9.89999999999999991118215802998747676610946655273e-1; D.908 = !D.907; if (D.908) ..........snip.............
(In reply to comment #11) > > Even though the final tree dump looks correct this is a still a front-end issue > > as the front-end communicates the aliasing sets to the rtl optimizers. > > I am going to take it too. > > I have either missed something, the PR has fixed itself or it is not a > front-end problem. See below. The symptom of this testcase passing might work but the bug is still there and most likely cannot expose it at the tree level and it is semi hard to expose it even on the RTL level. Comment #5 shows what needs to be added to the Fortran front-end which I will do sometime this week when I get some time (but note I have two papers to write which is what is right now taking up my time).
Subject: RE: EQUIVALENCE broken in 32-bit code with optimization -O2 Andrew, Oh, I did miss something, then! > The symptom of this testcase passing might work but the bug > is still there and > most likely cannot expose it at the tree level and it is semi > hard to expose it > even on the RTL level. If it is hard to expose, do we care about it? Is it certain systems that are sensistive to it.... or....? > Comment #5 shows what needs to be added to the Fortran > front-end which I will > do sometime this week when I get some time (but note I have > two papers to write > which is what is right now taking up my time). Me too. *sigh* All the best Paul
Jakub posted a patch: http://gcc.gnu.org/ml/gcc-patches/2006-03/msg01419.html So this is no longer mine.
Subject: RE: EQUIVALENCE broken in 32-bit code with optimization -O2 I thought to take a look at the patch tonight; does it look OK to you? Paul > -----Message d'origine----- > De : pinskia at gcc dot gnu dot org [mailto:gcc-bugzilla@gcc.gnu.org] > Envoyé : jeudi 23 mars 2006 02:06 > À : THOMAS Paul Richard 169137 > Objet : [Bug fortran/24406] EQUIVALENCE broken in 32-bit code with > optimization -O2 > > > > > ------- Comment #14 from pinskia at gcc dot gnu dot org > 2006-03-23 01:06 ------- > Jakub posted a patch: > http://gcc.gnu.org/ml/gcc-patches/2006-03/msg01419.html > > So this is no longer mine. > > > -- > > pinskia at gcc dot gnu dot org changed: > > What |Removed |Added > -------------------------------------------------------------- > -------------- > AssignedTo|pinskia at gcc dot gnu dot |unassigned > at gcc dot gnu > |org |dot org > URL| > |http://gcc.gnu.org/ml/gcc- > | |patches/2006- > | |03/msg01419.html > Status|ASSIGNED |NEW > Keywords| |patch > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24406 > > ------- You are receiving this mail because: ------- > You are on the CC list for the bug, or are watching someone who is. >
Subject: Re: EQUIVALENCE broken in 32-bit code with optimization -O2 On Mar 23, 2006, at 3:06 AM, paul dot richard dot thomas at cea dot fr wrote: > > I thought to take a look at the patch tonight; does it look OK to you? I forgot to mention, this was about the patch I was going to create anyways. -- Pinski
This has been dealt with, has it not? I have marked it as fixed - if I am wrong, please unfix it! Paul
Subject: Re: EQUIVALENCE broken in 32-bit code with optimization -O2 pault at gcc dot gnu dot org wrote: > ------- Comment #17 from pault at gcc dot gnu dot org 2006-04-23 06:07 ------- > This has been dealt with, has it not? > > I have marked it as fixed - if I am wrong, please unfix it! Looks fixed to me - thanks Mick ________________________________________________________________________ This e-mail has been scanned for all viruses by Star. The service is powered by MessageLabs. For more information on a proactive anti-virus service working around the clock, around the globe, visit: http://www.star.net.uk ________________________________________________________________________