http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48381

Vladimir Makarov <vmakarov at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |vmakarov at redhat dot com

--- Comment #2 from Vladimir Makarov <vmakarov at redhat dot com> 2011-03-31 
19:06:57 UTC ---
Jakub, thanks for reducing the test.  It really saved my time.

We have the following situation:

      Allocno a7r74 of CREG(1) has 1 avail. regs 2 (confl regs =  0 1 3-51 )
node:  2
      ...
      Allocno a10r80 of GENERAL_REGS(6) has 5 avail. regs obj 0 0-5 (confl regs
=  6-51 ) node:  0-5,  obj 1 0-5 (confl regs =  6-51 ) node:  0-5
      ...
      Popping a7(r74,l0)  -- assign reg 2
      ..
      Popping a10(r80,l0)  -- (memory is more profitable 7000 vs 2147483647)
spill
...
Spilling a7r74 for a10r80
Assigning 1 to a10r80
       a7(r74,l0)  -- assign hard reg 2

r74 got C reg and r80 was spilled.  Than function improve_allocation decides
that spilling r74 and assigning hard reg to r84 is more profitable.  The
function at the end of its work was trying to assign another hard reg to r74
and assign C reg again which is wrong because of r80 needs two hard registers
DX and CX.

The wrong assignment is because of wrong code in function (assign_hard_reg)
searching conflicting hard regs.  The code deciding that conflicting allocnos
really conflicts looks like

              hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
              if (hard_regno >= 0                                          
                 && ira_class_hard_reg_index[aclass][hard_regno] >= 0)

where aclass is class of r84 (CREGS) and hard_regno is r80 hard regno (DX). 
This code was ok for cover classes.  It should be different when different
classes of allocnos can intersect.

I'll send a patch to solve the PR soon.

Reply via email to