On 11/23/2016 07:57 PM, Bernd Schmidt wrote:
2. The i386 backend mishandles SET rtxs. If you have a fairly plain single-insn SET, you tend to get COSTS_N_INSNS (2) out of set_rtx_cost, because rtx_costs has a default of COSTS_N_INSNS (1) for a SET, and you get the cost of the src in addition to that.
Bernd
PR rtl-optimization/78120 * config/i386/i386.c (ix86_rtx_costs): Fully handle SETs. Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c (revision 242038) +++ gcc/config/i386/i386.c (working copy) @@ -39925,6 +39925,7 @@ ix86_rtx_costs (rtx x, machine_mode mode enum rtx_code code = GET_CODE (x); enum rtx_code outer_code = (enum rtx_code) outer_code_i; const struct processor_costs *cost = speed ? ix86_cost : &ix86_size_cost; + int src_cost; switch (code) { @@ -39935,7 +39936,23 @@ ix86_rtx_costs (rtx x, machine_mode mode *total = ix86_set_reg_reg_cost (GET_MODE (SET_DEST (x))); return true; } - return false; + + if (register_operand (SET_SRC (x), VOIDmode)) + /* Avoid potentially incorrect high cost from rtx_costs + for non-tieable SUBREGs. */ + src_cost = 0; + else + { + src_cost = rtx_cost (SET_SRC (x), mode, SET, 1, speed); + + if (CONSTANT_P (SET_SRC (x))) + /* Constant costs assume a base value of COSTS_N_INSNS (1) and add + a small value, possibly zero for cheap constants. */ + src_cost += COSTS_N_INSNS (1); + } + + *total = src_cost + rtx_cost (SET_DEST (x), mode, SET, 0, speed); + return true; case CONST_INT: case CONST: