This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Bug fix for egcs-1.1



I attach a patch based on the 19980816 egcs snapshot that fixes the
following bug:

On powerpc-unknown-linux-gnu, compiling the attached 'test12.c' with 
'gcc -O2 test12.c -o test12', and running it, the program abort()s,
when it should not.

The generated code for 'splat' is:

splat:
        stwu 1,-32(1)
        fadd 1,1,1
        stfd 1,8(1)
        lwz 9,8(1)
        lwz 10,12(1)
        ori 10,10,1
        stfd 1,dval@sdarel(13)
        la 1,32(1)
        blr

and there should be two (integer) stores and a (floating-point) load
after the 'ori' instruction.

This bug causes glibc (all 2.0.9x versions) to be miscompiled for that
configuration.

I haven't fully tested this fix, but I thought it was important enough
to send in anyway.  I am fairly confident it is correct.

-- 
Geoffrey Keating <geoffk@ozemail.com.au>

===File ~/patches/egcs-2.diff===============================
1998-08-19  Geoff Keating  <geoffk@ozemail.com.au>

	* reload1.c (forget_old_reloads_1): Don't look at SUBREG_WORD,
	forget all the register's reloads.

--- reload1.c~	Mon Aug 17 17:19:54 1998
+++ reload1.c	Wed Aug 19 00:16:07 1998
@@ -4252,6 +4252,8 @@ forget_old_reloads_1 (x, ignored)
 {
   register int regno;
   int nr;
+  /* 'offset' is actually unused, because the whole reg is reloaded at a
+     time.  */
   int offset = 0;
 
   /* note_stores does give us subregs of hard regs.  */
@@ -4264,7 +4266,7 @@ forget_old_reloads_1 (x, ignored)
   if (GET_CODE (x) != REG)
     return;
 
-  regno = REGNO (x) + offset;
+  regno = REGNO (x);
 
   if (regno >= FIRST_PSEUDO_REGISTER)
     nr = 1;
============================================================

===File ~/gcc-bugs/test12.c=================================
double dval = 0;
     
void splat (double d);

int main(void)
{
  splat(0);
  if (dval == 0)
    abort();
  return 0;
}

void splat (double d)
{
  union {
    double f;
    unsigned int l[2];
  } u;
  
  u.f = d + d;
  u.l[1] |= 1;
  asm volatile ("stfd %0,dval@sdarel(13)" : : "f" (u.f));
}
============================================================


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]