bootstrapped / regtested on i686-pc-linux-gnu build / regtested for i686-pc-linux-gnu X sh-elf
Also, Andreas Schwab reported in the PR that he has successfully tested this patch on m68k.
2013-05-29 Joern Rennecke <joern.renne...@embecosm.com> PR rtl-optimization/57439 * postreload.c (move2add_valid_value_p): Check that we have a zero subreg_regno_offset when accessing the register in the requested mode. Index: postreload.c =================================================================== --- postreload.c (revision 199387) +++ postreload.c (working copy) @@ -1726,10 +1726,25 @@ move2add_record_sym_value (rtx reg, rtx static bool move2add_valid_value_p (int regno, enum machine_mode mode) { - if (reg_set_luid[regno] <= move2add_last_label_luid - || !MODES_OK_FOR_MOVE2ADD (mode, reg_mode[regno])) + if (reg_set_luid[regno] <= move2add_last_label_luid) return false; + if (mode != reg_mode[regno]) + { + if (!MODES_OK_FOR_MOVE2ADD (mode, reg_mode[regno])) + return false; + /* For big endian, the starting regno for the subreg might be + different. */ + int s_off = subreg_lowpart_offset (mode, reg_mode[regno]); + s_off = subreg_regno_offset (regno, reg_mode[regno], s_off, mode); + if (s_off != 0) + /* We could in principle adjust regno, check reg_mode[regno] to be + BLKmode, and return s_off to the caller (vs. -1 for failure), + but we currently have no callers that could make use of this + information. */ + return false; + } + for (int i = hard_regno_nregs[regno][mode] - 1; i > 0; i--) if (reg_mode[regno + i] != BLKmode) return false;