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)