GCC, including at least versions 2.6.3 and 2.7.*, but not 2.8.0,
has a serious problem that causes it to generate incorrect code
for the x86 architecture.
For C code generated by the RML compiler, the bug results in
invalid pointers and segmentation violations.

The program tools/gcc.2722.x86.c may be compiled
to test if the bug is present or not in your gcc.

The patch below fixes the problem, and has been included in gcc 2.8.0.
If your version of gcc is affected by the bug, then please either
upgrade to gcc 2.8.0 (or a later version), or apply the patch and
rebuild gcc yourself.

From kenner@vlsi1.ultra.nyu.edu Tue Jan  2 00:24:44 1996
Received: from vlsi1.ultra.nyu.edu by ida.liu.se (5.65b/ida.minimaster-V1.0b6d5)
	id AA08729; Tue, 2 Jan 96 00:24:42 +0100
Received: by vlsi1.ultra.nyu.edu (5.61/1.34)
	id AA06453; Mon, 1 Jan 96 18:28:14 -0500
Date: Mon, 1 Jan 96 18:28:14 -0500
From: kenner@vlsi1.ultra.nyu.edu (Richard Kenner)
Message-Id: <9601012328.AA06453@vlsi1.ultra.nyu.edu>
To: mpe@ida.liu.se
Subject: Re:  gcc -O1 bug on x86
Content-Length: 1765
X-Lines: 55
Status: RO

Mon Jan  1 09:05:07 1996  Richard Kenner  (kenner@vlsi1.ultra.nyu.edu)

	* local-alloc (reg_equiv_replacement): New variable.
	(memref_referenced_p, case REG): Check for reg_equiv_replacement.
	(update_equiv_regs): reg_equiv_replacement now file-scope.

*** local-alloc.c.old	Sun Dec 17 08:08:19 1995
--- local-alloc.c	Mon Jan  1 18:13:05 1996
*************** static int this_insn_number;
*** 243,246 ****
--- 243,250 ----
  static rtx this_insn;
  
+ /* Used to communicate changes made by update_equiv_regs to
+    memref_referenced_p.  */
+ static rtx *reg_equiv_replacement;
+ 
  static void alloc_qty		PROTO((int, enum machine_mode, int, int));
  static void alloc_qty_for_scratch PROTO((rtx, int, rtx, int, int));
*************** memref_referenced_p (memref, x)
*** 617,621 ****
    switch (code)
      {
-     case REG:
      case CONST_INT:
      case CONST:
--- 621,624 ----
*************** memref_referenced_p (memref, x)
*** 629,632 ****
--- 632,640 ----
        return 0;
  
+     case REG:
+       return (reg_equiv_replacement[REGNO (x)] == 0
+ 	      || memref_referenced_p (memref,
+ 				      reg_equiv_replacement[REGNO (x)]));
+ 
      case MEM:
        if (true_dependence (memref, x))
*************** update_equiv_regs ()
*** 949,954 ****
  {
    rtx *reg_equiv_init_insn = (rtx *) alloca (max_regno * sizeof (rtx *));
-   rtx *reg_equiv_replacement = (rtx *) alloca (max_regno * sizeof (rtx *));
    rtx insn;
  
    bzero ((char *) reg_equiv_init_insn, max_regno * sizeof (rtx *));
--- 957,963 ----
  {
    rtx *reg_equiv_init_insn = (rtx *) alloca (max_regno * sizeof (rtx *));
    rtx insn;
+ 
+   reg_equiv_replacement = (rtx *) alloca (max_regno * sizeof (rtx *));
  
    bzero ((char *) reg_equiv_init_insn, max_regno * sizeof (rtx *));
