🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by trm Thu, 29 Oct 1992 13:53
gcc/i860 bug report
#14
Author: 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
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads