http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48345
Summary: [4.7 Regression] [SH] Invalid float register allocated Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization AssignedTo: unassig...@gcc.gnu.org ReportedBy: kkoj...@gcc.gnu.org sh4-unknown-linux-gnu fails to build on trunk revision 171649 during compiling libgfortran. The compiler generates invalid float instructions using wrong drN registers. A typical example in the C testsuite is gcc.c-torture/compile/pr34091.c with -O2 which produces the instruction like fadd dr14,dr3 which is reproduced on sh-elf -m4 -ml too. On SH with fpu, only even dr registers are valid double float registers, though the register allocator allocates dr3 which is invalid. .ira dump says that the problematic hard reg 67 corresponding dr3 is allocated: Secondary allocation: assign hard reg 67 to reg 757 where reg 757 is a DFmode register. It seems that ira-color.c:assign_hard_reg chooses a register of which corresponding bit of ira_prohibited_class_mode_regs [FP_REGS][DFmode] is set. The patch below looks to work for me, though I'm suspecting the real problem is in the target side. --- ORIG/trunk/gcc/ira-color.c 2011-03-29 10:08:17.000000000 +0900 +++ LOCAL/trunk/gcc/ira-color.c 2011-03-29 15:09:06.000000000 +0900 @@ -1692,6 +1692,9 @@ assign_hard_reg (ira_allocno_t a, bool r && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG) continue; #endif + if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode], + hard_regno)) + continue; if (! check_hard_reg_p (a, hard_regno, conflicting_regs, profitable_hard_regs)) continue;