On Wed, May 31, 2017 at 10:06:34AM +0200, Georg-Johann Lay wrote:
> Hi, this causes a performance degradation for avr.
>
> When optimizing for speed, and with a known denominatior, then v6 uses
> s/umulMM3_highpart insn to avoid division because no div instruction is
> available.
>
> unsigned scale256 (unsigned val)
> {
> return value / 255;
> }
>
> With this patch, v7 now uses __divmodhi4 which is very expensive but
> the costs are not computed because rtlanal.c:seq_cost assumes a cost of
> ONE:
>
> for (; seq; seq = NEXT_INSN (seq))
> {
> set = single_set (seq);
> if (set)
> cost += set_rtx_cost (set, speed);
> else
> cost++;
> }
>
> because divmod in not a single_set:
> (gdb) p seq
> $10 = (const rtx_insn *) 0x7ffff730d500
> (gdb) pr
> warning: Expression is not an assignment (and might have no effect)
> (insn 14 13 0 (parallel [
> (set (reg:HI 52)
> (div:HI (reg:HI 47)
> (reg:HI 54)))
> (set (reg:HI 53)
> (mod:HI (reg:HI 47)
> (reg:HI 54)))
> (clobber (reg:QI 21 r21))
> (clobber (reg:HI 22 r22))
> (clobber (reg:HI 24 r24))
> (clobber (reg:HI 26 r26))
> ]) "scale.c":7 -1
> (nil))
> (gdb)
>
> Hence the divmod appears to be much less expensive than the unsigned
> variant that computed the costs for mult_highpart.
Then you should fix the cost computation - be able to use a target hook
on insns that are not a single set or something similar.
Jakub