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).