http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55211
--- Comment #25 from davem at gcc dot gnu.org 2012-11-06 22:32:40 UTC --- Just an update. I know what the exact problem is. Actually it's a combination of things. Because of the way that IRA maintains it's hard reg sets, it can end up thinking that odd integer registers are legitimate to allocate for DImode values. Specifically, when an allocno's ->profitable_regs is populated, it sets bits for both registers in a DImode pair (actually this happens when populating ira_useful_class_mode_regs[][], which in turn get copied into the initial value of ->profitable_regs). Then during allocation, the bits are tested individually. So say that all the integer register pairs are set in the profitable_regs reg set. Then %o0 is allocated for an SImode value. IRA thinks that it's ok to allocate %o1 for a DImode pseudo because %o1 and %o2 are set in the hard register set. Even if the above problem is solved, the next problem we run into has to do with argument passing. Normally if we have something like (set (reg:DI %o1) ...) it will get split up into two SImode moves. But this cannot happen if the SET_SRC is a non-offsetable MEM. We relied upon the constraint that got removed to force a reload in this situation. I am going to do one of two possible things tonight to solve this. I'll either create a new register class for these even DImode hard regs, or I'll simply revert my change.