While writing the Thunder tunings, I got an internal compiler error
while building glibc.  The reduced testcase is:
  typedef unsigned int size_t;
  typedef unsigned int wchar_t;
  extern __thread int __libc_errno;
  extern __thread int *  t;
  int _IO_vfprintf_internal (char *string, char *workend, char *f) {
    int save_errno = __libc_errno;
   do
   {
       int prec = (workend - string);
       string = (char *) __strerror_r (save_errno);
 if ( *t == 1)
 {
 size_t ignore_size = (unsigned) prec > 1024 ? 1024 : prec;
 wchar_t ignore[ignore_size];
 const char *str2 = string;
 const char *strend = string + prec;
 int ps;
 while (str2 != ((void *)0) && str2 < strend)
__mbsnrtowcs (ignore, &str2 ,&ps) ;
 }
     }
   while (*f != '\0');
}
----  CUT ---
I changed the cost of moving between two neon registers (FP_REGS
register class) to be the same as the cost of moving between a
GENERAL_REGS and a FP_REGS class. This caused the cost of moving
between the STACK_REG and FP_REGS being the same FP_REGS and
GENERAL_REGS which is incorrect as it has to go through a
GENERAL_REGS.

This patch fixes the problem by changing the cost of the move between
STACK_REG and FP_REGS to the cost of moving via a GENERAL_REGS.

OK? Built and tested on aarch64-elf with no regressions.

Thanks,
Andrew Pinski

ChangeLog:
* config/aarch64/aarch64.c (aarch64_register_move_cost): Correct cost
of moving from/to the STACK_REG register class.
Index: config/aarch64/aarch64.c
===================================================================
--- config/aarch64/aarch64.c    (revision 206611)
+++ config/aarch64/aarch64.c    (working copy)
@@ -4870,6 +4870,16 @@ aarch64_register_move_cost (enum machine
   const struct cpu_regmove_cost *regmove_cost
     = aarch64_tune_params->regmove_cost;
 
+  /* Moving between GPR and stack cost is the same as GP2GP. */
+  if ((from == GENERAL_REGS && to == STACK_REG)
+      || (to == GENERAL_REGS && from == STACK_REG))
+    return regmove_cost->GP2GP;
+
+  /* To/From the stack register, is the move via the gprs. */
+  if (to == STACK_REG || from == STACK_REG)
+    return aarch64_register_move_cost (mode, from, GENERAL_REGS)
+            + aarch64_register_move_cost (mode, GENERAL_REGS, to);
+
   if (from == GENERAL_REGS && to == GENERAL_REGS)
     return regmove_cost->GP2GP;
   else if (from == GENERAL_REGS)

Reply via email to