Bug 22290 - Optimize Assigned GOTO to cause error with -O1 or higher
Summary: Optimize Assigned GOTO to cause error with -O1 or higher
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: 4.0.3
Assignee: Steven Bosscher
URL:
Keywords: wrong-code
Depends on:
Blocks: 19292
  Show dependency treegraph
 
Reported: 2005-07-04 08:23 UTC by fengwang
Modified: 2005-10-25 15:02 UTC (History)
1 user (show)

See Also:
Host: i686/ia64-pc-linux
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-09-13 10:27:12


Attachments
Patch (1.77 KB, patch)
2005-09-13 14:49 UTC, fengwang
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description fengwang 2005-07-04 08:23:27 UTC
See a fortran program:
$ cat t.f
      integer nz
      assign 93 to nz
      go to nz,(93)
  93  continue
      end
$ gfortran -v
Target: ia64-unknown-linux-gnu
Configured with: ../gcc/configure --enable-languages=c,f95 --
prefix=/home/wf/loc
al
Thread model: posix
gcc version 4.1.0 20050704 (experimental)
$ gfortran -O0 -w t.f
$ ./a.out
That's correct.

But if we compile with -O1 or higher, we get 
$ ./a.out
Fortran runtime error: Assigned label is not in the list

We dump the original tree with -fdump-tree-original as follows:
MAIN__ ()
{
  int4 nz;
  void * nz.1;
  int4 nz.0 = -2;

  nz.0 = -1;
  nz.1 = &__label_000093;
  if (__builtin_expect (nz.0 != -1, 0))
    {
      _gfortran_runtime_error ("Assigned label is not a target 
label", "kgfm2.f"
, 5);
    }
  else
    {
      (void) 0;
    }
  if (&__label_000093 == nz.1) goto __label_000093; else (void) 0;
  _gfortran_runtime_error ("Assigned label is not in the list", "kgfm2.f", 5);
  __label_000093:;
}
That's correct.

I think this is tree-optimization error. Tested on ia64/i686-pc-linux.
Comment 1 Andrew Pinski 2005-07-04 10:00:04 UTC
Confirmed, This is a fortran front-end or gimplifier bug.
Look at what the gimplifier produces:
  int4 nz.0 = -2;  // <--- this is not gimple

  nz.0 = -1;
  nz.1 = &__label_000093;
  D.475 = nz.0 != -1;
  D.476 = __builtin_expect (D.475, 0);

Comment 2 fengwang 2005-07-04 12:38:37 UTC
(In reply to comment #1)
> Confirmed, This is a fortran front-end or gimplifier bug.
> Look at what the gimplifier produces:
>   int4 nz.0 = -2;  // <--- this is not gimple

I am not very clear the gimple definition. Can you explain more? 

This is the initialization of nz.0 variable. I use this variable to indicate 
the integer is assigned a format label (-1) or target label (now it is the 
length of format string). See fortran/trans-decl.c (gfc_get_symbol_decl): 815
Comment 3 Steven Bosscher 2005-07-04 15:28:54 UTC
"int4 nz.0 = -2;"  look line an INIT_EXPR.  It should be 
 
"int4 nz.0; 
 nz.0 = -2" 
 
 
Comment 4 fengwang 2005-07-05 08:39:23 UTC
(In reply to comment #3)
> "int4 nz.0 = -2;"  look line an INIT_EXPR.  It should be 
>  
> "int4 nz.0; 
>  nz.0 = -2" 

Shall we add an assignment explicitly? Just give an initial value. I don't 
think we should defer doing this when generate function codes.

And another question, all the variables which have initial values are treat as 
static. Is this reasonable?

Back to this topic, in fact, the error is not caused by nz.0. It is used to 
judge if we assign a target label. And the output is "Assigned label is not in 
the list".  So it has passed the judgement of nz.0.

From the trees dumped, I found the CCP pass is wrong:
$cat as.f.t22.ccp
;; Function MAIN__ (MAIN__)

Removing basic block 3
Merging blocks 2 and 4
Merging blocks 2 and 5
MAIN__ ()
{
  void * gotovar.2;
  void * nz.1;
  int4 nz.0 = -2;
  int4 nz;
  <unnamed type> D.476;
  logical4 D.475;

<bb 0>:
  nz.0_1 = -1;
  nz.1_2 = &__label_000093;
  D.475_3 = 0;
  D.476_4 = 0;
  if (D.476_4 != 0) goto <L0>; else goto <L1>;

<L0>:;
  _gfortran_runtime_error ("Assigned label is not a target label", "as.f", 2);

__label_000093:;      <<<<<<<<<<<<<<<<<<<< Wrong here.
<L1>:;
  _gfortran_runtime_error ("Assigned label is not in the list", "as.f", 2
  return;

}

Before this pass, it it correct.
Comment 5 fengwang 2005-07-05 08:44:38 UTC
From as.f.t22.ccp:
<bb 0>:
  nz.0_1 = -1;
  nz.1_2 = &__label_000093;
  D.475_3 = 0;
  D.476_4 = 0;
  if (D.476_4 != 0) goto <L0>; else goto <L1>;
This is also wrong.
Comment 6 fengwang 2005-07-06 07:42:07 UTC
(In reply to comment #4)
> And another question, all the variables which have initial values are treat
> as static. Is this reasonable?
Yes, this is reasonable. Confirm myself. In section 5.1 (Fortran95, Working 
draft J3/97-007R2):
The presence of initialization implies that object-name is saved, except for 
an object-name in a named common block or an object-name with the PARAMETER 
attribute.
Comment 7 Thomas Koenig 2005-07-07 22:16:34 UTC
g77 gets this right.
Comment 8 Steven Bosscher 2005-09-13 10:27:12 UTC
Bloody hell.  Stupid bug. 
Alright then, let's see if I can fix this one. 
Comment 9 fengwang 2005-09-13 14:49:44 UTC
Created attachment 9717 [details]
Patch
Comment 10 fengwang 2005-09-13 14:53:27 UTC
(In reply to comment #8)
> Bloody hell.  Stupid bug. 
> Alright then, let's see if I can fix this one. 

Steven, it seems to disappear on current gcc4.1 and gcc4.0. I once send you a 
patch to fix the gimple problem. The patch is attached. And this patch fixes 
another compiling ICE in the test case:

subroutine s1 (a)
integer a
assign 777 to a
go to a
777 print *, "Hello s1"
end
program test
call s1 (1)
end
Comment 11 GCC Commits 2005-10-25 13:44:50 UTC
Subject: Bug 22290

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-4_0-branch
Changes by:	fengwang@gcc.gnu.org	2005-10-25 13:44:46

Modified files:
	gcc/testsuite  : ChangeLog 
	gcc/fortran    : ChangeLog trans-decl.c trans-stmt.c 
Added files:
	gcc/testsuite/gfortran.dg: assign_5.f90 assign_6.f 

Log message:
	2005-10-25  Feng Wang  <fengwang@nudt.edu.cn>
	
	PR fortran/22290
	* trans-decl.c (gfc_add_assign_aux_vars): New function. Add two
	auxiliary variables.
	(gfc_get_symbol_decl): Use it when a variable, including dummy
	argument, is assigned a label.
	(gfc_trans_assign_aux_var): New function. Set initial value of
	the auxiliary variable explicitly.
	(gfc_trans_deferred_vars): Use it.
	* trans-stmt.c (gfc_conv_label_variable): Handle dummy argument.
	
	2005-10-25  Feng Wang  <fengwang@nudt.edu.cn>
	
	PR fortran/22290
	* gfortran.dg/assign_5.f90: New test.
	* gfortran.dg/assign_6.f: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.5084.2.488&r2=1.5084.2.489
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gfortran.dg/assign_5.f90.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gfortran.dg/assign_6.f.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.335.2.141&r2=1.335.2.142
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/trans-decl.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.54.2.6&r2=1.54.2.7
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/trans-stmt.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.24.6.10&r2=1.24.6.11

Comment 12 GCC Commits 2005-10-25 14:06:26 UTC
Subject: Bug 22290

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	fengwang@gcc.gnu.org	2005-10-25 14:06:23

Modified files:
	gcc/testsuite  : ChangeLog 
	gcc/fortran    : ChangeLog trans-decl.c trans-stmt.c 
Added files:
	gcc/testsuite/gfortran.dg: assign_5.f90 assign_6.f 

Log message:
	2005-10-25  Feng Wang  <fengwang@nudt.edu.cn>
	
	PR fortran/22290
	* trans-decl.c (gfc_add_assign_aux_vars): New function. Add two
	auxiliary variables.
	(gfc_get_symbol_decl): Use it when a variable, including dummy
	argument, is assigned a label.
	(gfc_trans_assign_aux_var): New function. Set initial value of
	the auxiliary variable explicitly.
	(gfc_trans_deferred_vars): Use it.
	* trans-stmt.c (gfc_conv_label_variable): Handle dummy argument.
	
	2005-10-25  Feng Wang  <fengwang@nudt.edu.cn>
	
	PR fortran/22290
	* gfortran.dg/assign_5.f90: New test.
	* gfortran.dg/assign_6.f: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.6250&r2=1.6251
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gfortran.dg/assign_5.f90.diff?cvsroot=gcc&r1=1.1&r2=1.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gfortran.dg/assign_6.f.diff?cvsroot=gcc&r1=1.1&r2=1.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/ChangeLog.diff?cvsroot=gcc&r1=1.598&r2=1.599
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/trans-decl.c.diff?cvsroot=gcc&r1=1.72&r2=1.73
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/trans-stmt.c.diff?cvsroot=gcc&r1=1.42&r2=1.43

Comment 13 fengwang 2005-10-25 14:09:10 UTC
Fixed.