[backport from gcc-4.7/trunk r184310, fixes missed-optimization regression PR52208 from PR37273 patch ] gcc/ 2012-02-16 Jakub Jelinek PR rtl-optimization/52208 * ira-costs.c (scan_one_insn): Don't decrease mem_cost for MEMs with REG_EQUIV, if the MEM isn't general_operand. --- gcc-4.6.3/gcc/ira-costs.c.~1~ 2012-03-10 14:17:41.000000000 +0100 +++ gcc-4.6.3/gcc/ira-costs.c 2012-03-10 14:21:51.000000000 +0100 @@ -1029,13 +1029,20 @@ scan_one_insn (rtx insn) Similarly if we're loading other constants from memory (constant pool, TOC references, small data areas, etc) and this is the only - assignment to the destination pseudo. */ + assignment to the destination pseudo. + + Don't do this if SET_SRC (set) isn't a general operand, if it is + a memory requiring special instructions to load it, decreasing + mem_cost might result in it being loaded using the specialized + instruction into a register, then stored into stack and loaded + again from the stack. See PR52208. */ if (set != 0 && REG_P (SET_DEST (set)) && MEM_P (SET_SRC (set)) && (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != NULL_RTX && ((MEM_P (XEXP (note, 0))) || (CONSTANT_P (XEXP (note, 0)) && LEGITIMATE_CONSTANT_P (XEXP (note, 0)) - && REG_N_SETS (REGNO (SET_DEST (set))) == 1))) + && REG_N_SETS (REGNO (SET_DEST (set))) == 1)) + && general_operand (SET_SRC (set), GET_MODE (SET_SRC (set)))) { enum reg_class cl = GENERAL_REGS; rtx reg = SET_DEST (set);