reload problem in current CVS

Bernd Schmidt bernds@pathia.cygnus.co.uk
Mon Nov 29 06:03:00 GMT 1999


On Thu, 25 Nov 1999, Stephen L Moshier wrote:

> current egcs CVS at 25 November 1999
> i486-linux-gnu
> 
> /a/gnu/linux/gcc/xgcc -B/a/gnu/linux/gcc/ -I/a/gnu/linux/gcc/include -O1 -Wall -fno-builtin   -c tst.c
> tst.c:19: Internal compiler error in `reload', at reload1.c:1031

> extern float A[], B[];
> extern float MAXNUMF;
> float chbevlf(float, float *, int);
> float expf(float), i1f(float), logf(float), sqrtf(float);
> 
> float k1f(float xx)
> {
>   float x, y;
> 
>   x = xx;
>   if( x <= 2.0 )
>     {
>       y = x * x - 2.0;
>       y =  logf( 0.5f * x ) * i1f(x)  +  chbevlf( y, A, 7 ) / x;
>       return( y );
>     }
>   return(  expf(-x) * chbevlf( (float)(8.0/x - 2.0), B, 10 ) / sqrtf(x) );
> }

Is this OK for the testsuite (where did it come from)?

The abort happens because during reload_as_needed, we have a call to
get_secondary_mem which doesn't happen during the first pass of reload.

This happens while reloading this insn:

(insn 83 81 85 (parallel[
            (set (reg:SF 0 eax)
                (neg:SF (reg/v:SF 25)))
            (clobber (reg:CC 17 flags))
        ] ) 289 {*negsf2_if} (nil)
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))

which has the following definition:

(define_insn "*negsf2_if"
  [(set (match_operand:SF 0 "nonimmediate_operand" "=frm")
        (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0")))
   (clobber (reg:CC 17))]

debug_reload shows us:

Reload 0: reload_in (SF) = (reg/v:SF 25)
        reload_out (SF) = (reg:SF 0 eax)
        FLOAT_INT_REGS, RELOAD_OTHER (opnum = 0)
        reload_in_reg: (reg/v:SF 25)
        reload_out_reg: (reg:SF 0 eax)
        reload_reg_rtx: (reg:SF 0 eax)

This is OK, we don't need secondary memory if we use register eax as reload
register.  However, choose_reload_regs decides that it's better to inherit
the value of reg 25, which is still lying around in reg 8 (a stack reg).
This happens around here:

5969                  if (regno >= 0 && reg_last_reload_reg[regno] != 0)
5970                    {
5971                      enum reg_class class = rld[r].class, last_class;
5972                      rtx last_reg = reg_last_reload_reg[regno];
5973
5974                      i = REGNO (last_reg) + word;
5975                      last_class = REGNO_REG_CLASS (i);
5976                      if ((GET_MODE_SIZE (GET_MODE (last_reg))
5977                           >= GET_MODE_SIZE (mode) + word * UNITS_PER_WORD)
5978                          && reg_reloaded_contents[i] == regno
(gdb)
5979                          && TEST_HARD_REG_BIT (reg_reloaded_valid, i)
5980                          && HARD_REGNO_MODE_OK (i, rld[r].mode)
5981                          && (TEST_HARD_REG_BIT (reg_class_contents[(int) class], i)
5982                              /* Even if we can't use this register as a reload
5983                                 register, we might use it for reload_override_in,
5984                                 if copying it to the desired class is cheap
5985                                 enough.  */
5986                              || ((REGISTER_MOVE_COST (last_class, class)
5987                                   < MEMORY_MOVE_COST (mode, class, 1))
5988    #ifdef SECONDARY_INPUT_RELOAD_CLASS
(gdb)
5989                                  && (SECONDARY_INPUT_RELOAD_CLASS (class, mode,
5990                                                                    last_reg)
5991                                      == NO_REGS)
5992    #endif
5993    #ifdef SECONDARY_MEMORY_NEEDED
5994                                  && ! SECONDARY_MEMORY_NEEDED (last_class, class,
5995                                                                mode)
5996    #endif
5997                                  ))

Now, this if statement has a test against SECONDARY_MEMORY_NEEDED.  It doesn't
trigger, however.  LAST_CLASS is AREG, and CLASS is FLOAT_INT_REGS.
FLOAT_INT_REGS is a relatively recent addition, and SECONDARY_MEMORY_NEEDED
doesn't handle it.  Nor is it clear to me how it should be handled; the class
FLOAT_INT_REGS doesn't give us enough information to determine whether
secondary memory is needed.

Jan, is there any particular reason that the patterns which use FLOAT_INT_REGS
(like the one above) couldn't be written like this, i.e. splitting the
alternatives:

(define_insn "*negsf2_if"
  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
        (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
   (clobber (reg:CC 17))]

That should avoid this particular problem.

Bernd



More information about the Gcc-bugs mailing list