public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* More fp bug in egcs
@ 1998-04-25 18:25 H.J. Lu
  1998-04-27 21:29 ` Jim Wilson
  1998-04-30 20:03 ` Jim Wilson
  0 siblings, 2 replies; 22+ messages in thread
From: H.J. Lu @ 1998-04-25 18:25 UTC (permalink / raw)
  To: wilson, law, scox, crux; +Cc: egcs

Hi,

I discovered this x86 fp bug by accident.

# gcc -B/home/work/gnu/bin/egcs/gcc/ -S  mpgeomnn.c
gcc: Internal compiler error: program cc1 got fatal signal 6

It is very similar to the one fixed by Jim. It will compile if -O is
used. I think it may have something to do with Jim's patch. In the
greg rtl dump, the clobbered register is used as input in the next
insn.

Thanks.


-- 
H.J. Lu (hjl@gnu.org)
---mpgeomnn.c---
typedef struct _geom_elem {
  double        coeffs[6];
  double        constant[3 ];
  int		do_band[3];
} pGeomDefRec, *pGeomDefPtr;
typedef struct _mpgeombanddef {
	double	first_mlow,	 
		first_mhigh;	 
	int	first_ilow,	 
		first_ihigh;	 
	double	*s_locs;	 
	int	*x_locs;	 
	int	x_start;
	int	x_end;
	int	int_constant;	 
	int	yOut;		 
	int	out_width;	 
	int	out_height;	 
	int	in_width;	 
	int	in_height;
	int	lo_src_available;  
	int	hi_src_available;
	void	(*linefunc) ();
	void	(*fillfunc) ();
} mpGeometryBandRec, *mpGeometryBandPtr;
typedef void *pointer;
typedef unsigned char  CARD8;
typedef CARD8 BytePixel;
static void  BiGL_B  (OUTP,srcimg,width,sline,pedpvt,pvtband)	pointer OUTP;	pointer *srcimg;	register int width;	int sline;	pGeomDefPtr pedpvt; mpGeometryBandPtr pvtband;	{	register float s, t, st;	register double a  = pedpvt->coeffs[0];	register double c  = pedpvt->coeffs[2];	register double srcpix  = a * ((double)(0.0000))  +	pedpvt->coeffs[1] * (pvtband->yOut + ((double)(0.0000)) ) +	pedpvt->coeffs[4];	register double srcline = c * ((double)(0.0000))  +	pedpvt->coeffs[3] * (pvtband->yOut + ((double)(0.0000)) ) +	pedpvt->coeffs[5];	register int 	isrcline,isrcpix;	register   BytePixel  constant = (  BytePixel ) pvtband->  int_constant ;	register   BytePixel  *outp	= (  BytePixel  *) OUTP;	register   BytePixel  *ptrIn, *ptrJn;	register   BytePixel  val;	register int 	srcwidth = pvtband->in_width - 1;	register int 	minline  = pvtband->lo_src_available;	register int 	maxline  = pvtband->hi_src_available;	while ( width > 0 ) { isrcline = srcline; isrcpix  = srcpix; val = constant; if ( (isrcline >= minline) && (isrcline < maxline) ) {	s = srcpix - isrcpix;	ptrIn = (  BytePixel  *) srcimg[isrcline]; t = srcline - isrcline;	ptrJn = (  BytePixel  *) srcimg[isrcline+1]; st = s * t;	if ( (isrcpix >= 0) && (isrcpix < srcwidth) )	val =	ptrIn[isrcpix]   * ((float)1. - s - t + st) + ptrIn[isrcpix+1] * (s - st) +	ptrJn[isrcpix]   * (t - st) +	ptrJn[isrcpix+1] * (st) +   (float)0.5 ;	}	width--; srcline += c; srcpix  += a; *outp++ = val; }	} 

^ permalink raw reply	[flat|nested] 22+ messages in thread
* Re: More fp bug in egcs
@ 1998-05-03  0:55 H.J. Lu
  1998-05-03 12:03 ` H.J. Lu
  1998-05-03 20:10 ` Jim Wilson
  0 siblings, 2 replies; 22+ messages in thread
From: H.J. Lu @ 1998-05-03  0:55 UTC (permalink / raw)
  To: wilson, law, scox, p3; +Cc: egcs

> 
> > 
> > I believe this is another bug in the same i386 code as my last patch.
> > 
> > The problem is that the only FP->DImode converstion instruction pops the
> > FP stack.  Normally we have both popping and non-popping versions of
> > instructions.  The x86 code handles this by aborting if we need to emit
> > the non-existent non-popping instruction.  However, this can't work all
> > of the time, because it assumes the optimizer always generates optimal
> > code.  That isn't safe.  And it is obviously not safe if we are compiling
> > without optimization.
> > 
> > In order to fix this, we need to emulate the missing instruction if gcc
> > needs to emit it.  The following patch does this.   If there is a better way
> > to do this, then let me know.
> > 
> > Thu Apr 30 19:28:16 1998  Jim Wilson  <wilson@cygnus.com>
> > 
> > 	* i386.c (output_fix_trunc): Add code to emulate non-popping DImode
> > 	case.
> > 
> > *** i386.c	Sun Feb 15 11:54:11 1998
> > --- /home/wilson/tmp/i386.c	Thu Apr 30 19:26:54 1998
> > *************** output_fix_trunc (insn, operands)
> > *** 3731,3738 ****
> >     int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
> >     rtx xops[2];
> >   
> > !   if (! STACK_TOP_P (operands[1]) ||
> > !       (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
> >       abort ();
> >   
> >     xops[0] = GEN_INT (12);
> > --- 3731,3737 ----
> >     int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
> >     rtx xops[2];
> >   
> > !   if (! STACK_TOP_P (operands[1]))
> >       abort ();
> >   
> >     xops[0] = GEN_INT (12);
> > *************** output_fix_trunc (insn, operands)
> > *** 3750,3755 ****
> > --- 3749,3765 ----
> >       {
> >         if (stack_top_dies)
> >   	output_asm_insn (AS1 (fistp%z0,%0), operands);
> > +       else if (GET_MODE (operands[0]) == DImode && ! stack_top_dies)
> > + 	{
> > + 	  /* There is no DImode version of this without a stack pop, so
> > + 	     we must emulate it.  It doesn't matter much what the second
> > + 	     instruction is, because the value being pushed on the FP stack
> > + 	     is not used except for the following stack popping store.
> > + 	     This case can only happen without optimization, so it doesn't
> > + 	     matter that it is inefficient.  */
> > + 	  output_asm_insn (AS1 (fistp%z0,%0), operands);
> > + 	  output_asm_insn (AS1 (fild%z0,%0), operands);
> > + 	}
> >         else
> >   	output_asm_insn (AS1 (fist%z0,%0), operands);
> >       }
> > 
> 
> Here is the trimmed down test case. I am not sure if your patch is
> correct. If you take look at the stack RTL dump, you will see SF 1 in
> 
> (define_insn ""
>   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
>         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "+f")))) 
>    (clobber (match_dup 1))
>    (clobber (match_operand:SI 2 "memory_operand" "m"))        
>    (clobber (match_operand:DI 3 "memory_operand" "m"))
>    (clobber (match_scratch:SI 4 "=&q"))]
>   "TARGET_80387"
>   "* return output_fix_trunc (insn, operands);")                 
> 
> is used as the input for the next insn:
> 
> ;; Insn is not within a basic block
> (insn:QI 104 269 272 (parallel[ 
>             (set (mem:DI (plus:SI (reg:SI 6 %ebp)
>                         (const_int -144)))
>                 (fix:DI (fix:SF (reg:SF 8 %st(0)))))
>             (clobber (reg:SF 8 %st(0)))
>             (clobber (mem:SI (plus:SI (reg:SI 6 %ebp)
>                         (const_int -4))))
>             (clobber (mem:DI (plus:SI (reg:SI 6 %ebp)
>                         (const_int -12))))
>             (clobber (reg:SI 1 %edx))
>         ] ) 117 {fix_truncxfsi2-1} (nil)
>     (nil))
> 
> ;; Insn is not within a basic block
> (insn:QI 272 104 275 (set (mem:SF (plus:SI (reg:SI 6 %ebp)
>                 (const_int -148)))
>         (reg:SF 8 %st(0))) -1 (nil)
>     (expr_list:REG_DEAD (reg:DF 8 %st(0))
>         (nil)))
> 
> I don't know if it is correct. Did gcc know %st(0) was not the same
> %st(0) before?
> 

How does this patch look? It works for my test case.

I think it is a reload bug. I don't know what the purpose to output the
last reload for a dead register. I don't what the best solution is and
I am not sure if my patch covers all cases.

Thanks.


---
Sun May  3 00:35:41 1998  H.J. Lu  (hjl@gnu.org)

	* reload1.c (emit_reload_insns): Don't output the last reload
	insn if OLD is dead at the end of INSN.

--- ../../../import/egcs/gcc/reload1.c	Mon Apr 20 08:23:47 1998
+++ reload1.c	Sun May  3 00:49:52 1998
@@ -6729,7 +6729,8 @@ emit_reload_insns (insn)
 #endif
 
 	  /* Output the last reload insn.  */
-	  if (! special)
+	  if (! special && (GET_CODE (old) != REG
+			    || !dead_or_set_p (insn, old)))
 	    gen_reload (old, reloadreg, reload_opnum[j],
 			reload_when_needed[j]);
 

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~1998-05-08 16:04 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-04-25 18:25 More fp bug in egcs H.J. Lu
1998-04-27 21:29 ` Jim Wilson
1998-04-30 20:03 ` Jim Wilson
1998-05-02 18:56   ` H.J. Lu
1998-05-03 20:10     ` Jim Wilson
1998-05-05  0:35     ` Jeffrey A Law
1998-05-05 19:14       ` H.J. Lu
1998-05-06 11:49         ` Jim Wilson
1998-05-05  5:03   ` Jeffrey A Law
1998-05-06 17:12   ` A patch for PPro H.J. Lu
1998-05-06 18:14     ` Jeffrey A Law
1998-05-07 15:31     ` Jim Wilson
1998-05-03  0:55 More fp bug in egcs H.J. Lu
1998-05-03 12:03 ` H.J. Lu
1998-05-03 17:14   ` Jim Wilson
1998-05-04 11:17     ` H.J. Lu
1998-05-04 18:07       ` Jeffrey A Law
1998-05-04 18:07         ` H.J. Lu
1998-05-04 22:00           ` Jeffrey A Law
1998-05-08 16:04           ` Jeffrey A Law
1998-05-03 20:10 ` Jim Wilson
1998-05-05  5:46   ` Jeffrey A Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).