public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* Re: Optimization bug
       [not found] <20000812004418.A4935@a2000.nl>
@ 2000-08-12  9:30 ` Richard Henderson
  0 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2000-08-12  9:30 UTC (permalink / raw)
  To: Carlo Wood; +Cc: gcc-bugs, bug-gnu-utils, hjl, nickc, gcc-patches

On Sat, Aug 12, 2000 at 12:44:18AM +0200, Carlo Wood wrote:
> The problem is gcc is confused near `return' with its local variables
> on the stack: returning from a function exits the scope of the local
> variables, so that when a recursive call to the same function is
> performed, this call is replaced by a jmp to the start of the function
> and the same stack space is used for the local variables.

A similar test case already exists: gcc.c-torture/execute/20000412-2.c.

Fixed thus.  Tested on i686-linux.


r~

        * sibcall.c (uses_addressof): Accept both addressof and
        current_function_internal_arg_pointer inside a mem.
        (optimize_sibling_and_tail_recursive_call): Fail tail recursion
        if current_function_uses_addressof.
        * stmt.c (expand_return): Kill tail recursion and HAVE_return
        optimizations.

Index: sibcall.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/sibcall.c,v
retrieving revision 1.7
diff -c -p -d -r1.7 sibcall.c
*** sibcall.c	2000/08/04 20:28:06	1.7
--- sibcall.c	2000/08/12 16:24:33
*************** static rtx skip_copy_to_return_value	PAR
*** 37,43 ****
  static rtx skip_use_of_return_value	PARAMS ((rtx, enum rtx_code));
  static rtx skip_stack_adjustment	PARAMS ((rtx));
  static rtx skip_jump_insn		PARAMS ((rtx));
! static int uses_addressof		PARAMS ((rtx, int));
  static int sequence_uses_addressof	PARAMS ((rtx));
  static void purge_reg_equiv_notes	PARAMS ((void));
  
--- 37,43 ----
  static rtx skip_use_of_return_value	PARAMS ((rtx, enum rtx_code));
  static rtx skip_stack_adjustment	PARAMS ((rtx));
  static rtx skip_jump_insn		PARAMS ((rtx));
! static int uses_addressof		PARAMS ((rtx));
  static int sequence_uses_addressof	PARAMS ((rtx));
  static void purge_reg_equiv_notes	PARAMS ((void));
  
*************** skip_jump_insn (orig_insn)
*** 237,252 ****
  
  /* Scan the rtx X for ADDRESSOF expressions or
     current_function_internal_arg_pointer registers.
!    INMEM argument should be 1 if we're looking at inner part of some
!    MEM expression, otherwise 0.
!    Return nonzero if an ADDRESSOF expresion is found or if
!    current_function_internal_arg_pointer is found outside of some MEM
!    expression, else return zero.  */
  
  static int
! uses_addressof (x, inmem)
       rtx x;
-      int inmem;
  {
    RTX_CODE code;
    int i, j;
--- 237,248 ----
  
  /* Scan the rtx X for ADDRESSOF expressions or
     current_function_internal_arg_pointer registers.
!    Return nonzero if an ADDRESSOF or current_function_internal_arg_pointer
!    is found outside of some MEM expression, else return zero.  */
  
  static int
! uses_addressof (x)
       rtx x;
  {
    RTX_CODE code;
    int i, j;
*************** uses_addressof (x, inmem)
*** 256,270 ****
      return 0;
  
    code = GET_CODE (x);
- 
-   if (code == ADDRESSOF)
-     return 1;
  
!   if (x == current_function_internal_arg_pointer && ! inmem)
      return 1;
  
    if (code == MEM)
!     return uses_addressof (XEXP (x, 0), 1);
  
    /* Scan all subexpressions. */
    fmt = GET_RTX_FORMAT (code);
--- 252,263 ----
      return 0;
  
    code = GET_CODE (x);
  
!   if (code == ADDRESSOF || x == current_function_internal_arg_pointer)
      return 1;
  
    if (code == MEM)
!     return 0;
  
    /* Scan all subexpressions. */
    fmt = GET_RTX_FORMAT (code);
*************** uses_addressof (x, inmem)
*** 272,284 ****
      {
        if (*fmt == 'e')
  	{
! 	  if (uses_addressof (XEXP (x, i), inmem))
  	    return 1;
  	}
        else if (*fmt == 'E')
  	{
  	  for (j = 0; j < XVECLEN (x, i); j++)
! 	    if (uses_addressof (XVECEXP (x, i, j), inmem))
  	      return 1;
  	}
      }
--- 265,277 ----
      {
        if (*fmt == 'e')
  	{
! 	  if (uses_addressof (XEXP (x, i)))
  	    return 1;
  	}
        else if (*fmt == 'E')
  	{
  	  for (j = 0; j < XVECLEN (x, i); j++)
! 	    if (uses_addressof (XVECEXP (x, i, j)))
  	      return 1;
  	}
      }
*************** sequence_uses_addressof (seq)
*** 318,325 ****
  		&& sequence_uses_addressof (XEXP (PATTERN (insn), 2)))
  	      return 1;
  	  }
! 	else if (uses_addressof (PATTERN (insn), 0)
! 		 || (REG_NOTES (insn) && uses_addressof (REG_NOTES (insn), 0)))
  	  return 1;
        }
    return 0;
--- 311,318 ----
  		&& sequence_uses_addressof (XEXP (PATTERN (insn), 2)))
  	      return 1;
  	  }
! 	else if (uses_addressof (PATTERN (insn))
! 		 || (REG_NOTES (insn) && uses_addressof (REG_NOTES (insn))))
  	  return 1;
        }
    return 0;
*************** optimize_sibling_and_tail_recursive_call
*** 490,503 ****
  	  if (frame_offset)
  	    goto failure;
  
  	  /* alloca (until we have stack slot life analysis) inhibits
  	     sibling call optimizations, but not tail recursion.
- 
- 	     Similarly if we have ADDRESSOF expressions.
- 
  	     Similarly if we use varargs or stdarg since they implicitly
  	     may take the address of an argument.  */
!  	  if (current_function_calls_alloca || current_function_uses_addressof
  	      || current_function_varargs || current_function_stdarg)
  	    sibcall = 0;
  
--- 483,498 ----
  	  if (frame_offset)
  	    goto failure;
  
+ 	  /* Taking the address of a local variable is fatal to tail
+ 	     recursion if the address is used by the recursive call.  */
+ 	  if (current_function_uses_addressof)
+ 	    goto failure;
+ 
  	  /* alloca (until we have stack slot life analysis) inhibits
  	     sibling call optimizations, but not tail recursion.
  	     Similarly if we use varargs or stdarg since they implicitly
  	     may take the address of an argument.  */
!  	  if (current_function_calls_alloca
  	      || current_function_varargs || current_function_stdarg)
  	    sibcall = 0;
  
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/stmt.c,v
retrieving revision 1.156
diff -c -p -d -r1.156 stmt.c
*** stmt.c	2000/08/06 10:07:30	1.156
--- stmt.c	2000/08/12 16:24:33
*************** expand_return (retval)
*** 2809,2817 ****
    rtx last_insn = 0;
    rtx result_rtl = DECL_RTL (DECL_RESULT (current_function_decl));
    register rtx val = 0;
- #ifdef HAVE_return
-   register rtx op0;
- #endif
    tree retval_rhs;
    int cleanups;
  
--- 2809,2814 ----
*************** expand_return (retval)
*** 2884,2965 ****
        end_cleanup_deferral ();
        return;
      }
- 
-   /* Attempt to optimize the call if it is tail recursive.  */
-   if (flag_optimize_sibling_calls
-       && retval_rhs != NULL_TREE
-       && frame_offset == 0
-       && TREE_CODE (retval_rhs) == CALL_EXPR
-       && TREE_CODE (TREE_OPERAND (retval_rhs, 0)) == ADDR_EXPR
-       && (TREE_OPERAND (TREE_OPERAND (retval_rhs, 0), 0)
- 	  == current_function_decl)
-       && optimize_tail_recursion (TREE_OPERAND (retval_rhs, 1), last_insn))
-     return;
- 
- #ifdef HAVE_return
-   /* This optimization is safe if there are local cleanups
-      because expand_null_return takes care of them.
-      ??? I think it should also be safe when there is a cleanup label,
-      because expand_null_return takes care of them, too.
-      Any reason why not?  */
-   if (HAVE_return && cleanup_label == 0
-       && ! current_function_returns_pcc_struct
-       && BRANCH_COST <= 1)
-     {
-       /* If this is  return x == y;  then generate
- 	 if (x == y) return 1; else return 0;
- 	 if we can do it with explicit return insns and branches are cheap,
- 	 but not if we have the corresponding scc insn.  */
-       int has_scc = 0;
-       if (retval_rhs)
- 	switch (TREE_CODE (retval_rhs))
- 	  {
- 	  case EQ_EXPR:
- #ifdef HAVE_seq
- 	    has_scc = HAVE_seq;
- #endif
- 	  case NE_EXPR:
- #ifdef HAVE_sne
- 	    has_scc = HAVE_sne;
- #endif
- 	  case GT_EXPR:
- #ifdef HAVE_sgt
- 	    has_scc = HAVE_sgt;
- #endif
- 	  case GE_EXPR:
- #ifdef HAVE_sge
- 	    has_scc = HAVE_sge;
- #endif
- 	  case LT_EXPR:
- #ifdef HAVE_slt
- 	    has_scc = HAVE_slt;
- #endif
- 	  case LE_EXPR:
- #ifdef HAVE_sle
- 	    has_scc = HAVE_sle;
- #endif
- 	  case TRUTH_ANDIF_EXPR:
- 	  case TRUTH_ORIF_EXPR:
- 	  case TRUTH_AND_EXPR:
- 	  case TRUTH_OR_EXPR:
- 	  case TRUTH_NOT_EXPR:
- 	  case TRUTH_XOR_EXPR:
- 	    if (! has_scc)
- 	      {
- 		op0 = gen_label_rtx ();
- 		jumpifnot (retval_rhs, op0);
- 		expand_value_return (const1_rtx);
- 		emit_label (op0);
- 		expand_value_return (const0_rtx);
- 		return;
- 	      }
- 	    break;
- 
- 	  default:
- 	    break;
- 	  }
-     }
- #endif /* HAVE_return */
  
    /* If the result is an aggregate that is being returned in one (or more)
       registers, load the registers here.  The compiler currently can't handle
--- 2881,2886 ----
>From pedwards@disaster.jaj.com Sat Aug 12 13:01:00 2000
From: Phil Edwards <pedwards@disaster.jaj.com>
To: brent@rcfile.org, fwx@home.com
Cc: gcc-bugs@gcc.gnu.org
Subject: Re: c++ library bug report
Date: Sat, 12 Aug 2000 13:01:00 -0000
Message-id: <200008122003.QAA02188@disaster.jaj.com>
X-SW-Source: 2000-08/msg00267.html
Content-length: 521

brent verner <brent@rcfile.org>:
> On 11 Aug 2000 at 14:40 (-0700), Forest Wilkinson wrote:
> | Where should I report a bug in the C++ library that is distributed with
> | gcc?
>
> If the bug report is against libstdc++-v3, send email to 
> libstdc++@sources.redhat.com. If you have any problems with sending the
> email (becuase/if you're not subscribed),

Last I heard, the list didn't require a subscription before sending to it.
Has that changed?  (If it has, I need to update one of the -v3 web pages.)


Tnx,
Phil


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  2003-03-10 14:24 optimization bug surjan
@ 2003-03-10 15:31 ` Tim Prince
  0 siblings, 0 replies; 31+ messages in thread
From: Tim Prince @ 2003-03-10 15:31 UTC (permalink / raw)
  To: surjan, gcc-bugs; +Cc: bug-gcc

On Monday 10 March 2003 05:28, surjan@coulson.chem.elte.hu wrote:
> Dear Sir:
>          The attached fortran code, named optbug.f, compiles
> with g77 without any message. I use gcc-g77-2.96-112.7.2. Issuing the
> command
>
>                            g77 -o bug optbug.f
> or
>                            g77 -O1 -o bug optbug.f
> we get an executable producing the correct result:
>                          /scr/surjan> bug
>                           1 -1
> while optimizing the compilation with O2 or higher
>                             g77 -O2 -o bug2 optbug.f
> produces the erroneous answer:
>                         /scr/surjan> bug2
>                           1 -100
>
The current snapshot gcc-3.3/g77 produces your correct result.  gcc-2.96 was 
not a gnu version, and is no longer maintained by anybody.  If I may say so, 
it's an abomination and I have it on one of my systems only because I just 
had to rebuild it after a crash.
-- 
Tim Prince


^ permalink raw reply	[flat|nested] 31+ messages in thread

* optimization bug
@ 2003-03-10 14:24 surjan
  2003-03-10 15:31 ` Tim Prince
  0 siblings, 1 reply; 31+ messages in thread
From: surjan @ 2003-03-10 14:24 UTC (permalink / raw)
  To: gcc-bugs; +Cc: bug-gcc

[-- Attachment #1: Type: text/plain, Size: 1961 bytes --]

Dear Sir:
         The attached fortran code, named optbug.f, compiles 
with g77 without any message. I use gcc-g77-2.96-112.7.2. Issuing the command

                           g77 -o bug optbug.f
or
                           g77 -O1 -o bug optbug.f
we get an executable producing the correct result:
                         /scr/surjan> bug
                          1 -1
while optimizing the compilation with O2 or higher
                            g77 -O2 -o bug2 optbug.f
produces the erroneous answer:
                        /scr/surjan> bug2
                          1 -100
  
The attached 20-line source appears to be somewhat idiotic, but it
is extracted from an old big program producing the same error. The source
complied by the intell ifc compiler or f77 on AIX or UNIX, does not show this
optimization problem. I have neither experienced this bug with previous
versions of gcc-g77.

 The reason why the optimization fails for this particular case is that
the source line 'V1(I)=-V2(1)' may suggest as if the V1(I) value was
independent on I. However, if I=2, the array element V2(1) was already 
determined in the previous cycle (I=1). The O2, O3 and O4 compilations 
overlook this point and substitute the initialized value for V2(1).

 I thought this report might be useful. The bug does not represent a serious
problem for me, since I can easily change the code to avoid such a
situation.

Sincerely Yours:

              Peter Surjan




---------------------------------------------------
          P\'eter R. Surj\'an
          Professor of Chemistry
          E\"otv\"os University, Budapest
          Department of Theoretical Chemistry
location: H-1117 Budapest Pazmany Peter setany 1/A
    mail: H-1518 Budapest P.O.B. 32., Hungary
  e-mail: surjan@para.chem.elte.hu
     FAX: (36)-(1)-209-0602    
     TEL: (36)-(1)-209-0555-1632 (office)
          (36)-(1)-209-0555-1445 (lab)
---------------------------------------------------

[-- Attachment #2: optbug.f --]
[-- Type: text/plain, Size: 908 bytes --]

      INTEGER I,K,L,N,V1,V2
      COMMON/A/V1(2)  
      DIMENSION V2(2)
      V2(1)=100
      L=0                                                           
      N=0                                                            
      DO K=1,1                                                      
       DO I=1,2                                                 
        N=N+1                                                       
        V2(N)=I                                                       
        IF(L.eq.0)then 
         V1(I)=1                                                        
         GO TO 1
        ENDIF
        V1(I)=-V2(1)  
  1    L=L+1                                                     
       ENDDO
      ENDDO                                                             
      WRITE(6,*)(V1(i),i=1,2)
      END                                                               

^ permalink raw reply	[flat|nested] 31+ messages in thread

* optimization bug
@ 2002-01-04  6:20 Calin Cascaval
  0 siblings, 0 replies; 31+ messages in thread
From: Calin Cascaval @ 2002-01-04  6:20 UTC (permalink / raw)
  To: gcc-bugs


The following program gives the wrong result when compiled with optimizations.
The correct output is shown for the non-optimized version.
I have seen the behavior on several machines running RedHat Linux 7.1 and 7.2.
Also, I have tried with two versions of gcc (2.95.3 and 2.96). Same behavior.

/* ---------- machine ----------------------------- */
gccbug> uname -a
Linux pongo.watson.ibm.com 2.4.17 #1 Thu Dec 27 16:55:39 EST 2001 i686 unknown

/* ---------- gcc --------------------------------- */
gccbug> /usr/local/bin/gcc -v
Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.3/specs
gcc version 2.95.3 20010315 (release)

GCC configure options:
	--prefix=/usr/local --enable-languages=c++,c


/*  ------ ceil.c ----------------- */
#include <math.h>
#include <stdio.h>

int main()
{
  printf("%d:%d\n%d:%d\n%d:%d\n", 
	 16, (int)ceil(log(16)/log(2)),
	 32, (int)ceil(log(32)/log(2)),
	 64, (int)ceil(log(64)/log(2)));
	 
  return 0;
}

/* --------------- output ------------------ */
gccbug> /usr/local/bin/gcc ceil.c -lm
gccbug> a.out
16:4
32:5
64:6
gccbug> /usr/local/bin/gcc -O3 ceil.c -lm
gccbug> a.out
16:4
32:6
64:6
gccbug> /usr/local/bin/gcc -O2 ceil.c -lm
gccbug> a.out
16:4
32:6
64:6
gccbug> /usr/local/bin/gcc -O1 ceil.c -lm
gccbug> a.out
16:4
32:6
64:6

Calin Cascaval
IBM TJ Watson Research Center
(914)-945-2635
cascaval@us.ibm.com


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Optimization bug
@ 2000-03-24 12:07 Gerald Gutierrez
  0 siblings, 0 replies; 31+ messages in thread
From: Gerald Gutierrez @ 2000-03-24 12:07 UTC (permalink / raw)
  To: gcc-bugs

Hi. Details:

gcc version 2.95.2 19991024 (release)  
Linux Mandrake 7.0 
Source code is bugs.c. It works without -funroll-loops, or if a number of
things in the source code is removed.

Command line: $g++ -v --save-temps -funroll-loops -O3 bug.c   

Output:
Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux/2.95.2/specs
gcc version 2.95.2 19991024 (release)
 /usr/lib/gcc-lib/i586-mandrake-linux/2.95.2/cpp -lang-c -v -D__GNUC__=2 -D__GNUC_MINOR__=95 -D__ELF__ -Dunix -D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__linux -Asystem(posix) -D__OPTIMIZE__ -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -Di586 -Dpentium -D__i586 -D__i586__ -D__pentium -D__pentium__ bug.c bug.i
GNU CPP version 2.95.2 19991024 (release) (i386 Linux/ELF)
#include "..." search starts here:
#include <...> search starts here:
 /opt/gnome/include
 /z/include
 /usr/local/include
 /usr/lib/gcc-lib/i586-mandrake-linux/2.95.2/include
 /usr/include
End of search list.
The following default directories have been omitted from the search path:
 /home/gerald/include
 
 /usr/lib/gcc-lib/i586-mandrake-linux/2.95.2/../../../../include/g++-3
 /usr/lib/gcc-lib/i586-mandrake-linux/2.95.2/../../../../i586-mandrake-linux/include
End of omitted list.
 /usr/lib/gcc-lib/i586-mandrake-linux/2.95.2/cc1 bug.i -quiet -dumpbase bug.c -O3 -version -funroll-loops -o bug.s
GNU C version 2.95.2 19991024 (release) (i586-mandrake-linux) compiled by GNU C
version 2.95.2 19991024 (release).
gcc: Internal compiler error: program cc1 got fatal signal 11                  


^ permalink raw reply	[flat|nested] 31+ messages in thread

* optimization bug
@ 2000-03-22  1:41 Andrea Latina
  0 siblings, 0 replies; 31+ messages in thread
From: Andrea Latina @ 2000-03-22  1:41 UTC (permalink / raw)
  To: gcc-bugs

When I execute this little program (runge-kutta with adaptive step)
compiled with the option -On (where 'n' > 0), it goes in an infinite
loop. Without optimization runs correctly.

The compilation line is:

g++ runge_kutta.cpp -o runge_kutta -On

I use gcc-2.95.2 on a PentiumIII-RedHat-6.1-linux.

Follow the source.

bye and thanks,
Andrea
/*
** rka.cpp: Solves differential equation
**
**	dx/dt = function(t, x)
**
** using runge-kutta with adaprive step
*/

#include <iostream.h>
#include <math.h>

#define EPSILON_0 	1e-16
#define EPSILON		0.01
#define SAFETY		0.9
#define COEFF		pow(SAFETY / 4, 5)

typedef double (*FUNCTION)(double, double );

template <class T> static T abs(T a) { return a > 0 ? a : -a; }

double function(double t, double x )
{ 
	// the exact solution is x = exp(-t^2/2)

	return -x * t; 
}

double runge_kutta_adaptive_step(FUNCTION func, double &t, double &x, double h )
{
	for(;;)
	{
		const double A1 = func(t, 		x);
		const double A2 = func(t + h / 4,	x + h * A1 / 4);
		const double A3 = func(t + h / 4,	x + h * A2 / 4);
		const double A4 = func(t + h / 2,	x + h * A3 / 2);

		const double x_inter = x + h * (A1 + 2 * (A2 + A3) + A4) / 12;

		const double B1 = func(t + h / 2,	x_inter);
		const double B2 = func(t + 3 * h / 4,	x_inter + h * B1 / 4);
		const double B3 = func(t + 3 * h / 4, 	x_inter + h * B2 / 4);
		const double B4 = func(t + h, 		x_inter + h * B3 / 2);

		const double x_half = x_inter + h * (B1 + 2 * (B2 + B3) + B4) / 12;

		const double C1 = func(t, 		x);
		const double C2 = func(t + h / 2,	x + h * C1 / 2);
		const double C3 = func(t + h / 2,	x + h * C2 / 2);
		const double C4 = func(t + h,		x + h * C3);

		const double x_full = x + h * (C1 + 2 * (C2 + C3) + C4) / 6;

		const double x_temp = x_half - x_full;

		const double delta = abs(x_temp / (h * A1 + EPSILON_0)) / EPSILON;
				
		if (delta <= 1.0)	// increase the step size
		{
			x = x_half + x_temp / 15;
			t = t + h;

			if (delta > COEFF)	h = h * SAFETY / pow(delta, 0.2);
			else			h = h * 4;
		
			break;
		}
		
		h = h * SAFETY / pow(delta, 0.25);
		
		if (h == 0) break;
	}

	return h;
}

double runge_kutta_adaptive(FUNCTION func, double x, double t0, double t1, double h )
{
	while(h != 0 && t0 < t1)	h = runge_kutta_adaptive_step(func, t0, x, h);

    	cout << t0 << " " << x << " (" << exp(-t0 * t0 / 2) << ")" << endl;
					// ^^^^^^^^^^^^^^^^^
					// the exact solution			   
    	return x;
}

int main()
{
    	runge_kutta_adaptive(function, 1, 0, 1, EPSILON);

    	return 0;
}
>From rth@cygnus.com Wed Mar 22 01:45:00 2000
From: Richard Henderson <rth@cygnus.com>
To: Alexandre Oliva <aoliva@cygnus.com>
Cc: Michael Hayes <m.hayes@elec.canterbury.ac.nz>, rth@gcc.gnu.org, gcc-bugs@gcc.gnu.org
Subject: Re: expand_call
Date: Wed, 22 Mar 2000 01:45:00 -0000
Message-id: <20000322014521.A3887@cygnus.com>
References: <14551.14845.51288.27188@ongaonga.elec.canterbury.ac.nz> <orln3cbmsm.fsf@garnize.lsd.ic.unicamp.br>
X-SW-Source: 2000-03/msg00913.html
Content-length: 344

On Tue, Mar 21, 2000 at 08:11:21AM -0300, Alexandre Oliva wrote:
> > This patch breaks the build of a c4x cross compiler when
> > compiling tinfo.cc with -O2.
> 
> Same problem on alpha and hppa, both native.

Eh?  What target triple for the alpha?  I've just bootstrapped
alpha-dec-linux-gnu and alphaev67-dec-linux-gnu without incident.


r~
>From c.galambos@eim.surrey.ac.uk Wed Mar 22 02:17:00 2000
From: Charles Galambos <c.galambos@eim.surrey.ac.uk>
To: gcc-bugs@gcc.gnu.org
Subject: Re: Use of atexit for destructors on Solaris 7.
Date: Wed, 22 Mar 2000 02:17:00 -0000
Message-id: <E12XiCy-0006bV-00@phoebe.eim.surrey.ac.uk>
X-SW-Source: 2000-03/msg00914.html
Content-length: 1258

Hi,

> The problem can be worked-around: Don't use block-local static
> variables... Of course, the other proposed work-around (replace atexit
> function, have compiler emit a different function call) also work.

The only reason I use static functions is so I can garantee initalisation
order.   I use something like the following code fragment in a number of 
places.

MyClassC &AVar() { static MyClassC x; return x; }

This allows me to refer to them in the constructors of other classes that
maybe declared as normal static variables.   This gets around the limits
placed by the standard on the expected order of initalisation order of global 
variables in different files.   This kind of thing is usefull for things like 
dynamicly
creating hash tables of IO routines for all the classes linked into an 
executable.

Since 'atexit' on solaris is function ptr it can be replaced. (Is this part of
the standard ??)  Is there a way I can replace the atexit function before or 
at
least early  in the initilisation of static variables ?    

It would have been good also if failure of the atexit function wasn't silently
ignored, especailly as most implementations seem to have a limit of the
the number of times it can be called.


Thanks,

Charles.








^ permalink raw reply	[flat|nested] 31+ messages in thread

* Optimization bug...
@ 1999-12-31 20:54 Peter R. Torpman
  1999-12-31 20:54 ` Nathan Sidwell
  0 siblings, 1 reply; 31+ messages in thread
From: Peter R. Torpman @ 1999-12-31 20:54 UTC (permalink / raw)
  To: gcc-bugs

Hi!

My environment is the following:

GCC:     2.95.2
OS :     Solaris 2.6
Machine: SunOS ksba43 5.6 Generic_105181-11 sun4u sparc SUNW,Ultra-5_10

The following file cannot be properly compiled when using -O3:

-----------------------------------------------
#include <stdio.h>

static void *array[10];

int dontDoIt = 0;

void x(  ) 
{
  array[0] = &&LABEL;

  if( dontDoIt == 0 ) {
    return;
  }

  LABEL:
  printf("It rules\n");
}


int main( ) 
{
  x();

  goto *array[0];

  return 1;
}
-------------------------------------------------

If compiled with -O2 the printout will be printed once, i.e it works... 
However, if it's compiled with -O3 it will generate a eternal loop for 
the printouts...

I compiled the program like this:

	gcc -O3 x.c -o x


Hope you can fix this for us....

Good Luck!

Regards,
/ Peter
# 1 "x.c"
 




























 


 

# 1 "/usr/include/stdio.h" 1 3
 
 

 
 
 

 






#pragma ident	"@(#)stdio.h	1.49	97/05/09 SMI"	

# 1 "/usr/include/sys/feature_tests.h" 1 3
 
 

 
 
 




#pragma ident	"@(#)feature_tests.h	1.13	97/06/26 SMI"





 











 







































 
















 

















 

























# 17 "/usr/include/stdio.h" 2 3

# 1 "/usr/include/sys/va_list.h" 1 3
 







#pragma ident	"@(#)va_list.h	1.6	96/01/26 SMI"

 













# 41 "/usr/include/sys/va_list.h" 3



typedef void *__va_list;











# 18 "/usr/include/stdio.h" 2 3


 













typedef unsigned int	size_t;


# 52 "/usr/include/stdio.h" 3


# 66 "/usr/include/stdio.h" 3



typedef long		fpos_t;













 










 



















# 122 "/usr/include/stdio.h" 3




















































typedef struct	 
{




	int		_cnt;	 
	unsigned char	*_ptr;	 

	unsigned char	*_base;	 
	unsigned char	_flag;	 
	unsigned char	_file;	 
} FILE;


extern FILE		__iob[20 ];



extern FILE		*_lastbuf;
extern unsigned char	*_bufendtab[];

extern unsigned char	 _sibuf[], _sobuf[];


 
# 222 "/usr/include/stdio.h" 3




extern int	remove(const char *);
extern int	rename(const char *, const char *);
extern FILE	*tmpfile(void);
extern char	*tmpnam(char *);



extern int	fclose(FILE *);
extern int	fflush(FILE *);
extern FILE	*fopen(const char *, const char *);
extern FILE	*freopen(const char *, const char *, FILE *);
extern void	setbuf(FILE *, char *);


extern void setbuffer(FILE *, char *, size_t);
extern int setlinebuf(FILE *);

extern int	setvbuf(FILE *, char *, int, size_t);
 
extern int	fprintf(FILE *, const char *, ...);
 
extern int	fscanf(FILE *, const char *, ...);
 
extern int	printf(const char *, ...);
 
extern int	scanf(const char *, ...);


 
extern int	snprintf(char *, size_t, const char *, ...);

 
extern int	sprintf(char *, const char *, ...);
 
extern int	sscanf(const char *, const char *, ...);
extern int	vfprintf(FILE *, const char *, __va_list);
extern int	vprintf(const char *, __va_list);


extern int	vsnprintf(char *, size_t, const char *, __va_list);

extern int	vsprintf(char *, const char *, __va_list);
extern int	fgetc(FILE *);
extern char	*fgets(char *, int, FILE *);
extern int	fputc(int, FILE *);
extern int	fputs(const char *, FILE *);
extern int	getc(FILE *);
extern int	getchar(void);
extern char	*gets(char *);
extern int	putc(int, FILE *);
extern int	putchar(int);
extern int	puts(const char *);
extern int	ungetc(int, FILE *);
extern size_t	fread(void *, size_t, size_t, FILE *);
extern size_t	fwrite(const void *, size_t, size_t, FILE *);
extern int	fgetpos(FILE *, fpos_t *);
extern int	fseek(FILE *, long, int);
extern int	fsetpos(FILE *, const fpos_t *);
extern long	ftell(FILE *);
extern void	rewind(FILE *);
extern void	clearerr(FILE *);
extern int	feof(FILE *);
extern int	ferror(FILE *);
extern void	perror(const char *);

extern int	__filbuf(FILE *);
extern int	__flsbuf(int, FILE *);

 





extern FILE	*fdopen(int, const char *);
extern char	*ctermid(char *);
extern int	fileno(FILE *);



 


# 319 "/usr/include/stdio.h" 3


 




extern FILE	*popen(const char *, const char *);
extern char	*cuserid(char *);
extern char	*tempnam(const char *, const char *);
extern int	getopt(int, char *const *, const char *);

extern int	getsubopt(char **, char *const *, char **);

extern char	*optarg;
extern int	optind, opterr, optopt;
extern int	getw(FILE *);
extern int	putw(int, FILE *);
extern int	pclose(FILE *);



 







 



# 362 "/usr/include/stdio.h" 3


# 467 "/usr/include/stdio.h" 3



























# 515 "/usr/include/stdio.h" 3









# 35 "x.c" 2


 

 

 

static void *array[10];

int dontDoIt = 0;

void x(  ) 
{
  array[0] = &&LABEL;

  if( dontDoIt == 0 ) {
    return;
  }

  LABEL:
  printf("It rules\n");


}


int main( ) 
{
  x();

  goto *array[0];

  return 1;
}



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Optimization bug...
  1999-12-31 20:54 Optimization bug Peter R. Torpman
@ 1999-12-31 20:54 ` Nathan Sidwell
  0 siblings, 0 replies; 31+ messages in thread
From: Nathan Sidwell @ 1999-12-31 20:54 UTC (permalink / raw)
  To: Peter R. Torpman; +Cc: gcc-bugs

"Peter R. Torpman" wrote:
> static void *array[10];
> 
> int dontDoIt = 0;
> 
> void x(  )
> {
>   array[0] = &&LABEL;
>   LABEL:
> }
> 
> int main( )
> {
>   x();
> 
>   goto *array[0];
> 
>   return 1;
> }
from the info pages
	"You may not use this mechanism to jump to code in a different function.
	If you do that, totally unpredictable things will happen.  The best way to
	avoid this is to store the label address only in automatic variables and
	never pass it as an argument."
You've invoked undefined behaviour, so this is not a bug.

nathan
-- 
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
Never hand someone a gun unless you are sure where they will point it
nathan@acm.org  http://www.cs.bris.ac.uk/~nathan/  nathan@cs.bris.ac.uk


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Optimization bug
@ 1999-03-31 23:54 Hyman Rosen
  1999-03-31 23:54 ` Jeffrey A Law
  0 siblings, 1 reply; 31+ messages in thread
From: Hyman Rosen @ 1999-03-31 23:54 UTC (permalink / raw)
  To: egcs-bugs

Not to long ago, someone posted a patch for optimization problems with
respect to partial word comparisons. This patch never seems to have made
it into release, since the latest snapshot still exhibits the problems.

Here is the test code again. It produces no output when compiled without
optimization, but many failures when compiled with optimization.

/************************************************************************/
#include <stdio.h>

struct a {
        char a, b;
        short c;
};

int
a1()
{
        static struct a x = { 1, 2, ~1 }, y = { 65, 2, ~2 };

        return (x.a == (y.a & ~64) && x.b == y.b);
}

int
a2()
{
        static struct a x = { 1, 66, ~1 }, y = { 1, 2, ~2 };

        return (x.a == y.a && (x.b & ~64) == y.b);
}

int
a3()
{
        static struct a x = { 9, 66, ~1 }, y = { 33, 18, ~2 };

        return ((x.a & ~8) == (y.a & ~32) && (x.b & ~64) == (y.b & ~16));
}

struct b {
        int c;
        short b, a;
};

int
b1()
{
        static struct b x = { ~1, 2, 1 }, y = { ~2, 2, 65 };

        return (x.a == (y.a & ~64) && x.b == y.b);
}

int
b2()
{
        static struct b x = { ~1, 66, 1 }, y = { ~2, 2, 1 };

        return (x.a == y.a && (x.b & ~64) == y.b);
}

int
b3()
{
        static struct b x = { ~1, 66, 9 }, y = { ~2, 18, 33 };

        return ((x.a & ~8) == (y.a & ~32) && (x.b & ~64) == (y.b & ~16));
}

struct c {
        unsigned int c:4, b:14, a:14;
};

int
c1()
{
        static struct c x = { ~1, 2, 1 }, y = { ~2, 2, 65 };

        return (x.a == (y.a & ~64) && x.b == y.b);
}

int
c2()
{
        static struct c x = { ~1, 66, 1 }, y = { ~2, 2, 1 };

        return (x.a == y.a && (x.b & ~64) == y.b);
}

int
c3()
{
        static struct c x = { ~1, 66, 9 }, y = { ~2, 18, 33 };

        return ((x.a & ~8) == (y.a & ~32) && (x.b & ~64) == (y.b & ~16));
}

struct d {
        unsigned int a:14, b:14, c:4;
};

int
d1()
{
        static struct d x = { 1, 2, ~1 }, y = { 65, 2, ~2 };

        return (x.a == (y.a & ~64) && x.b == y.b);
}

int
d2()
{
        static struct d x = { 1, 66, ~1 }, y = { 1, 2, ~2 };

        return (x.a == y.a && (x.b & ~64) == y.b);
}

int
d3()
{
        static struct d x = { 9, 66, ~1 }, y = { 33, 18, ~2 };

        return ((x.a & ~8) == (y.a & ~32) && (x.b & ~64) == (y.b & ~16));
}

struct e {
        int c:4, b:14, a:14;
};

int
e1()
{
        static struct e x = { ~1, -2, -65 }, y = { ~2, -2, -1 };

        return (x.a == (y.a & ~64) && x.b == y.b);
}

int
e2()
{
        static struct e x = { ~1, -2, -1 }, y = { ~2, -66, -1 };

        return (x.a == y.a && (x.b & ~64) == y.b);
}

int
e3()
{
        static struct e x = { ~1, -18, -33 }, y = { ~2, -66, -9 };

        return ((x.a & ~8) == (y.a & ~32) && (x.b & ~64) == (y.b & ~16));
}

struct f {
        int a:14, b:14, c:4;
};

int
f1()
{
        static struct f x = { -65, -2, ~1 }, y = { -1, -2, ~2 };

        return (x.a == (y.a & ~64) && x.b == y.b);
}

int
f2()
{
        static struct f x = { -1, -2, ~1 }, y = { -1, -66, ~2 };

        return (x.a == y.a && (x.b & ~64) == y.b);
}

int
f3()
{
        static struct f x = { -33, -18, ~1 }, y = { -9, -66, ~2 };

        return ((x.a & ~8) == (y.a & ~32) && (x.b & ~64) == (y.b & ~16));
}

struct gx {
        int c:4, b:14, a:14;
};
struct gy {
        int b:14, a:14, c:4;
};

int
g1()
{
        static struct gx x = { ~1, -2, -65 };
        static struct gy y = { -2, -1, ~2 };

        return (x.a == (y.a & ~64) && x.b == y.b);
}

int
g2()
{
        static struct gx x = { ~1, -2, -1 };
        static struct gy y = { -66, -1, ~2 };

        return (x.a == y.a && (x.b & ~64) == y.b);
}

int
g3()
{
        static struct gx x = { ~1, -18, -33 };
        static struct gy y = { -66, -9, ~2 };

        return ((x.a & ~8) == (y.a & ~32) && (x.b & ~64) == (y.b & ~16));
}

int
g4()
{
        static struct gx x = { ~1, 0x0020, 0x0010 };
        static struct gy y = { 0x0200, 0x0100, ~2 };

        return!((x.a & 0x00f0) == (y.a & 0x0f00) &&
                (x.b & 0x00f0) == (y.b & 0x0f00));
}

int
g5()
{
        static struct gx x = { ~1, 0x0200, 0x0100 };
        static struct gy y = { 0x0020, 0x0010, ~2 };

        return!((x.a & 0x0f00) == (y.a & 0x00f0) &&
                (x.b & 0x0f00) == (y.b & 0x00f0));
}

int
g6()
{
        static struct gx x = { ~1, 0xfe20, 0xfd10 };
        static struct gy y = { 0xc22f, 0xc11f, ~2 };

        return ((x.a & 0x03ff) == (y.a & 0x3ff0) &&
                (x.b & 0x03ff) == (y.b & 0x3ff0));
}

int
g7()
{
        static struct gx x = { ~1, 0xc22f, 0xc11f };
        static struct gy y = { 0xfe20, 0xfd10, ~2 };

        return ((x.a & 0x3ff0) == (y.a & 0x03ff) &&
                (x.b & 0x3ff0) == (y.b & 0x03ff));
}

struct hx {
        int a:14, b:14, c:4;
};
struct hy {
        int c:4, a:14, b:14;
};

int
h1()
{
        static struct hx x = { -65, -2, ~1 };
        static struct hy y = { ~2, -1, -2 };

        return (x.a == (y.a & ~64) && x.b == y.b);
}

int
h2()
{
        static struct hx x = { -1, -2, ~1 };
        static struct hy y = { ~2, -1, -66 };

        return (x.a == y.a && (x.b & ~64) == y.b);
}

int
h3()
{
        static struct hx x = { -33, -18, ~1 };
        static struct hy y = { ~2, -9, -66 };

        return ((x.a & ~8) == (y.a & ~32) && (x.b & ~64) == (y.b & ~16));
}

int
h4()
{
        static struct hx x = { 0x0010, 0x0020, ~1 };
        static struct hy y = { ~2, 0x0100, 0x0200 };

        return!((x.a & 0x00f0) == (y.a & 0x0f00) &&
                (x.b & 0x00f0) == (y.b & 0x0f00));
}

int
h5()
{
        static struct hx x = { 0x0100, 0x0200, ~1 };
        static struct hy y = { ~2, 0x0010, 0x0020 };

        return!((x.a & 0x0f00) == (y.a & 0x00f0) &&
                (x.b & 0x0f00) == (y.b & 0x00f0));
}

int
h6()
{
        static struct hx x = { 0xfd10, 0xfe20, ~1 };
        static struct hy y = { ~2, 0xc11f, 0xc22f };

        return ((x.a & 0x03ff) == (y.a & 0x3ff0) &&
                (x.b & 0x03ff) == (y.b & 0x3ff0));
}

int
h7()
{
        static struct hx x = { 0xc11f, 0xc22f, ~1 };
        static struct hy y = { ~2, 0xfd10, 0xfe20 };

        return ((x.a & 0x3ff0) == (y.a & 0x03ff) &&
                (x.b & 0x3ff0) == (y.b & 0x03ff));
}

int
main()
{
        if (!a1()) printf("a1 FAIL\n");
        if (!a2()) printf("a2 FAIL\n");
        if (!a3()) printf("a3 FAIL\n");
        if (!b1()) printf("b1 FAIL\n");
        if (!b2()) printf("b2 FAIL\n");
        if (!b3()) printf("b3 FAIL\n");
        if (!c1()) printf("c1 FAIL\n");
        if (!c2()) printf("c2 FAIL\n");
        if (!c3()) printf("c3 FAIL\n");
        if (!d1()) printf("d1 FAIL\n");
        if (!d2()) printf("d2 FAIL\n");
        if (!d3()) printf("d3 FAIL\n");
        if (!e1()) printf("e1 FAIL\n");
        if (!e2()) printf("e2 FAIL\n");
        if (!e3()) printf("e3 FAIL\n");
        if (!f1()) printf("f1 FAIL\n");
        if (!f2()) printf("f2 FAIL\n");
        if (!f3()) printf("f3 FAIL\n");
        if (!g1()) printf("g1 FAIL\n");
        if (!g2()) printf("g2 FAIL\n");
        if (!g3()) printf("g3 FAIL\n");
        if (!g4()) printf("g4 FAIL\n");
        if (!g5()) printf("g5 FAIL\n");
        if (!g6()) printf("g6 FAIL\n");
        if (!g7()) printf("g7 FAIL\n");
        if (!h1()) printf("h1 FAIL\n");
        if (!h2()) printf("h2 FAIL\n");
        if (!h3()) printf("h3 FAIL\n");
        if (!h4()) printf("h4 FAIL\n");
        if (!h5()) printf("h5 FAIL\n");
        if (!h6()) printf("h6 FAIL\n");
        if (!h7()) printf("h7 FAIL\n");
}


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Optimization bug
  1999-03-31 23:54 Hyman Rosen
@ 1999-03-31 23:54 ` Jeffrey A Law
  1999-03-31 23:54   ` Hyman Rosen
  0 siblings, 1 reply; 31+ messages in thread
From: Jeffrey A Law @ 1999-03-31 23:54 UTC (permalink / raw)
  To: Hyman Rosen; +Cc: egcs-bugs

  In message < 199903242130.QAA17947@panix7.panix.com >you write:
  > Not to long ago, someone posted a patch for optimization problems with
  > respect to partial word comparisons. This patch never seems to have made
  > it into release, since the latest snapshot still exhibits the problems.
  > 
  > Here is the test code again. It produces no output when compiled without
  > optimization, but many failures when compiled with optimization.
It's in the queue, but hasn't been reviewed yet.

Also note the test has endianness issues that need to be resolved before it
can be installed.

jeff


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Optimization bug
  1999-03-31 23:54 ` Jeffrey A Law
@ 1999-03-31 23:54   ` Hyman Rosen
  0 siblings, 0 replies; 31+ messages in thread
From: Hyman Rosen @ 1999-03-31 23:54 UTC (permalink / raw)
  To: law; +Cc: egcs-bugs

Jeffrey A. Law writes:
 > Also note the test has endianness issues that need to be resolved before it
 > can be installed.

It does? From my quick look at the code, I see nothing but ordinary C
arithmetic. It's not the code that's doing any fiddling with more than
one field at a time, it's the compiler.


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Optimization bug
  1998-10-12 11:18 Optimization bug Phillip Ezolt
@ 1999-01-13  5:41 ` Jeffrey A Law
  0 siblings, 0 replies; 31+ messages in thread
From: Jeffrey A Law @ 1999-01-13  5:41 UTC (permalink / raw)
  To: Phillip Ezolt; +Cc: egcs-bugs

--
Jeff Law (law@cygnus.com)
Cygnus Solutions		EGCS GNU Compiler System
http://www.cygnus.com		http://www.cygnus.com/egcs

  In message <Pine.OSF.3.96.981012123719.6060A-100000@perf.zko.dec.com>you writ
e:
  > Hi,	
  > 	I was working on porting the upcoming SPEC CPU99 benchmark suite to
  > Alpha/Linux and I stumbled on the following compiler bug. 
  > 
  > First, it is only appearant when compiling with optimizations.
  > (Since we are going for high-power numbers we NEED to use optimizations)
  > 
  > -O..-O4 breaks compilation.
  > 
  > This file is part of "perl" (pp.c), so I am kind of surprised that nobody
  > else has jumped up screaming.  
  > 
  > The Computer is an alpha ev5 running Redhat linux 5.1.  Egcs version is 1.1
  > b. 
  >  
[ ... ]
  > toplev.c:1360: Internal compiler error in function fatal_insn       
  > 
  > And the corresponding pp.i file:
  > # 1 "pp.c"
  > 
  > static unsigned long seed(void)
  > {
  >     unsigned long u;
  >     u = getpid();
  >     u = 26107 * (unsigned long)&u;
  >     return u;
  > }
Thanks for the bug report.  This seems to be working fine with current egcs
snapshots.

jeff


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1998-10-27  8:56       ` Dima Volodin
@ 1998-10-27 11:04         ` Alexandre Oliva
  1998-10-27  9:54           ` Dima Volodin
  0 siblings, 1 reply; 31+ messages in thread
From: Alexandre Oliva @ 1998-10-27 11:04 UTC (permalink / raw)
  To: Dima Volodin; +Cc: Valentin Bonnard, egcs-bugs

Dima Volodin <dvv@dvv.ru> writes:

> Did I, really? Can you quote the chapter and verse where it reads that
> passing an argument by reference is a dereference?

Passing it by reference is not a dereference, but *(T*)0 is, even if
it is only used as an lvalue.  A long thread is going on in
comp.std.c++ about a similar issue, namely, is &array[3] valid if
array is define to have three element?  Or must one use array+3?

> Anyway, changing the reference to the "dereferenced" zero pointer to a
> reference to any other object doesn't change the compiler's behavior a
> little bit.

Certainly

-- 
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:oliva@gnu.org mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
@ 1998-10-27 11:04 Valentin Bonnard
  0 siblings, 0 replies; 31+ messages in thread
From: Valentin Bonnard @ 1998-10-27 11:04 UTC (permalink / raw)
  To: Dima Volodin, Alexandre Oliva; +Cc: egcs-bugs

A (At) 12:50 27/10/98, Dima Volodin ecrivait (wrote):

>> comp.std.c++ about a similar issue, namely, is &array[3] valid if
>> array is define to have three element?  Or must one use array+3?

>And what if you re-define & for the base class of _array_ here? 

This case is explicitly eliminated (as a special case).

>Anyway, has
>this thread ended with any definitive outcome? 

To me, it has always been very clear that the behaviour is undefined 
and no one had any arguments proving the contrary. The issue isn't 
how the behaviour should be defined but how it is actually defined.

You can't dereference a null pointer. There isn't any ambiguity.

>As of my own opinion - I
>tend to consider passing *(T*)0 by reference as a perfectly valid construct
>(together with this &array[3]) as 

It isn't

>I don't see it any more different (and
>dangerous) than the zero pointer.

I agree. They are as undefined as each other.


Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1998-10-27 11:04         ` Alexandre Oliva
@ 1998-10-27  9:54           ` Dima Volodin
  0 siblings, 0 replies; 31+ messages in thread
From: Dima Volodin @ 1998-10-27  9:54 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: Valentin Bonnard, egcs-bugs

Alexandre Oliva wrote:

> Dima Volodin <dvv@dvv.ru> writes:
>
> > Did I, really? Can you quote the chapter and verse where it reads that
> > passing an argument by reference is a dereference?
>
> Passing it by reference is not a dereference, but *(T*)0 is, even if
> it is only used as an lvalue.  A long thread is going on in

> comp.std.c++ about a similar issue, namely, is &array[3] valid if
> array is define to have three element?  Or must one use array+3?

And what if you re-define & for the base class of _array_ here? Anyway, has
this thread ended with any definitive outcome? As of my own opinion - I
tend to consider passing *(T*)0 by reference as a perfectly valid construct
(together with this &array[3]) as I don't see it any more different (and
dangerous) than the zero pointer.

> Alexandre Oliva

Cheers

Dima



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1998-10-26 18:00     ` Alexandre Oliva
@ 1998-10-27  8:56       ` Dima Volodin
  1998-10-27 11:04         ` Alexandre Oliva
  0 siblings, 1 reply; 31+ messages in thread
From: Dima Volodin @ 1998-10-27  8:56 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: Valentin Bonnard, egcs-bugs

Did I, really? Can you quote the chapter and verse where it reads that
passing an argument by reference is a dereference?

Anyway, changing the reference to the "dereferenced" zero pointer to a
reference to any other object doesn't change the compiler's behavior a
little bit.

Cheers

Dima

Alexandre Oliva wrote:

> Dima Volodin <dvv@dvv.ru> writes:
>
> > And, BTW, what's so undefined about my program's behavior?
>
> You dereferenced a NULL pointer.
>
> --
> Alexandre Oliva
> mailto:oliva@dcc.unicamp.br mailto:oliva@gnu.org mailto:aoliva@acm.org
> http://www.dcc.unicamp.br/~oliva
> Universidade Estadual de Campinas, SP, Brasil



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1998-10-25 17:41   ` Dima Volodin
@ 1998-10-26 18:00     ` Alexandre Oliva
  1998-10-27  8:56       ` Dima Volodin
  0 siblings, 1 reply; 31+ messages in thread
From: Alexandre Oliva @ 1998-10-26 18:00 UTC (permalink / raw)
  To: Dima Volodin; +Cc: Valentin Bonnard, egcs-bugs

Dima Volodin <dvv@dvv.ru> writes:

> And, BTW, what's so undefined about my program's behavior?

You dereferenced a NULL pointer.

-- 
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:oliva@gnu.org mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
@ 1998-10-25 21:47 Kaoru Fukui
  0 siblings, 0 replies; 31+ messages in thread
From: Kaoru Fukui @ 1998-10-25 21:47 UTC (permalink / raw)
  To: Dima Volodin, Valentin Bonnard; +Cc: egcs-bugs

Hi!
I have the same problem.
I am useing egcs-1.1branch  from cvs  at 22th Oct. gcc version egcs-2.91.57.


$ cat test.cxx
#include <iostream.h>
class BaseClass {
  public:
        virtual void SayHello() = 0;
};
int main()
{
        class LocalClass : public BaseClass {
          public:
                void SayHello() { cout << "Hello" << endl; }
        };
        LocalClass l;
        l.SayHello();
        return 0;
}

When compiled with -O0  is Ok, But----

$ g++ test.cxx
$ ./a.out
Hello

When compiled with -O2 is fail.

$ g++ -O2 test.cxx
/tmp/cc90fTLK.o(.gnu.linkonce.d._vt.Q26main.0_10LocalClass+0xc): \
	undefined reference to `SayHello__Q26main.0_10LocalClass.280'
collect2: ld returned 1 exit status

Thanks 
Kaoru Fukui
k_fukui@highway.ne.jp
>From law@cygnus.com Sun Oct 25 21:47:00 1998
From: Jeffrey A Law <law@cygnus.com>
To: Jason Merrill <jason@cygnus.com>
Cc: gdt@linuxppc.org (Gary Thomas), egcs-bugs@cygnus.com
Subject: Re: Bad code from egcs-1.1b 
Date: Sun, 25 Oct 1998 21:47:00 -0000
Message-id: <14829.909380819@hurl.cygnus.com>
References: <u9g1cbc2u2.fsf@yorick.cygnus.com>
X-SW-Source: 1998-10/msg00684.html
Content-length: 2597

  In message < u9g1cbc2u2.fsf@yorick.cygnus.com >you write:
  > >>>>> Jeffrey A Law <law@cygnus.com> writes:
  > 
  >  > jump.c::duplicate_loop_exit_test simply refuses to roll loops in this
  >  > manner if it finds a BLOCK_{BEGIN,END} note.  We could do the same.  I
  >  > don't see many alternatives.
  > 
  > The jump code refuses because duplicating the notes is invalid.  Moving
  > them isn't, so long as the order is preserved, and it seems to me that the
  > order would only be broken iff the test contains block notes and the loop
  > body contains block notes.  That seems quite testable.
Well, if jump.c moved them, then we'd probably be in the same boat as we
are in stmt.c :-)  Though possibly it wouldn't be able to since the cleanup
code would have been inserted which may (or may not) inhibit the optimization.

  > Another possibility would be to associate the fixup with something
  > other than a block; perhaps a code_label?
This is interesting.  Assuming I understand the problem, you actually don't
want to associate with the note or any existing label, but instead the edge
as you leave an inner scope to an outer scope.

We don't want to associate with the inner scope due to the problem we're
trying to solve now.

We don't want to associate with anything that currently exists in the outer
scope because any point we select may potentially be reachable from multiple
threads of control.

Instead we want to run cleanups after we exit the inner scope, but before we
enter the outer scope.  Any optimizer geeks still listening may recognize this
as nearly idential to critical edge problems in global optimizers.

We solve those problems by creating a new intermediate block to hold instructions
which can't be placed at either the head or tail of an edge.  We can use the
same technique here I suspect.


We associate the cleanup with a new label and redirect jumps out of the inner
scope to this new label.  After the new label, we have a jump to the target
label in the outer scope.  We insert our cleanup code after the new label, but
before the jump to the outer scope.

This is probably more complicated than we want to tackle at the moment (then
again, for someone familiar with this code, maybe not).

  >  > Is there any way to distinguish between a random BLOCK_{BEG,END} and one
  >  > used for placement of cleanups?
  > 
  > You could scan goto_fixup_chain, I suppose.  See expand_fixup for how they
  > are created.
Yea, that looks pretty straightforward.  I can do this if you don't want to
try and tackle the potential solution I mentioned above.

jeff


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1998-10-25 12:17 ` Valentin Bonnard
@ 1998-10-25 17:41   ` Dima Volodin
  1998-10-26 18:00     ` Alexandre Oliva
  0 siblings, 1 reply; 31+ messages in thread
From: Dima Volodin @ 1998-10-25 17:41 UTC (permalink / raw)
  To: Valentin Bonnard; +Cc: egcs-bugs

My intention was not to find a shortest possible demonstration of any
bug, I just happened to come across this particular bug quite
accidentally. And, BTW, what's so undefined about my program's behavior?

Dima

On Sun, 25 Oct 1998 21:17:38 +0100, you wrote:

>Dima Volodin wrote:
>
>> The same thing w/o -O works OK. This one was tested on Solaris x86 and
>> Solaris Sparc. The results are absolutely the same.
>
>Well, you program invokes undefined behaviour and thus ins't garantied 
>to compile anyway. Here is a program which doesn't invoke undefined 
>behaviour and is way shorter:
>
>struct Base
>{
>  virtual void foo () = 0;
>};
>
>int main ()
>{
>  struct Der :  Base
>  {
>    void foo ()
>      {
>      }
>  } l;
>}
>
>produces
>
>/var/tmp/cchOM1Q1%O(.gnu.linkonce.d._vt.Q26main.0_3Der+0xc): undefined
>reference to `foo__Q26main.0_3Der.2'
>collect2: ld returned 1 exit status
>
>when compiled with -O. Version is: 
>
>Reading specs from
>/usr/local/util/packages/egcs-050798/lib/gcc-lib/sparc-sun-solaris2.5/egcs-2.91.45/specs
>gcc version egcs-2.91.45 19980704 (gcc2 ss-980609 experimental)
>
>-- 
>
>Valentin Bonnard                mailto:bonnardv@pratique.fr
>info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/
>



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1998-10-22 10:56 Dima Volodin
@ 1998-10-25 12:17 ` Valentin Bonnard
  1998-10-25 17:41   ` Dima Volodin
  0 siblings, 1 reply; 31+ messages in thread
From: Valentin Bonnard @ 1998-10-25 12:17 UTC (permalink / raw)
  To: Dima Volodin; +Cc: egcs-bugs

Dima Volodin wrote:

> The same thing w/o -O works OK. This one was tested on Solaris x86 and
> Solaris Sparc. The results are absolutely the same.

Well, you program invokes undefined behaviour and thus ins't garantied 
to compile anyway. Here is a program which doesn't invoke undefined 
behaviour and is way shorter:

struct Base
{
  virtual void foo () = 0;
};

int main ()
{
  struct Der :  Base
  {
    void foo ()
      {
      }
  } l;
}

produces

/var/tmp/cchOM1Q1%O(.gnu.linkonce.d._vt.Q26main.0_3Der+0xc): undefined
reference to `foo__Q26main.0_3Der.2'
collect2: ld returned 1 exit status

when compiled with -O. Version is: 

Reading specs from
/usr/local/util/packages/egcs-050798/lib/gcc-lib/sparc-sun-solaris2.5/egcs-2.91.45/specs
gcc version egcs-2.91.45 19980704 (gcc2 ss-980609 experimental)

-- 

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/


^ permalink raw reply	[flat|nested] 31+ messages in thread

* optimization bug
@ 1998-10-22 10:56 Dima Volodin
  1998-10-25 12:17 ` Valentin Bonnard
  0 siblings, 1 reply; 31+ messages in thread
From: Dima Volodin @ 1998-10-22 10:56 UTC (permalink / raw)
  To: egcs-bugs

The same thing w/o -O works OK. This one was tested on Solaris x86 and
Solaris Sparc. The results are absolutely the same.


Cheers

Dima



==== 00.cc ====
#include <iostream.h>

class L
{
public:
        virtual int operator () () = 0;
};

void
p (L& f)
{
        class LL : public L
        {
        public:
                int x;

                int internal ()
                {
                        return ++x;
                }

                int operator () ()
                {
                        return internal ();
                }

        } l;

        l.x = 0;

        if (&f == 0) p (l);
        else         cout << f();

        cout << l.x;
}

int
main ()
{
        p (*(L*)0);

        cout << endl;
}


==== g++ -v -O 00.cc ====
Reading specs from
/usr/local/lib/gcc-lib/i586--solaris2.6/egcs-2.91.57/specs
gcc version egcs-2.91.57 19980901 (egcs-1.1 release)
 /usr/local/lib/gcc-lib/i586--solaris2.6/egcs-2.91.57/cpp -lang-c++ -v
-undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -D__GNUC_MINOR__=91
-Dunix -D__svr4__ -D__SVR4 -Dsun -D__unix__ -D__svr4__ -D__SVR4
-D__sun__ -D__unix -D__sun -Asystem(svr4) -D__EXCEPTIONS -D__OPTIMIZE__
-Asystem(unix) -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__
-Di586 -Dpentium -D__i586 -D__i586__ -D__pentium -D__pentium__ 00.cc
/var/tmp/cc7Z02yJ.ii
GNU CPP version egcs-2.91.57 19980901 (egcs-1.1 release) (i386 System V
Release 4)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include/g++
 /usr/local/include
 /usr/local/i586--solaris2.6/include
 /usr/local/lib/gcc-lib/i586--solaris2.6/egcs-2.91.57/include
 /usr/include
End of search list.
 /usr/local/lib/gcc-lib/i586--solaris2.6/egcs-2.91.57/cc1plus
/var/tmp/cc7Z02yJ.ii -quiet -dumpbase 00.cc -O -version -o
/var/tmp/cckAVDWE.s
GNU C++ version egcs-2.91.57 19980901 (egcs-1.1 release)
(i586--solaris2.6) compiled by GNU C version 2.8.1.
 /usr/local/i586--solaris2.6/bin/as -V -Qy -o /var/tmp/ccYAxHz5.o
/var/tmp/cckAVDWE.s
GNU assembler version 2.8.1 (i586--solaris2.6), using BFD version 2.8.1
 /usr/local/lib/gcc-lib/i586--solaris2.6/egcs-2.91.57/collect2 -V -Y
P,/usr/ccs/lib:/usr/lib -Qy
/usr/local/lib/gcc-lib/i586--solaris2.6/egcs-2.91.57/crt1.o
/usr/local/lib/gcc-lib/i586--solaris2.6/egcs-2.91.57/crti.o
/usr/ccs/lib/values-Xa.o
/usr/local/lib/gcc-lib/i586--solaris2.6/egcs-2.91.57/crtbegin.o
-L/usr/local/lib/gcc-lib/i586--solaris2.6/egcs-2.91.57
-L/usr/local/i586--solaris2.6/lib -L/usr/ccs/bin -L/usr/ccs/lib
-L/usr/local/lib /var/tmp/ccYAxHz5.o -lstdc++ -lm -lgcc -lc -lgcc
/usr/local/lib/gcc-lib/i586--solaris2.6/egcs-2.91.57/crtend.o
/usr/local/lib/gcc-lib/i586--solaris2.6/egcs-2.91.57/crtn.o
ld: Software Generation Utilities - Solaris/ELF (3.0)
Undefined                       first referenced
 symbol                             in file
__cl__Q29p__FR1L.0_2LL.283          /var/tmp/ccYAxHz5.o
ld: fatal: Symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Optimization bug
@ 1998-10-12 11:18 Phillip Ezolt
  1999-01-13  5:41 ` Jeffrey A Law
  0 siblings, 1 reply; 31+ messages in thread
From: Phillip Ezolt @ 1998-10-12 11:18 UTC (permalink / raw)
  To: egcs-bugs

Hi,	
	I was working on porting the upcoming SPEC CPU99 benchmark suite to
Alpha/Linux and I stumbled on the following compiler bug. 

First, it is only appearant when compiling with optimizations.
(Since we are going for high-power numbers we NEED to use optimizations)

-O..-O4 breaks compilation.

This file is part of "perl" (pp.c), so I am kind of surprised that nobody
else has jumped up screaming.  

The Computer is an alpha ev5 running Redhat linux 5.1.  Egcs version is 1.1b. 
 
[ezolt@cpu98 egcs_bug]$ gcc -v --save-temps -O -o pp.o  pp.c
Reading specs from /usr/local/lib/gcc-lib/alphaev5-unknown-linux-gnu/egcs-2.91.5
7/specs
gcc version egcs-2.91.57 19980901 (egcs-1.1 release)
 /usr/local/lib/gcc-lib/alphaev5-unknown-linux-gnu/egcs-2.91.57/cpp -lang-c -v -
undef -D__GNUC__=2 -D__GNUC_MINOR__=91 -Dlinux -Dunix -D_LONGLONG -D__ELF__ -D__
linux__ -D__unix__ -D_LONGLONG -D__ELF__ -D__linux -D__unix -Asystem(linux) -D__
OPTIMIZE__ -D__LANGUAGE_C__ -D__LANGUAGE_C -DLANGUAGE_C -Acpu(alpha) -Amachine(a
lpha) -D__alpha -D__alpha__ -D__alpha_ev5__ -Acpu(ev5) pp.c pp.i
GNU CPP version egcs-2.91.57 19980901 (egcs-1.1 release) (Alpha GNU/Linux for EL
F)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/local/alphaev5-unknown-linux-gnu/include
 /usr/local/lib/gcc-lib/alphaev5-unknown-linux-gnu/egcs-2.91.57/include
 /usr/include
End of search list.
 /usr/local/lib/gcc-lib/alphaev5-unknown-linux-gnu/egcs-2.91.57/cc1 pp.i -quiet
-dumpbase pp.c -O -version -o pp.s
GNU C version egcs-2.91.57 19980901 (egcs-1.1 release) (alphaev5-unknown-linux-g
nu) compiled by GNU C version egcs-2.90.27 980315 (egcs-1.0.2 release).
pp.c: In function `seed':
pp.c:16: internal error--unrecognizable insn:
(insn 48 20 21 (set (reg:DI 4 $4)
        (mult:DI (reg:DI 30 $30)
            (const_int 4))) -1 (nil)
    (nil))
toplev.c:1360: Internal compiler error in function fatal_insn       

And the corresponding pp.i file:
# 1 "pp.c"

static unsigned long seed(void)
{
    unsigned long u;
    u = getpid();
    u = 26107 * (unsigned long)&u;
    return u;
}

If you need any more info (Or need me to test something out..) feel free to contact me. 

Thanks,
--Phil

Digital/Compaq High Performance Servers/Benchmark Engineering
Phillip.Ezolt@compaq.com



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1997-09-21 18:07 optimization bug Weiwen Liu
  1997-09-21 21:28 ` Jeffrey A Law
@ 1997-11-02 22:26 ` Jeffrey A Law
  1 sibling, 0 replies; 31+ messages in thread
From: Jeffrey A Law @ 1997-11-02 22:26 UTC (permalink / raw)
  To: Weiwen Liu; +Cc: egcs-bugs

  In message <Pine.OSF.3.96.970921210021.4151A-100000@hepunix1.physics.yale.edu write:
  > Hi, 
  > I reported the following bug in a previous email which is attached below.
  > 
  > I found that the bug is due to replace a register in a USE RTL with
  > its value.
I believe this has been fixed for the next egcs snapshot.

jeff


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1997-09-23 13:08         ` Jim Wilson
@ 1997-09-24  7:51           ` Weiwen Liu
  0 siblings, 0 replies; 31+ messages in thread
From: Weiwen Liu @ 1997-09-24  7:51 UTC (permalink / raw)
  To: Jim Wilson; +Cc: egcs-bugs, law

Hi, 

After applying your patch to egcs-970917/egcs-970922, gcc fails to
compile redisplay-x.c in xemacs-20.2 while running

cc1 redisplay-x.i -quiet -dumpbase redisplay-x.c -O3 
-version -o redisplay-x.s

My patch works fine and should be used instead.

The file redisplay-x.i is too long and I do not think I should send it to
the whole egcs list. I will send it to you if you need it.

Regards,

Weiwen

On Tue, 23 Sep 1997, Jim Wilson wrote:

> I have a patch that fixes the problem by eliminating the unnecessary USE
> insns.  I am not sure how safe this patch is though.  Modifying combine to
> increment REG_N_REFS if it emits a USE insn is much safer, but may result
> is poorer code because of its affect on register allocation.
> 
> There are two separate bugs here that needed to be fixed to make the testcase
> work.
> 



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1997-09-22 22:55       ` Jim Wilson
@ 1997-09-23 13:08         ` Jim Wilson
  1997-09-24  7:51           ` Weiwen Liu
  0 siblings, 1 reply; 31+ messages in thread
From: Jim Wilson @ 1997-09-23 13:08 UTC (permalink / raw)
  To: egcs-bugs; +Cc: law, Weiwen Liu

I have a patch that fixes the problem by eliminating the unnecessary USE
insns.  I am not sure how safe this patch is though.  Modifying combine to
increment REG_N_REFS if it emits a USE insn is much safer, but may result
is poorer code because of its affect on register allocation.

There are two separate bugs here that needed to be fixed to make the testcase
work.

Tue Sep 23 12:57:35 1997  Jim Wilson  <wilson@cygnus.com>

	* combine.c (try_combine): When setting elim_i2, check whether newi2pat
	sets i2dest.  When calling distribute_notes for i3dest_killed, pass
	elim_i2 and elim_i1.

Index: combine.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/combine.c,v
retrieving revision 1.3
diff -p -r1.3 combine.c
*** combine.c	1997/09/22 17:41:11	1.3
--- combine.c	1997/09/23 19:56:48
*************** try_combine (i3, i2, i1)
*** 2134,2141 ****
      rtx i3links, i2links, i1links = 0;
      rtx midnotes = 0;
      register int regno;
!     /* Compute which registers we expect to eliminate.  */
!     rtx elim_i2 = (newi2pat || i2dest_in_i2src || i2dest_in_i1src
  		   ? 0 : i2dest);
      rtx elim_i1 = i1 == 0 || i1dest_in_i1src ? 0 : i1dest;
  
--- 2134,2143 ----
      rtx i3links, i2links, i1links = 0;
      rtx midnotes = 0;
      register int regno;
!     /* Compute which registers we expect to eliminate.  newi2pat may be setting
!        either i3dest or i2dest, so we must check it.  */
!     rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat))
! 		   || i2dest_in_i2src || i2dest_in_i1src
  		   ? 0 : i2dest);
      rtx elim_i1 = i1 == 0 || i1dest_in_i1src ? 0 : i1dest;
  
*************** try_combine (i3, i2, i1)
*** 2298,2304 ****
  	distribute_notes (gen_rtx (EXPR_LIST, REG_DEAD, i3dest_killed,
  				   NULL_RTX),
  			  NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
! 			  NULL_RTX, NULL_RTX);
        }
  
      /* For I2 and I1, we have to be careful.  If NEWI2PAT exists and sets
--- 2300,2306 ----
  	distribute_notes (gen_rtx (EXPR_LIST, REG_DEAD, i3dest_killed,
  				   NULL_RTX),
  			  NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
! 			  elim_i2, elim_i1);
        }
  
      /* For I2 and I1, we have to be careful.  If NEWI2PAT exists and sets


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1997-09-22 11:08     ` Jeffrey A Law
@ 1997-09-22 22:55       ` Jim Wilson
  1997-09-23 13:08         ` Jim Wilson
  0 siblings, 1 reply; 31+ messages in thread
From: Jim Wilson @ 1997-09-22 22:55 UTC (permalink / raw)
  To: law; +Cc: Weiwen Liu, egcs-bugs

I think combine never should have created the USE insn in the first place.

The USE insn should only be created when combine can't the insn setting and/or
using a reg in the current block, which implies that the reg must be live
in multiple blocks, and the insn using it in the current block has been
optimized away.  Neither is true in this case, the reg is live in a single
block, and the insn using it is still there.

Since the local-alloc optimization only applies to variables that are set
and used in a single block, then we should never have any combiner USE insns
emitted for variables which are eligible for the update_equiv_regs
optimization.

I need to look at this some more though.  I built egcs on an alpha-dec-osf4.0
system here, but gdb isn't working right, so I started another build on a
different system which I know has a working gdb.

Jim


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1997-09-21 21:28   ` Weiwen Liu
@ 1997-09-22 11:08     ` Jeffrey A Law
  1997-09-22 22:55       ` Jim Wilson
  0 siblings, 1 reply; 31+ messages in thread
From: Jeffrey A Law @ 1997-09-22 11:08 UTC (permalink / raw)
  To: Weiwen Liu; +Cc: egcs-bugs, wilson

  In message < Pine.OSF.3.96.970922001305.6099A-100000@hepunix1.physics.yale.edu >you write:
  > The problem shows up on an alpha-dec-osf4.0 with haifa schedule.
OK.  You need to make sure to let us know this kind of information
when you make the initial bug report.  It'll keep everyone from wasting
time.

  > The RTL files t1.c.sched and t1.c.lreg are in the appendix.
  > 
  > Note the INSN in t1.c.sched
  > ======>(insn 88 4 15 (use (reg:DI 88)) -1 (nil)
  > is changed in t1.c.lreg to 
  > ======>(insn 88 4 15 (use (const:DI (plus:DI (symbol_ref:DI ("pure"))
  > which should not have happened.
  > 
  > With this change, pseudo-reg 88 is never set, but it is used later which
  > cause the program crash.
OK.  This is also something you need to tell us when you send patches;
otherwise we have to figure these things out ourselves to determine
if your patch is correct.

Your patch is probably correct, though I want Jim's opinion on
one aspect.

Jim -- the problem is combine creates a use, but leaves reg_n_refs
as 2.

local-alloc handles reg_n_refs == 2 specially if the register is
equivalent to a constant (tries to replace references to the register
with the corresponding constant expression).  In thise case there's
actually two insns that reference the reg as a source operand and
local-alloc substituted the constant expression in the wrong one
(ie the USE insn).

Should register references in USE insns be counted in reg_n_refs?

jeff






^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1997-09-21 18:07 optimization bug Weiwen Liu
@ 1997-09-21 21:28 ` Jeffrey A Law
  1997-09-21 21:28   ` Weiwen Liu
  1997-11-02 22:26 ` Jeffrey A Law
  1 sibling, 1 reply; 31+ messages in thread
From: Jeffrey A Law @ 1997-09-21 21:28 UTC (permalink / raw)
  To: Weiwen Liu; +Cc: egcs-bugs

  In message < Pine.OSF.3.96.970921210021.4151A-100000@hepunix1.physics.yale.edu >you write:
  > Hi, 
  > I found that the bug is due to replace a register in a USE RTL with
  > its value.
Can you explain exactly why the compiler core dumped and why
you patch fixes the problem?

Using your testcase, compiling with -O2 I don't get an abort.

There are 3 instances where we have USE insns which have a
REG_DEAD note attached to them:

(insn 96 52 53 (use (reg:DI 92)) -1 (nil)
    (expr_list:REG_DEAD (reg:DI 92)
        (nil)))


(insn 95 88 64 (use (reg:DI 90)) -1 (nil)
    (expr_list:REG_DEAD (reg:DI 90)
        (nil)))


(insn 72 73 97 (use (reg/i:DI 0 $0)) -1 (nil)
    (expr_list:REG_DEAD (reg/i:DI 0 $0)
        (nil)))


In each and every case reg_equiv_replace is zero for the register
in question -- which would prevent the replacement code from
doing anything.

So, what exactly is the problem?
 
 Jeff


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
  1997-09-21 21:28 ` Jeffrey A Law
@ 1997-09-21 21:28   ` Weiwen Liu
  1997-09-22 11:08     ` Jeffrey A Law
  0 siblings, 1 reply; 31+ messages in thread
From: Weiwen Liu @ 1997-09-21 21:28 UTC (permalink / raw)
  To: law; +Cc: egcs-bugs

Hi,

The problem shows up on an alpha-dec-osf4.0 with haifa schedule.
I have not compile the program without haifa schedule, so I do not known
if what I say below will apply.

The RTL files t1.c.sched and t1.c.lreg are in the appendix.

Note the INSN in t1.c.sched
======>(insn 88 4 15 (use (reg:DI 88)) -1 (nil)
is changed in t1.c.lreg to 
======>(insn 88 4 15 (use (const:DI (plus:DI (symbol_ref:DI ("pure"))
which should not have happened.

With this change, pseudo-reg 88 is never set, but it is used later which
cause the program crash.

The patch I sent in will disable this change.

Weiwen

Appendix:
With haifa schedule, the RTL files after schedule is
/* t1.c.sched */
;; Function purified

(note 2 0 5 "" NOTE_INSN_DELETED)

;; Start of basic block 0, registers live: 16 [$16] 86 88
(note 5 2 6 "" NOTE_INSN_FUNCTION_BEG)

(note 6 5 8 "" NOTE_INSN_DELETED)

(note 8 6 11 "" NOTE_INSN_DELETED)

(note 11 8 12 "" NOTE_INSN_DELETED)

(note 12 11 17 "" NOTE_INSN_DELETED)

(note 17 12 25 "" NOTE_INSN_DELETED)

(note 25 17 4 "" NOTE_INSN_DELETED)

(insn 4 25 88 (set (reg/v:DI 68)
        (reg:DI 16 $16)) 254 {movdi-1} (nil)
    (expr_list:REG_DEAD (reg:DI 16 $16)
        (nil)))

(insn 88 4 15 (use (reg:DI 88)) -1 (nil)
    (expr_list:REG_DEAD (reg:DI 88)
        (nil)))

(insn 15 88 87 (set (reg:DI 74)
        (and:DI (reg/v:DI 68)
            (const_int 7))) 41 {anddi3} (insn_list 4 (nil))
    (nil))

(insn 87 15 22 (use (reg:DI 86)) -1 (nil)
    (expr_list:REG_DEAD (reg:DI 86)
        (nil)))

(insn 22 87 39 (set (reg:DI 78)
        (eq:DI (reg:DI 74)
            (const_int 6))) 131 {subdf3+4} (insn_list 15 (nil))
    (nil))

(insn 39 22 26 (set (reg:DI 84)
        (lshiftrt:DI (reg/v:DI 68)
            (const_int 4))) 64 {lshrdi3} (insn_list 4 (nil))
    (expr_list:REG_DEAD (reg/v:DI 68)
        (nil)))

(insn 26 39 44 (set (reg:DI 80)
        (if_then_else:DI (ne (reg:DI 74)
                (const_int 0))
            (reg:DI 78)
            (const_int 1))) 134 {absdi2-6} (insn_list 15 (insn_list 22 (nil)))
    (expr_list:REG_DEAD (reg:DI 74)
        (expr_list:REG_DEAD (reg:DI 78)
            (nil))))

(insn 44 26 45 (set (reg:DI 85)
        (symbol_ref:DI ("pure"))) 254 {movdi-1} (nil)
    (nil))

(insn 45 44 28 (set (reg:DI 88)
        (const:DI (plus:DI (symbol_ref:DI ("pure"))
                (const_int 1788000)))) 254 {movdi-1} (insn_list:REG_DEP_ANTI 88 (nil))
    (expr_list:REG_EQUAL (const:DI (plus:DI (symbol_ref:DI ("pure"))
                (const_int 1788000)))
        (nil)))

(jump_insn 28 45 31 (set (pc)
        (if_then_else (eq (reg:DI 80)
                (const_int 0))
            (label_ref 35)
            (pc))) 157 {umindi3+2} (insn_list:REG_DEP_ANTI 4 (insn_list:REG_DEP_ANTI 15 (insn_list:REG_DEP_ANTI 22 (insn_list 26 (nil)))))
    (expr_list:REG_DEAD (reg:DI 80)
        (nil)))
;; End of basic block 0

;; Start of basic block 1, registers live:
(insn 31 28 33 (set (reg/i:DI 0 $0)
        (const_int 0)) 254 {movdi-1} (nil)
    (expr_list:REG_EQUAL (const_int 0)
        (nil)))

(jump_insn 33 31 34 (set (pc)
        (label_ref 65)) 230 {jump} (insn_list:REG_DEP_ANTI 31 (nil))
    (nil))
;; End of basic block 1

(barrier 34 33 35)

;; Start of basic block 2, registers live: 84 85 88
(code_label 35 34 38 2 "")

(note 38 35 41 "" NOTE_INSN_DELETED)

(note 41 38 43 "" NOTE_INSN_DELETED)

(note 43 41 82 "" NOTE_INSN_DELETED)

(note 82 43 84 "" NOTE_INSN_DELETED)

(note 84 82 76 "" NOTE_INSN_DELETED)

(note 76 84 79 "" NOTE_INSN_DELETED)

(note 79 76 80 "" NOTE_INSN_DELETED)

(note 80 79 77 "" NOTE_INSN_DELETED)

(insn 77 80 46 (set (reg:DI 96)
        (leu:DI (reg:DI 85)
            (reg:DI 84))) 131 {subdf3+4} (insn_list 39 (insn_list 44 (nil)))
    (expr_list:REG_DEAD (reg:DI 85)
        (nil)))

(insn 46 77 56 (set (reg:DI 89)
        (ltu:DI (reg:DI 84)
            (reg:DI 88))) 131 {subdf3+4} (insn_list 39 (insn_list 45 (nil)))
    (expr_list:REG_DEAD (reg:DI 84)
        (expr_list:REG_DEAD (reg:DI 88)
            (nil))))

(insn 56 46 65 (set (reg/i:DI 0 $0)
        (if_then_else:DI (ne (reg:DI 89)
                (const_int 0))
            (subreg:DI (reg:DI 96) 0)
            (const_int 0))) 134 {absdi2-6} (insn_list 46 (insn_list 77 (nil)))
    (expr_list:REG_DEAD (reg:DI 89)
        (expr_list:REG_DEAD (reg:DI 96)
            (nil))))
;; End of basic block 2

;; Start of basic block 3, registers live: 0 [$0]
(code_label 65 56 64 4 "")

(insn 64 65 89 (use (reg/i:DI 0 $0)) -1 (insn_list 56 (insn_list 31 (nil)))
    (expr_list:REG_DEAD (reg/i:DI 0 $0)
        (nil)))
;; End of basic block 3

(note 89 64 0 "" NOTE_INSN_DELETED)
======END

RTL file after local register allocation:
/* t1.c.lreg */
;; Function purified

100 registers.

Register 68 used 3 times across 6 insns in block 0; GENERAL_REGS or none.

Register 74 used 3 times across 5 insns in block 0; GENERAL_REGS or none.

Register 78 used 2 times across 3 insns in block 0; GENERAL_REGS or none.

Register 80 used 2 times across 4 insns in block 0; GENERAL_REGS or none.

Register 84 used 3 times across 7 insns; GENERAL_REGS or none.

Register 85 used 3 times across 4 insns; GENERAL_REGS or none; pointer.

Register 89 used 2 times across 2 insns in block 2; GENERAL_REGS or none.

Register 96 used 2 times across 3 insns in block 2; GENERAL_REGS or none.

4 basic blocks.

Basic block 0: first insn 5, last 28.

Registers live at start: 16 86 88

Basic block 1: first insn 31, last 33.

Registers live at start:

Basic block 2: first insn 35, last 56.

Registers live at start: 84 85 88

Basic block 3: first insn 65, last 64.

Registers live at start: 0

;; Register 68 in 16.
;; Register 74 in 2.
;; Register 78 in 1.
;; Register 80 in 1.
;; Register 89 in 1.
;; Register 96 in 0.
(note 2 0 5 "" NOTE_INSN_DELETED)

;; Start of basic block 0, registers live: 16 [$16] 86 88
(note 5 2 6 "" NOTE_INSN_FUNCTION_BEG)

(note 6 5 8 "" NOTE_INSN_DELETED)

(note 8 6 11 "" NOTE_INSN_DELETED)

(note 11 8 12 "" NOTE_INSN_DELETED)

(note 12 11 17 "" NOTE_INSN_DELETED)

(note 17 12 25 "" NOTE_INSN_DELETED)

(note 25 17 4 "" NOTE_INSN_DELETED)

(insn 4 25 88 (set (reg/v:DI 68)
        (reg:DI 16 $16)) 254 {movdi-1} (nil)
    (expr_list:REG_DEAD (reg:DI 16 $16)
        (nil)))

(insn 88 4 15 (use (const:DI (plus:DI (symbol_ref:DI ("pure"))
                (const_int 1788000)))) -1 (nil)
    (nil))

(insn 15 88 87 (set (reg:DI 74)
        (and:DI (reg/v:DI 68)
            (const_int 7))) 41 {anddi3} (insn_list 4 (nil))
    (nil))

(insn 87 15 22 (use (reg:DI 86)) -1 (nil)
    (expr_list:REG_DEAD (reg:DI 86)
        (nil)))

(insn 22 87 39 (set (reg:DI 78)
        (eq:DI (reg:DI 74)
            (const_int 6))) 131 {subdf3+4} (insn_list 15 (nil))
    (nil))

(insn 39 22 26 (set (reg:DI 84)
        (lshiftrt:DI (reg/v:DI 68)
            (const_int 4))) 64 {lshrdi3} (insn_list 4 (nil))
    (expr_list:REG_DEAD (reg/v:DI 68)
        (nil)))

(insn 26 39 44 (set (reg:DI 80)
        (if_then_else:DI (ne (reg:DI 74)
                (const_int 0))
            (reg:DI 78)
            (const_int 1))) 134 {absdi2-6} (insn_list 15 (insn_list 22 (nil)))
    (expr_list:REG_DEAD (reg:DI 74)
        (expr_list:REG_DEAD (reg:DI 78)
            (nil))))

(insn 44 26 45 (set (reg:DI 85)
        (symbol_ref:DI ("pure"))) 254 {movdi-1} (nil)
    (nil))

(note 45 44 28 "" NOTE_INSN_DELETED)

(jump_insn 28 45 31 (set (pc)
        (if_then_else (eq (reg:DI 80)
                (const_int 0))
            (label_ref 35)
            (pc))) 157 {umindi3+2} (insn_list:REG_DEP_ANTI 4 (insn_list:REG_DEP_ANTI 15 (insn_list:REG_DEP_ANTI 22 (insn_list 26 (nil)))))
    (expr_list:REG_DEAD (reg:DI 80)
        (nil)))
;; End of basic block 0

;; Start of basic block 1, registers live:
(insn 31 28 33 (set (reg/i:DI 0 $0)
        (const_int 0)) 254 {movdi-1} (nil)
    (expr_list:REG_EQUAL (const_int 0)
        (nil)))

(jump_insn 33 31 34 (set (pc)
        (label_ref 65)) 230 {jump} (insn_list:REG_DEP_ANTI 31 (nil))
    (nil))
;; End of basic block 1

(barrier 34 33 35)

;; Start of basic block 2, registers live: 84 85 88
(code_label 35 34 38 2 "")

(note 38 35 41 "" NOTE_INSN_DELETED)

(note 41 38 43 "" NOTE_INSN_DELETED)

(note 43 41 82 "" NOTE_INSN_DELETED)

(note 82 43 84 "" NOTE_INSN_DELETED)

(note 84 82 76 "" NOTE_INSN_DELETED)

(note 76 84 79 "" NOTE_INSN_DELETED)

(note 79 76 80 "" NOTE_INSN_DELETED)

(note 80 79 77 "" NOTE_INSN_DELETED)

(insn 77 80 46 (set (reg:DI 96)
        (leu:DI (reg:DI 85)
            (reg:DI 84))) 131 {subdf3+4} (insn_list 39 (insn_list 44 (nil)))
    (expr_list:REG_DEAD (reg:DI 85)
        (nil)))

(insn 46 77 56 (set (reg:DI 89)
        (ltu:DI (reg:DI 84)
            (reg:DI 88))) 131 {subdf3+4} (insn_list 39 (insn_list 45 (nil)))
    (expr_list:REG_DEAD (reg:DI 84)
        (expr_list:REG_DEAD (reg:DI 88)
            (nil))))

(insn 56 46 65 (set (reg/i:DI 0 $0)
        (if_then_else:DI (ne (reg:DI 89)
                (const_int 0))
            (subreg:DI (reg:DI 96) 0)
            (const_int 0))) 134 {absdi2-6} (insn_list 46 (insn_list 77 (nil)))
    (expr_list:REG_DEAD (reg:DI 89)
        (expr_list:REG_DEAD (reg:DI 96)
            (nil))))
;; End of basic block 2

;; Start of basic block 3, registers live: 0 [$0]
(code_label 65 56 64 4 "")

(insn 64 65 89 (use (reg/i:DI 0 $0)) -1 (insn_list 56 (insn_list 31 (nil)))
    (expr_list:REG_DEAD (reg/i:DI 0 $0)
        (nil)))
;; End of basic block 3

(note 89 64 0 "" NOTE_INSN_DELETED)
======END



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: optimization bug
@ 1997-09-21 18:07 Weiwen Liu
  1997-09-21 21:28 ` Jeffrey A Law
  1997-11-02 22:26 ` Jeffrey A Law
  0 siblings, 2 replies; 31+ messages in thread
From: Weiwen Liu @ 1997-09-21 18:07 UTC (permalink / raw)
  To: egcs-bugs

Hi, 
I reported the following bug in a previous email which is attached below.

I found that the bug is due to replace a register in a USE RTL with
its value.

The following patch will disable replacing a register in a USE.

Weiwen

Sun Sep 21 18:17:24 1997  Weiwen Liu <liu@hepunix.physics.yale.edu>
	* local-alloc.c (update_equiv_regs): Forbids replacing a register
	  in a USE RTL.

*** local-alloc.c.~1~	Tue Sep  2 17:40:31 1997
--- local-alloc.c	Sun Sep 21 18:17:24 1997
*************** update_equiv_regs ()
*** 1227,1232 ****
--- 1227,1234 ----
        for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
  	{
  	  if (REG_NOTE_KIND (link) == REG_DEAD
+               /* Do not replace register in USE */
+               && GET_CODE(PATTERN(insn)) != USE
  	      /* Make sure this insn still refers to the register.  */
  	      && reg_mentioned_p (XEXP (link, 0), PATTERN (insn)))
  	    {


The previous message:
Hi,

On alpha-dec-osf4.0, egcs-2.90.08 970917 fails to compile the following
program with -O2 or -O3, but succeeds with -O1. 
The error message:
gcc: Internal compiler error: program cc1 got fatal signal 11

Weiwen

/* tmp.i */
enum Lisp_Type
{
  Lisp_Int                     
  ,Lisp_Record                 
  ,Lisp_Cons                   
  ,Lisp_String                 
  ,Lisp_Vector                 
  ,Lisp_Symbol
  ,Lisp_Char			 
};
typedef
union Lisp_Object
{
    struct
    {
	unsigned long  type_mark: 3L  + 1;
	signed long  val: (((8 * 8 ) )-((3L )+1L)) ;
    } s;
    struct
    {
        enum Lisp_Type type: 3L ;
	unsigned long  markbit: 1;
	unsigned long  val: (((8 * 8 ) )-((3L )+1L)) ;
    } gu;
    long  i;
    struct __nosuchstruct__ *v;
    struct __nosuchstruct__ *cv;              
}
Lisp_Object;
extern Lisp_Object pure[]; 
int
purified (Lisp_Object obj)
{
    if (! (( ((enum Lisp_Type) (  obj  ).gu.type)   ) != Lisp_Int
           && ( ((enum Lisp_Type) (  obj  ).gu.type)   ) != Lisp_Char) )
        return (0);
    return (((unsigned long ) ( ((void *) (( obj ).gu.val))  )
             <	(unsigned long ) (((unsigned char *) pure)
                                  + ((((1400000 ) + (43000 ) + (43000 )
                                       + (4000 ) + (4000 ) + (95000 )
                                       + (99000) + (100000 )) )) )
             &&	(unsigned long ) ( ((void *) (( obj ).gu.val))  )
             >=	(unsigned long ) ((unsigned char *) pure) ) );
}






^ permalink raw reply	[flat|nested] 31+ messages in thread

* optimization bug
@ 1997-09-19 21:03 Weiwen Liu
  0 siblings, 0 replies; 31+ messages in thread
From: Weiwen Liu @ 1997-09-19 21:03 UTC (permalink / raw)
  To: egcs-bugs

Hi,

On alpha-dec-osf4.0, egcs-2.90.08 970917 fails to compile the following
program with -O2 or -O3, but succeeds with -O1. 
The error message:
gcc: Internal compiler error: program cc1 got fatal signal 11

Weiwen

/* tmp.i */
enum Lisp_Type
{
  Lisp_Int                     
  ,Lisp_Record                 
  ,Lisp_Cons                   
  ,Lisp_String                 
  ,Lisp_Vector                 
  ,Lisp_Symbol
  ,Lisp_Char			 
};
typedef
union Lisp_Object
{
    struct
    {
	unsigned long  type_mark: 3L  + 1;
	signed long  val: (((8 * 8 ) )-((3L )+1L)) ;
    } s;
    struct
    {
        enum Lisp_Type type: 3L ;
	unsigned long  markbit: 1;
	unsigned long  val: (((8 * 8 ) )-((3L )+1L)) ;
    } gu;
    long  i;
    struct __nosuchstruct__ *v;
    struct __nosuchstruct__ *cv;              
}
Lisp_Object;
extern Lisp_Object pure[]; 
int
purified (Lisp_Object obj)
{
    if (! (( ((enum Lisp_Type) (  obj  ).gu.type)   ) != Lisp_Int
           && ( ((enum Lisp_Type) (  obj  ).gu.type)   ) != Lisp_Char) )
        return (0);
    return (((unsigned long ) ( ((void *) (( obj ).gu.val))  )
             <	(unsigned long ) (((unsigned char *) pure)
                                  + ((((1400000 ) + (43000 ) + (43000 )
                                       + (4000 ) + (4000 ) + (95000 )
                                       + (99000) + (100000 )) )) )
             &&	(unsigned long ) ( ((void *) (( obj ).gu.val))  )
             >=	(unsigned long ) ((unsigned char *) pure) ) );
}





^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2003-03-10 14:26 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20000812004418.A4935@a2000.nl>
2000-08-12  9:30 ` Optimization bug Richard Henderson
2003-03-10 14:24 optimization bug surjan
2003-03-10 15:31 ` Tim Prince
  -- strict thread matches above, loose matches on Subject: below --
2002-01-04  6:20 Calin Cascaval
2000-03-24 12:07 Optimization bug Gerald Gutierrez
2000-03-22  1:41 optimization bug Andrea Latina
1999-12-31 20:54 Optimization bug Peter R. Torpman
1999-12-31 20:54 ` Nathan Sidwell
1999-03-31 23:54 Hyman Rosen
1999-03-31 23:54 ` Jeffrey A Law
1999-03-31 23:54   ` Hyman Rosen
1998-10-27 11:04 optimization bug Valentin Bonnard
1998-10-25 21:47 Kaoru Fukui
1998-10-22 10:56 Dima Volodin
1998-10-25 12:17 ` Valentin Bonnard
1998-10-25 17:41   ` Dima Volodin
1998-10-26 18:00     ` Alexandre Oliva
1998-10-27  8:56       ` Dima Volodin
1998-10-27 11:04         ` Alexandre Oliva
1998-10-27  9:54           ` Dima Volodin
1998-10-12 11:18 Optimization bug Phillip Ezolt
1999-01-13  5:41 ` Jeffrey A Law
1997-09-21 18:07 optimization bug Weiwen Liu
1997-09-21 21:28 ` Jeffrey A Law
1997-09-21 21:28   ` Weiwen Liu
1997-09-22 11:08     ` Jeffrey A Law
1997-09-22 22:55       ` Jim Wilson
1997-09-23 13:08         ` Jim Wilson
1997-09-24  7:51           ` Weiwen Liu
1997-11-02 22:26 ` Jeffrey A Law
1997-09-19 21:03 Weiwen Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).