On Wed, 14 May 2014, Sandra Loosemore wrote:

> > > When I was trying to benchmark another patch (which I'll be sending
> > > along shortly) with CSiBE for -mabi=64, I ran into an assembler error
> > > like this:
> > > 
> > > /tmp/ccJv2faG.s: Assembler messages:
> > > /tmp/ccJv2faG.s:1605: Error: a destination register must be supplied
> > > `jalr $31'
> > 
> > JALR patterns should have an explicit clobber of $31, which I thought
> > was also supposed to stop $31 from being used as the call address.
> 
> Hmmmmm.  Yes, that ought to work, in theory....
> 
> > Do you have a testcase?
> 
> I can reproduce the error in a current mipsisa64-elfoabi build, with my patch
> to delete ADJUST_REG_ALLOC_ORDER applied.  It triggers on this file from
> CSiBE:
> 
> mipsisa64-elfoabi-gcc -c -mabi=64 -O2 -fno-common -w
> csibe/src/./ttt-0.10.1.preproc/src/connect4.i

 I wonder if there's something fishy going on here.  I checked output 
produced with -dP and the offending instruction is emitted like this:

 #(call_insn 172 124 161 (parallel [
 #            (call (mem:SI (reg:DI 31 $31) [0 c4_setup S4 A32])
 #                (const_int 0 [0]))
 #            (clobber (reg:SI 31 $31))
 #        ]) c4_new.i:79 594 {call_internal}
 #     (expr_list:REG_DEAD (reg:DI 31 $31)
 #        (expr_list:REG_DEAD (reg:DI 7 $7)
 #            (expr_list:REG_DEAD (reg:DI 6 $6)
 #                (expr_list:REG_DEAD (reg:DI 5 $5)
 #                    (expr_list:REG_DEAD (reg:DI 4 $4)
 #                        (nil))))))
 #    (expr_list:DI (use (reg:DI 4 $4))
 #        (expr_list:SI (use (reg:DI 5 $5))
 #            (expr_list:SI (use (reg:DI 6 $6))
 #                (expr_list:SI (use (reg:DI 7 $7))
 #                    (nil))))))
        jalr    $31      # 172  call_internal/1 [length = 4]

so clearly the clobber is ignored, or perhaps rather considered a late 
clobber instead of an early clobber that's indeed required here.

 I have reduced your case a bit and attached the result to this e-mail.  
With this code I can reproduce the problem using the following command:

$ mips-sde-elf-gcc -S -dP -mabi=64 -O2 -fno-common -w -o c4_new.s c4_new.i

and current trunk with the patch you recently posted as archived at:

https://gcc.gnu.org/ml/gcc-patches/2014-05/msg01016.html

applied.  With the patch reverted the issue goes away ($17 is used for the 
jump), so clearly the register allocation order override made in 
mips_order_regs_for_local_alloc is currently covering an underlying bug.

  Maciej
typedef unsigned int size_t;

extern void *malloc (size_t __size);

typedef char bool;
typedef struct _Board {
  struct _Board *(*copy) (const struct _Board *);  
  void (*setup) (struct _Board *, int, int, int);
  void (*display) (struct _Board *);  
  int (*eval) (struct _Board *);
  void (*score) (struct _Board *, int *, int *);  
  bool (*full) (struct _Board *);      
  int (*winner) (struct _Board *);     
                         
  bool (*valid_move) (struct _Board *, int);  
  bool (*move) (struct _Board *, int, int);   
  void (*unmove) (struct _Board *);           
  int (*getmove) (struct _Board *, int, 
                int *, int *);  
  void (*help) (void);      
  char (*symbol) (struct _Board *, int, int);   
  void (*coords) (struct _Board *, int, char *);  
  int rows, cols;    
  int squares;       
  int *moves;  
  int nummoves;  
  int X_player;      
  int *board;       
  int **points;  
  int numpoints;
  int depth, depth2;   
  int *center;  
} Board;

Board *c4_copy (const Board *);
void c4_setup (Board *, int, int, int);
void c4_display (Board *);
int c4_eval (Board *);
inline bool c4_full (Board *);
int c4_winner (Board *);
bool c4_valid_move (Board *, int);
bool c4_move (Board *, int, int);
void c4_unmove (Board *);
int c4_getmove (Board *, int, int *, int *);
void c4_help (void);
char c4_symbol (Board *, int, int);
void c4_coords (Board *, int, char *);

Board *c4_new (int players, int size, int depth)
{
  Board *T = (Board *) malloc (sizeof (Board));
  Board *B = (Board *)T;
  int **points;
  int *board;
  int i, j, point = 0;
  int MyPE = 0;
  int rows, cols;

  B->copy = c4_copy;
  B->setup = c4_setup;
  B->display = c4_display;
  B->eval = c4_eval;
  B->full = c4_full;
  B->winner = c4_winner;
  B->valid_move = c4_valid_move;
  B->move = c4_move;
  B->unmove = c4_unmove;
  B->getmove = c4_getmove;
  B->help = c4_help;
  B->symbol = c4_symbol;
  B->coords = c4_coords;
  B->score = ((void *)0) ;

  rows = B->rows = 6;
  cols = B->cols = 7;
  B->squares = 7;  

  if (MyPE == 0)
    c4_setup ((Board *)T, players, depth, 0);

  B->board = (int *) malloc (rows*cols * sizeof(int));

  B->moves = (int *) malloc (rows*cols * sizeof(int));
  B->nummoves = 0;

  for (i = 0; i < rows*cols; i++)
    B->board[i] = B->moves[i] = 0;

  B->numpoints = rows*(cols-3) + cols*(rows-3) + 2*(rows-3)*(cols-3);
  points = (int **) malloc (B->numpoints * 4 * sizeof(int *));
  board = B->board;
   
  for (j = 0; j < rows - 3; j++) {
    for (i = 0; i < cols; i++, point++) {
      points[point*4+0] = board + i*rows + 0 + j;
      points[point*4+1] = board + i*rows + 1 + j;
      points[point*4+2] = board + i*rows + 2 + j;
      points[point*4+3] = board + i*rows + 3 + j;
    }
  }
  
  for (j = 0; j < cols - 3; j++) {
    for (i = 0; i < rows; i++, point++) {
      points[point*4+0] = board + i + 0*rows + j*rows;
      points[point*4+1] = board + i + 1*rows + j*rows;
      points[point*4+2] = board + i + 2*rows + j*rows;
      points[point*4+3] = board + i + 3*rows + j*rows;
    }
  }

  for (j = 0; j < cols - 3; j++) {
    for (i = 0; i < rows - 3; i++, point++) {
      points[point*4+0] = board + j*rows + i + 0*rows + 0;
      points[point*4+1] = board + j*rows + i + 1*rows + 1;
      points[point*4+2] = board + j*rows + i + 2*rows + 2;
      points[point*4+3] = board + j*rows + i + 3*rows + 3;
    }
  }
  for (j = 0; j < cols - 3; j++) {
    for (i = 0; i < rows - 3; i++, point++) {
      points[point*4+0] = board + j*rows + i + 0*rows + 3;
      points[point*4+1] = board + j*rows + i + 1*rows + 2;
      points[point*4+2] = board + j*rows + i + 2*rows + 1;
      points[point*4+3] = board + j*rows + i + 3*rows + 0;
    }
  }

  B->points = points;

  return T;
}

Reply via email to