ldmud-3.2.9/doc/
ldmud-3.2.9/doc/efun/
ldmud-3.2.9/mud/
ldmud-3.2.9/mud/heaven7/
ldmud-3.2.9/mud/heaven7/lib/
ldmud-3.2.9/mud/lp-245/
ldmud-3.2.9/mud/lp-245/banish/
ldmud-3.2.9/mud/lp-245/doc/
ldmud-3.2.9/mud/lp-245/doc/examples/
ldmud-3.2.9/mud/lp-245/doc/sefun/
ldmud-3.2.9/mud/lp-245/log/
ldmud-3.2.9/mud/lp-245/obj/Go/
ldmud-3.2.9/mud/lp-245/players/lars/
ldmud-3.2.9/mud/lp-245/room/death/
ldmud-3.2.9/mud/lp-245/room/maze1/
ldmud-3.2.9/mud/lp-245/room/sub/
ldmud-3.2.9/mud/lp-245/secure/
ldmud-3.2.9/mud/morgengrauen/
ldmud-3.2.9/mud/morgengrauen/lib/
ldmud-3.2.9/mud/sticklib/
ldmud-3.2.9/mud/sticklib/src/
ldmud-3.2.9/mudlib/uni-crasher/
ldmud-3.2.9/pkg/
ldmud-3.2.9/pkg/debugger/
ldmud-3.2.9/pkg/diff/
ldmud-3.2.9/pkg/misc/
ldmud-3.2.9/src/autoconf/
ldmud-3.2.9/src/bugs/
ldmud-3.2.9/src/bugs/MudCompress/
ldmud-3.2.9/src/bugs/b-020916-files/
ldmud-3.2.9/src/bugs/doomdark/
ldmud-3.2.9/src/bugs/ferrycode/ferry/
ldmud-3.2.9/src/bugs/ferrycode/obj/
ldmud-3.2.9/src/bugs/psql/
ldmud-3.2.9/src/done/
ldmud-3.2.9/src/done/order_alist/
ldmud-3.2.9/src/done/order_alist/obj/
ldmud-3.2.9/src/done/order_alist/room/
ldmud-3.2.9/src/gcc/
ldmud-3.2.9/src/gcc/2.7.0/
ldmud-3.2.9/src/gcc/2.7.1/
ldmud-3.2.9/src/hosts/
ldmud-3.2.9/src/hosts/GnuWin32/
ldmud-3.2.9/src/hosts/amiga/NetIncl/
ldmud-3.2.9/src/hosts/amiga/NetIncl/netinet/
ldmud-3.2.9/src/hosts/amiga/NetIncl/sys/
ldmud-3.2.9/src/hosts/i386/
ldmud-3.2.9/src/hosts/msdos/byacc/
ldmud-3.2.9/src/hosts/msdos/doc/
ldmud-3.2.9/src/hosts/os2/
ldmud-3.2.9/src/hosts/win32/
ldmud-3.2.9/src/util/
ldmud-3.2.9/src/util/erq/
ldmud-3.2.9/src/util/indent/hosts/next/
ldmud-3.2.9/src/util/xerq/
ldmud-3.2.9/src/util/xerq/lpc/
ldmud-3.2.9/src/util/xerq/lpc/www/
Path: meolyon!mwhh!news.Hanse.DE!news.rrz.uni-hamburg.de!news.dkrz.de!news.tu-harburg.de!news.dfn.de!Germany.EU.net!EU.net!news.sprintlink.net!tank.news.pipex.net!pipex!news.mathworks.com!panix!bloom-beacon.mit.edu!usc!math.ohio-state.edu!magnus.acs.ohio-state.edu!cis.ohio-state.edu!meolyon.hanse.DE!amylaar
From: amylaar@meolyon.hanse.DE (Joern Rennecke)
Newsgroups: gnu.gcc.bug
Subject: REG_EQUIV confusion (Was: gcc 2.7.0 bug HP-PA)
Date: 5 Sep 1995 00:37:11 -0400
Organization: GNUs Not Usenet
Lines: 99
Sender: daemon@cis.ohio-state.edu
Approved: bug-gcc@prep.ai.mit.edu
Distribution: gnu
Message-ID: <m0spomo-000D1tC@meolyon>

~Newsgroups: gnu.gcc.bug
Path: amylaar
~From: amylaar@meolyon.hanse.de (Joern Rennecke)
~Subject: REG_EQUIV confusion (Was: gcc 2.7.0 bug HP-PA)
Distribution: gnu
Organization: Private site running Linux
Message-ID: <1995Sep5.033452.1390@meolyon.hanse.de>
~References: <DD1EzG.D1L@ida.liu.se>
~Date: Tue, 5 Sep 1995 03:34:52 GMT

mpe@ida.liu.se (Mikael Pettersson) writes:

>GCC 2.7.0 and 2.6.3, configured with "i486-hp-solaris2",
>grossly miscompile (with -O1) the following function:
>
>/* yyy.c */
>struct rml_state {
>    void **SP, *FC, **SC, *TP, *ARGS[10];
>};
>extern void *Unify_2eunify(struct rml_state*);
>extern void *sclam616(struct rml_state*);
>
>void *sclam617(struct rml_state *rmlState)
>{
>    void **tmp950 = rmlState->SC;
>    void *tmp375 = tmp950[1];           /*1a*/
>    void *tmp374 = tmp950[2];
>    void *tmp602 = tmp950[3];
>    void *tmp609 = rmlState->ARGS[0];
>    void *tmp610 = rmlState->ARGS[1];   /*2a*/
>    tmp950[3] = tmp375;                 /*1b*/
>    tmp950[2] = tmp602;
>    tmp950[1] = tmp610;                 /*2b*/
>    tmp950[0] = (void*)sclam616;
>    rmlState->ARGS[1] = tmp609;
>    rmlState->ARGS[0] = tmp602;
>    rmlState->FC = (void**)tmp374;
>    rmlState->SP = tmp950;
>    return (void*)Unify_2eunify;
>}
>
>The problem is that gcc performs the second load-store group
>(2a and 2b) BEFORE it does the load at 1a, and in doing so
>overwrites the original value of tmp950[1]. tmp375 will then
>later be loaded with the wrong value.

I used some rtl dumps and gdb to find out where the problem occurs.
It seems to be due to a definition problem what REG_EQUIV really is.

rtl.texi states:

  For @code{REG_EQUIV}, the register is equivalent to @var{op} throughout
  the entire function, and could validly be replaced in all its
  occurrences by @var{op}.  (``Validly'' here refers to the data flow of
  the program; simple replacement may make some insns invalid.)  For
  example, when a constant is loaded into a register that is never
  assigned any other value, this kind of note is used.

OTOH, update_equiv_regs () in "local-alloc.c" seems to have a different
idea what REG_EQUIV might be validly used for.

Here is the relevant section from the code:

      /* If this insn introduces a "constant" register, decrease the priority
         of that register.  Record this insn if the register is only used once
         more and the equivalence value is the same as our source.

         The latter condition is checked for two reasons:  First, it is an
         indication that it may be more efficient to actually emit the insn
         as written (if no registers are available, reload will substitute
         the equivalence).  Secondly, it avoids problems with any registers
         dying in this insn whose death notes would be missed.

         If we don't have a REG_EQUIV note, see if this insn is loading
         a register used only in one basic block from a MEM.  If so, and the
         MEM remains unchanged for the life of the register, add a REG_EQUIV
         note.  */

      note = find_reg_note (insn, REG_EQUIV, NULL_RTX);

      if (note == 0 && reg_basic_block[regno] >= 0
          && GET_CODE (SET_SRC (set)) == MEM
          && validate_equiv_mem (insn, dest, SET_SRC (set)))
        REG_NOTES (insn) = note = gen_rtx (EXPR_LIST, REG_EQUIV, SET_SRC (set),
                                           REG_NOTES (insn));

Now this causes problems when the instructions get reordered later in a way
that expands the lifetime of the register so that it overlaps with a point
in time when the MEM has a different value.

Thus, REG_EQUIV is usually used as meaning 'equal in the entire scope of the
register' while equiv_regs() uses it to denote 'equal in the entire lifetime
of the register' , which is unfortunately not quite the same.

What is the correct definition of REG_EQUIV? And should there be an
additional note type to describe the situation that is currently described
wrongly as REG_EQUIV ?

	Joern Rennecke

Path: meolyon!mwhh!news.Hanse.DE!news.rrz.uni-hamburg.de!news.dkrz.de!news.tu-harburg.de!news.dfn.de!Germany.EU.net!EU.net!howland.reston.ans.net!math.ohio-state.edu!magnus.acs.ohio-state.edu!cis.ohio-state.edu!meolyon.hanse.DE!amylaar
From: amylaar@meolyon.hanse.DE (Joern Rennecke)
Newsgroups: gnu.gcc.bug
Subject: Re: More on the -fforce-mem optimization bug on i386
Date: 8 Sep 1995 23:37:51 -0400
Organization: GNUs Not Usenet
Lines: 113
Sender: daemon@cis.ohio-state.edu
Approved: bug-gcc@prep.ai.mit.edu
Distribution: gnu
Message-ID: <m0srFCU-000DfMC@meolyon>

~Newsgroups: gnu.gcc.bug
Path: amylaar
~From: amylaar@meolyon.hanse.de (Joern Rennecke)
~Subject: Re: More on the -fforce-mem optimization bug on i386
Distribution: gnu
Organization: Private site running Linux
Message-ID: <1995Sep9.015918.1154@meolyon.hanse.de>
~References: <9508280955.AA14222@crunch>
~Date: Sat, 9 Sep 1995 01:59:18 GMT

anlauf@crunch.ikp.physik.th-darmstadt.de (Harald Anlauf) writes:

>Hi,

>last weekend I did some more research on the -fforce-mem problem on i386
>platforms reported by me.  It appears that it is the declaration of
>static variables that confuses gcc.  See below a stripped-down C version
>of a subset of the original program:

>Test run output, when compiled with gcc 2.5.8 and gcc 2.7.0
>(i486-*-linuxoldld):

>gcc -O1 -fno-force-mem:
>       12        34        56        78
>       16        32       110        89       110
>       48        28       116       139       116
>(which is correct).

>gcc -O1 -fforce-mem:
>       12        34        56        78
>      115       115       134        89       134
>       50        50       115       139       115
>(which is wrong).

>Replacing -O1 by -O2 seems to "fix" the problem for the stripped-down
>program as appended below, but this is misleading, since the full
>program in the original report still exhibits the bug (because there are
>even more static variables declared ... ;-)

>Note that in the translation of Fortran77 to C by f2c local variables
>are defined as static, so I would be interested to know if the original
>Fortran program works correctly with g77.  Could somebody please test
>this, with the appropriate flags?

>Cheers,
>Harald

>bug.c:
>------------------------------> cut here <------------------------------
>void bug(void)
>{
>  int i, l, m, ii, jj;
>  static int j, k;
>/* If I change any of j, k to automatic, gcc -fforce-mem -O will compile
>   the code correctly !?!?!?!? */

>  i = 12;
>  j = 34;
>  k = 56;
>  l = 78;
>  printf ("%9d %9d %9d %9d\n", i, j, k, l);

>  for (ii = 1; ii <= 2; ++ii) {
>    for (jj = 1; jj <= 24; ++jj) {
>      m = i * j % 179 * k % 179;
>      i = j;
>      j = k;
>      k = m;
>      l = (l * 53 + 1) % 169;
>    }
>    printf ("%9d %9d %9d %9d %9d\n", i, j, k, l, m);
>  }
>} /* bug */


>main()
>{
>   bug ();
>   exit (0);
>} /* main */
>------------------------------> cut here <------------------------------


This bug seems to be due to the REG_EQUIV confusion too. At least it goes
away when the appended patch is applied.

        Joern Rennecke

*** gcc-2.7.0/local-alloc.c	Sat Jul  8 01:56:38 1995
--- gcc-2.7.0-x/local-alloc.c	Tue Sep  5 06:02:58 1995
*************** update_equiv_regs ()
*** 987,992 ****
--- 987,996 ----
  	 insn that set REG is safe.  If so, put a REG_EQUIV note on the
  	 initializing insn.  */

+ #if 0
+ /* This is invalid when code gets reordered. Therefore, I temporarily
+  * disabled this code. Joern Rennecke Tue Sep  5 06:02:24 MET DST 1995
+  */
        if (GET_CODE (dest) == MEM && GET_CODE (SET_SRC (set)) == REG
  	  && (regno = REGNO (SET_SRC (set))) >= FIRST_PSEUDO_REGISTER
  	  && reg_basic_block[regno] >= 0
*************** update_equiv_regs ()
*** 998,1003 ****
--- 1002,1008 ----
  	REG_NOTES (reg_equiv_init_insn[regno])
  	  = gen_rtx (EXPR_LIST, REG_EQUIV, dest,
  		     REG_NOTES (reg_equiv_init_insn[regno]));
+ #endif

        /* If this is a register-register copy where SRC is not dead, see if we
  	 can optimize it.  */