🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #14

gcc/i860 bug report

#14
From: trm
Date: Thu, 29 Oct 1992 13:53
134 lines
4288 bytes
These bug reports are for GCC version 2.2.2 compiled as a cross compiler
for an i860/SVR4 target on a SPARCstation host.  I have two bugs to report.
The configure command had arguments i860-sysv4 and --host sun4.  The 
i860.h file was changed to define BYTES_BIG_ENDING and WORDS_BIG_ENDIAN to
one because this target machine uses the i860 that way.

1) GCC has a bug in the common subexpression elimination optimization
step.  It is too optimistic about the use of varying addresses to
access memory.  The note_mem_written procedure in cse.c was changed to
fix the bug.  Here is an example program:

void bar(void *val)
{
	printf("%x\n", (unsigned long)val);
}

void foo(void *addr, long *val)
{
	unsigned long lval = 42;
	((char *)&lval)[(unsigned long)addr & 3] = 6;
	
	bar((void *)lval);
}

main()
{
	unsigned long x = 3;

	foo(0, (void*)x);
}

When this program is compiled with just the -O option, the change to the 
local variable lval is lost when lval is passed to the bar function so 
2a is printed rather than 600002A.  To fix the bug, I commented out some
lines in cse.c, the note_mem_written function as shown below:

      else if (cse_rtx_addr_varies_p (written))
	{
	  /* A varying address that is a sum indicates an array element,
	     and that's just as good as a structure element
	     in implying that we need not invalidate scalar variables.  */
/*
 *	  if (!(MEM_IN_STRUCT_P (written)
 *		|| GET_CODE (XEXP (written, 0)) == PLUS))
 */
	    writes_ptr->all = 1;
	  writes_ptr->nonscalar = 1;
	}

There's probably a better way to fix this problem but it seems to be working
for me.  


2) There is a bug in final.c, alter_subreg() due to the WORD_BIG_ENDIAN
change that I made.  This caused multiplies to work incorrectly when the 
number of local variables spilled over from registers into memory.

Here is an example program to demonstrate the bug:

bar()
{
	char x[10000];
	memset(x, 'z', 10000);
}

foo(int z)
{
	int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
	int a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
	int x;

	a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = a10 = z;
	a11 = a12 = a13 = a14 = a15 = a16 = a17 = a18 = a19 = a20 = z;
	
	x = a1 * a2 * a3 * a4 * a5 * a6 * a7 * a8 * a9 * a10*
		a11 * a12 * a13 * a14 * a15 * a16 * a17 * a18 * a19 * a20;
	printf("x = %d (should be 1)\n", x);
}

main()
{
	bar();
	foo(1);
}

When this program is compiled with the -O option, it prints a garbage value
rather than 1. 

To fix the bug, I changed alter_subreg as follows:

rtx
alter_subreg (x)
     register rtx x;
{
  register rtx y = SUBREG_REG (x);
  if (GET_CODE (y) == SUBREG)
    y = alter_subreg (y);

  if (GET_CODE (y) == REG)
    {
      /* If the containing reg really gets a hard reg, so do we.  */
      PUT_CODE (x, REG);
      REGNO (x) = REGNO (y) + SUBREG_WORD (x);
    }
  else if (GET_CODE (y) == MEM)
    {
#if WORDS_BIG_ENDIAN
      register int offset = 
	GET_MODE_SIZE (GET_MODE (y)) - (SUBREG_WORD (x) + 1) * UNITS_PER_WORD;
#else
      register int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
#endif
/*
 *    printf("alter_subreg: offset=%d, word=%d, y mode size=%d\n", 
 *	     offset, SUBREG_WORD(x), GET_MODE_SIZE (GET_MODE (y)));
 */
#if BYTES_BIG_ENDIAN
      offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))
		 - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (y))));
#endif
      PUT_CODE (x, MEM);
      MEM_VOLATILE_P (x) = MEM_VOLATILE_P (y);
      XEXP (x, 0) = plus_constant (XEXP (y, 0), offset);
    }

  return x;
}

The #if WORDS_BIG_ENDIAN statement was added.  Again, there may be a better
way to fix the problem but this is working for me.

Tom Mueller			AT&T Bell Laboratories (CBE 64E-327)
(614) 860-5287			6400 East Broad Street
trm@cblpn.cb.att.com		Columbus, OH  43213
Technical Details
Message-ID: <9210291357.AA16979@life.ai.mit.edu>
Path: arc1-ca.pugleaf.net!sparky!uunet!think.com!sdd.hp.com!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!cblpn.ATt.COM!trm

Show Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug
Path: arc1-ca.pugleaf.net!sparky!uunet!think.com!sdd.hp.com!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!cblpn.ATt.COM!trm
From: trm@cblpn.ATt.COM
Subject: gcc/i860 bug report
Message-ID: <9210291357.AA16979@life.ai.mit.edu>
Sender: gnulists@ai.mit.edu
Organization: GNUs Not Usenet
Distribution: gnu
Date: Thu, 29 Oct 1992 13:53:00 GMT
Approved: bug-gcc@prep.ai.mit.edu
Lines: 135