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

Reply via email to