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: [email protected]
ReportedBy: [email protected]
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;