PR 45074 showed up a rather embarrassing oversight in the MIPS backend: global registers were still being treated as call-saved.
Fixed with the attached patch. Tested on mips64-linux-gnu and applied. Richard gcc/ * config/mips/mips.c (mips_cfun_call_saved_reg_p): Handle global registers. gcc/testsuite/ * gcc.target/mips/reg-var-1.c: New test. Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2011-04-16 09:02:10.000000000 +0100 +++ gcc/config/mips/mips.c 2011-04-17 11:14:53.000000000 +0100 @@ -9097,6 +9097,11 @@ mips_interrupt_extra_call_saved_reg_p (u static bool mips_cfun_call_saved_reg_p (unsigned int regno) { + /* If the user makes an ordinarily-call-saved register global, + that register is no longer call-saved. */ + if (global_regs[regno]) + return false; + /* Interrupt handlers need to save extra registers. */ if (cfun->machine->interrupt_handler_p && mips_interrupt_extra_call_saved_reg_p (regno)) Index: gcc/testsuite/gcc.target/mips/reg-var-1.c =================================================================== --- /dev/null 2011-04-17 10:56:28.045573347 +0100 +++ gcc/testsuite/gcc.target/mips/reg-var-1.c 2011-04-17 11:22:39.000000000 +0100 @@ -0,0 +1,16 @@ +/* { dg-do run } */ +register int g asm ("$18"); + +void __attribute__((noinline)) +test (void) +{ + g = g + 1; +} + +int +main (void) +{ + g = 2; + test (); + return g != 3; +}