On 31.05.2017 10:15, Jakub Jelinek wrote:
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


Are you saying that cost computation in GCC is fundamentally flawed
for anything that it not a single_set?

Johann

Reply via email to