Bug 24406 - EQUIVALENCE broken in 32-bit code with optimization -O2
Summary: EQUIVALENCE broken in 32-bit code with optimization -O2
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: alias, patch, wrong-code
Depends on:
Blocks: 20405
  Show dependency treegraph
 
Reported: 2005-10-17 11:10 UTC by Mick Pont
Modified: 2006-04-23 06:07 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-01-29 19:45:28


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mick Pont 2005-10-17 11:10:05 UTC
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
Comment 1 Andrew Pinski 2005-10-17 11:29:54 UTC
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.
Comment 2 Andrew Pinski 2005-10-17 11:30:51 UTC
-O2 -fno-strict-aliasing works .
Comment 3 kargl 2005-10-17 18:00:58 UTC
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).
Comment 4 kargl 2005-10-17 18:01:33 UTC
Forgot to add myself to the CC list.
Comment 5 Andrew Pinski 2005-10-23 22:52:30 UTC
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;

Comment 6 Tobias Schlüter 2005-11-01 20:20:06 UTC
(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.

Comment 7 Thomas Koenig 2006-02-06 20:33:38 UTC
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).
Comment 8 Tobias Schlüter 2006-02-06 20:56:44 UTC
Moving this to the rtl-optimization component, the final tree dump looks correct.
Comment 9 Steve Kargl 2006-02-06 20:57:23 UTC
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.

Comment 10 Andrew Pinski 2006-02-06 21:01:26 UTC
(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.
Comment 11 Paul Thomas 2006-03-03 10:08:25 UTC
> 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.............
Comment 12 Andrew Pinski 2006-03-06 21:03:53 UTC
(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).
Comment 13 Paul Thomas 2006-03-07 07:28:41 UTC
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
Comment 14 Andrew Pinski 2006-03-23 01:06:11 UTC
Jakub posted a patch:
http://gcc.gnu.org/ml/gcc-patches/2006-03/msg01419.html

So this is no longer mine.
Comment 15 Paul Thomas 2006-03-23 08:06:11 UTC
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.
> 
Comment 16 Andrew Pinski 2006-03-23 14:54:34 UTC
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

Comment 17 Paul Thomas 2006-04-23 06:07:39 UTC
This has been dealt with, has it not?

I have marked it as fixed - if I am wrong, please unfix it!

Paul
Comment 18 Mick Pont 2006-04-24 10:13:10 UTC
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
________________________________________________________________________