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;

Reply via email to