Hi, This patch (diff-reload) backports fixes for a couple of problems in PowerPC reload handling.
Thanks, Bill 2014-03-19 Bill Schmidt <wschm...@linux.vnet.ibm.com> Apply mainline r207798 2014-02-26 Alan Modra <amo...@gmail.com> PR target/58675 PR target/57935 * config/rs6000/rs6000.c (rs6000_secondary_reload_inner): Use find_replacement on parts of insn rtl that might be reloaded. Backport from mainline r208287 2014-03-03 Bill Schmidt <wschm...@linux.vnet.ibm.com> * config/rs6000/rs6000.c (rs6000_preferred_reload_class): Disallow reload of PLUS rtx's outside of GENERAL_REGS or BASE_REGS; relax constraint on constants to permit them being loaded into GENERAL_REGS or BASE_REGS. Index: gcc-4_8-test/gcc/config/rs6000/rs6000.c =================================================================== --- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.c +++ gcc-4_8-test/gcc/config/rs6000/rs6000.c @@ -16380,7 +16380,7 @@ rs6000_secondary_reload_inner (rtx reg, rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p); rclass = REGNO_REG_CLASS (regno); - addr = XEXP (mem, 0); + addr = find_replacement (&XEXP (mem, 0)); switch (rclass) { @@ -16391,19 +16391,18 @@ rs6000_secondary_reload_inner (rtx reg, if (GET_CODE (addr) == AND) { and_op2 = XEXP (addr, 1); - addr = XEXP (addr, 0); + addr = find_replacement (&XEXP (addr, 0)); } if (GET_CODE (addr) == PRE_MODIFY) { - scratch_or_premodify = XEXP (addr, 0); + scratch_or_premodify = find_replacement (&XEXP (addr, 0)); if (!REG_P (scratch_or_premodify)) rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p); - if (GET_CODE (XEXP (addr, 1)) != PLUS) + addr = find_replacement (&XEXP (addr, 1)); + if (GET_CODE (addr) != PLUS) rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p); - - addr = XEXP (addr, 1); } if (GET_CODE (addr) == PLUS @@ -16411,6 +16410,8 @@ rs6000_secondary_reload_inner (rtx reg, || !rs6000_legitimate_offset_address_p (PTImode, addr, false, true))) { + /* find_replacement already recurses into both operands of + PLUS so we don't need to call it here. */ addr_op1 = XEXP (addr, 0); addr_op2 = XEXP (addr, 1); if (!legitimate_indirect_address_p (addr_op1, false)) @@ -16486,7 +16487,7 @@ rs6000_secondary_reload_inner (rtx reg, || !VECTOR_MEM_ALTIVEC_P (mode))) { and_op2 = XEXP (addr, 1); - addr = XEXP (addr, 0); + addr = find_replacement (&XEXP (addr, 0)); } /* If we aren't using a VSX load, save the PRE_MODIFY register and use it @@ -16498,14 +16499,13 @@ rs6000_secondary_reload_inner (rtx reg, || and_op2 != NULL_RTX || !legitimate_indexed_address_p (XEXP (addr, 1), false))) { - scratch_or_premodify = XEXP (addr, 0); + scratch_or_premodify = find_replacement (&XEXP (addr, 0)); if (!legitimate_indirect_address_p (scratch_or_premodify, false)) rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p); - if (GET_CODE (XEXP (addr, 1)) != PLUS) + addr = find_replacement (&XEXP (addr, 1)); + if (GET_CODE (addr) != PLUS) rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p); - - addr = XEXP (addr, 1); } if (legitimate_indirect_address_p (addr, false) /* reg */ @@ -16765,8 +16765,14 @@ rs6000_preferred_reload_class (rtx x, en && easy_vector_constant (x, mode)) return ALTIVEC_REGS; - if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS)) - return NO_REGS; + if ((CONSTANT_P (x) || GET_CODE (x) == PLUS)) + { + if (reg_class_subset_p (GENERAL_REGS, rclass)) + return GENERAL_REGS; + if (reg_class_subset_p (BASE_REGS, rclass)) + return BASE_REGS; + return NO_REGS; + } if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS) return GENERAL_REGS;