http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54674
--- Comment #8 from Oleg Endo <olegendo at gcc dot gnu.org> 2012-09-24 20:11:03 UTC --- (In reply to comment #7) > I'm working on a patch to avoid introducing a multiply by a pointer type, such > as happened here. > > The interesting thing is that this doesn't look like a profitable > transformation on most architectures. It appears that a multiply of two > registers and an add of two registers may be given the same RTL cost in the SH > family? It seems unlikely that those two operations have the same cost in > practice, so it might be worth looking into whether the cost model for this > target is fully implemented. I just checked the rtx_costs code on SH. You are right, plus/minus and mul might return the same cost. The cost function for mul doesn't even look at the operands to see whether they are regs, consts etc. This could probably be corrected, although I'm not sure of the consequences. I'll have to try it out. It seems that the mul costs return the number of insns a mul costs, not taking into account that mul insn execution time usually takes longer. The explanation why this ICE happens only for -Os seems to be sh.c (multcosts): if (optimize_size) return 2; return 3; Probably this was put like that to discourage conversions of muls into plus/shift insns when optimizing for size. The mul cost number could be made to be always higher than plus/minus, but there's also a target option that allows the user to specify the mul cost, which would then always return the fixed specified cost number. So I don't think it's a safe thing to rely on (that mul costs are always > plus/minus costs). For example, I'd catch power-of-two mul constants and return the shift costs, which then again would be the same as plus/minus for those constants.