From mboxrd@z Thu Jan 1 00:00:00 1970 From: hjl@lucon.org (H.J. Lu) To: gafton@redhat.com (Cristian Gafton) Cc: rth@cygnus.com, egcs@cygnus.com, law@cygnus.com Subject: egcs 1.0.2 is broken on x86 and a patch for it. Date: Wed, 15 Apr 1998 19:57:00 -0000 Message-id: References: X-SW-Source: 1998-04/msg00614.html > > > Hello, > > Richard - Could you please send the the correct patch for the fortran > index problem from egcs 1.0.2 ? > > HJ and Richard: I have started to collect patches for 1.0.2. To date I > have the libio patch and the optimization patch (to fix ImageMagick > compile) from HJ. > > Other patches you might want in, I have to have them by the end of this > week. Technically, by thursday, because I will need some time to rebuild > the whole lot of packages... > egcs 1.0.2 is broken on x86. The test case here is miscompiled by -O2. Basically convert_regs () calls change_stack () with INSN to emit some insn after INSN. But some insn has been added after INSN so that change_stack () will emit some insn at the wrong place. As the result, the floating point is broken on x86. This patch seems to fix it. Could someone please take a look? Given the bugs we have seen in egcs 1.0.2, I suggest egcs 1.0.3 be made. Thanks. H.J. --- Wed Apr 15 08:01:56 1998 H.J. Lu (hjl@gnu.org) * reg-stack.c (subst_asm_stack_regs): Change to return the last new insn generated by this function. (subst_stack_regs): Likewise. (convert_regs): Record the last newly generated insn and use it for change_stack () instead of INSN. --- ../../../import/egcs/gcc/reg-stack.c Wed Apr 15 07:30:26 1998 +++ ./reg-stack.c Wed Apr 15 10:56:50 1998 @@ -262,9 +262,9 @@ static void move_for_stack_reg PROTO((r static void swap_rtx_condition PROTO((rtx)); static void compare_for_stack_reg PROTO((rtx, stack, rtx)); static void subst_stack_regs_pat PROTO((rtx, stack, rtx)); -static void subst_asm_stack_regs PROTO((rtx, stack, rtx *, rtx **, +static rtx subst_asm_stack_regs PROTO((rtx, stack, rtx *, rtx **, char **, int, int)); -static void subst_stack_regs PROTO((rtx, stack)); +static rtx subst_stack_regs PROTO((rtx, stack)); static void change_stack PROTO((rtx, stack, stack, rtx (*) ())); static void goto_block_pat PROTO((rtx, stack, rtx)); @@ -2407,9 +2407,11 @@ subst_stack_regs_pat (insn, regstack, pa stack-like regs in asm statements. These rules are enforced by record_asm_stack_regs; see comments there for details. Any asm_operands left in the RTL at this point may be assume to meet the - requirements, since record_asm_stack_regs removes any problem asm. */ + requirements, since record_asm_stack_regs removes any problem asm. -static void + It returns the last new insn generated by this function. */ + +static rtx subst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints, n_inputs, n_outputs) rtx insn; @@ -2688,14 +2690,18 @@ subst_asm_stack_regs (insn, regstack, op break; } } + + return insn; } /* Substitute stack hard reg numbers for stack virtual registers in INSN. Non-stack register numbers are not changed. REGSTACK is the current stack content. Insns may be emitted as needed to arrange the - stack for the 387 based on the contents of the insn. */ + stack for the 387 based on the contents of the insn. -static void + It returns the last new insn generated by this function. */ + +static rtx subst_stack_regs (insn, regstack) rtx insn; stack regstack; @@ -2752,9 +2758,9 @@ subst_stack_regs (insn, regstack) decode_asm_operands (body, operands, operands_loc, constraints, NULL_PTR); get_asm_operand_lengths (body, n_operands, &n_inputs, &n_outputs); - subst_asm_stack_regs (insn, regstack, operands, operands_loc, - constraints, n_inputs, n_outputs); - return; + return subst_asm_stack_regs (insn, regstack, operands, + operands_loc, constraints, + n_inputs, n_outputs); } if (GET_CODE (PATTERN (insn)) == PARALLEL) @@ -2772,7 +2778,7 @@ subst_stack_regs (insn, regstack) REG_UNUSED will already have been dealt with, so just return. */ if (GET_CODE (insn) == NOTE) - return; + return insn; /* If we are reached by a computed goto which sets this same stack register, then pop this stack register, but maintain regstack. */ @@ -2821,6 +2827,8 @@ subst_stack_regs (insn, regstack) } else note_link = &XEXP (note, 1); + + return insn; } /* Change the organization of the stack so that it fits a new basic @@ -3061,7 +3069,7 @@ static void convert_regs () { register int block, reg; - register rtx insn, next; + register rtx insn, next, new; struct stack_def regstack; for (block = 0; block < blocks; block++) @@ -3087,6 +3095,7 @@ convert_regs () do { insn = next; + new = insn; next = NEXT_INSN (insn); /* Don't bother processing unless there is a stack reg @@ -3094,7 +3103,8 @@ convert_regs () floating point values). */ if (GET_MODE (insn) == QImode || GET_CODE (insn) == CALL_INSN) - subst_stack_regs (insn, ®stack); + /* We may have generated some new instructions here. */ + new = subst_stack_regs (insn, ®stack); } while (insn != block_end[block]); @@ -3117,7 +3127,7 @@ convert_regs () /* Likewise handle the case where we fall into the next block. */ if ((block < blocks - 1) && block_drops_in[block+1]) - change_stack (insn, ®stack, &block_stack_in[block+1], + change_stack (new, ®stack, &block_stack_in[block+1], emit_insn_after); } -------- static __inline double mypow (double __x, double __y) { register double __value; long __p = (long) __y; if (__y == (double) __p) { if (__p & 1) __x *= __x; if (__p == 0) return __x; } __asm __volatile__ ("fmul %%st(1)" : "=t" (__value) : "0" (__x), "u" (__y)); return __value; } const double E1 = 2.71828182845904523536028747135; double fact (double x) { double corr; corr = 1.0; return corr * mypow(x/E1, x); } int main () { double y, z; y = fact (46.2); z = mypow (46.2/E1, 46.2); printf ("%26.19e, %26.19e\n", y, z); if (y > z) y -= z; else y = z - y; y /= z; if (y > 0.1) abort (); return 0; }