Hi Vlad, Vladimir Makarov <vmaka...@redhat.com> writes: > The following patch fixes > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87305 > > The patch was bootstrapped and tested on x86-64 and ppc64 (be). > > Committed as rev. 267823. > > Index: ChangeLog > =================================================================== > --- ChangeLog (revision 267822) > +++ ChangeLog (working copy) > @@ -1,3 +1,12 @@ > +2019-01-10 Vladimir Makarov <vmaka...@redhat.com> > + > + PR rtl-optimization/87305 > + * lra-assigns.c > + (setup_live_pseudos_and_spill_after_risky_transforms): Check > + allocation for big endian pseudos used as paradoxical subregs and > + spill them if it is wrong. > + * lra-constraints.c (lra_constraints): Add a comment. > + > 2019-01-10 Richard Biener <rguent...@suse.de> > > PR tree-optimization/88792 > Index: lra-assigns.c > =================================================================== > --- lra-assigns.c (revision 267822) > +++ lra-assigns.c (working copy) > @@ -1146,12 +1146,12 @@ static void > setup_live_pseudos_and_spill_after_risky_transforms (bitmap > spilled_pseudo_bitmap) > { > - int p, i, j, n, regno, hard_regno; > + int p, i, j, n, regno, hard_regno, biggest_nregs, nregs_diff; > unsigned int k, conflict_regno; > poly_int64 offset; > int val; > HARD_REG_SET conflict_set; > - machine_mode mode; > + machine_mode mode, biggest_mode; > lra_live_range_t r; > bitmap_iterator bi; > int max_regno = max_reg_num (); > @@ -1166,8 +1166,26 @@ setup_live_pseudos_and_spill_after_risky > for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) > if ((pic_offset_table_rtx == NULL_RTX > || i != (int) REGNO (pic_offset_table_rtx)) > - && reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0) > - sorted_pseudos[n++] = i; > + && (hard_regno = reg_renumber[i]) >= 0 && lra_reg_info[i].nrefs > 0) > + { > + biggest_mode = lra_reg_info[i].biggest_mode; > + biggest_nregs = hard_regno_nregs (hard_regno, biggest_mode); > + nregs_diff = (biggest_nregs > + - hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (i))); > + enum reg_class rclass = lra_get_allocno_class (i); > + > + if (WORDS_BIG_ENDIAN > + && (hard_regno - nregs_diff < 0 > + || !TEST_HARD_REG_BIT (reg_class_contents[rclass], > + hard_regno - nregs_diff))) > + { > + /* Hard registers of paradoxical sub-registers are out of > + range of pseudo register class. Spill the pseudo. */ > + reg_renumber[i] = -1; > + continue; > + }
I think for !WORDS_BIG_ENDIAN the equivalent problem to: || !TEST_HARD_REG_BIT (reg_class_contents[rclass], hard_regno - nregs_diff))) would be: || !TEST_HARD_REG_BIT (reg_class_contents[rclass], hard_regno + biggest_nregs - 1))) Where does that little-endian check happen? I wasn't sure why "biggest_mode goes outside the class" problems only occured here for big-endian. Thanks, Richard