https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82981

            Bug ID: 82981
           Summary: unnecessary __multi3 call for mips64r6 linux kernel
           Product: gcc
           Version: 7.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wilson at gcc dot gnu.org
  Target Milestone: ---

Given the testcase
unsigned long func(unsigned long a, unsigned long b)
{
        return a > (~0UL) / b;
}
compiled with -march=mips64r6 -mabi=64 -mexplicit-relocs -O2 we end up with a
call to __multi3 which is inefficient and inconvenient.

The testcase gets converted to 
  _1 = MUL_OVERFLOW (a_4(D), b_5(D));
  _2 = IMAGPART_EXPR <_1>;
There are no mulv patterns in the mips port, so it tries mulditi3 which fails,
and then calls __multi3.

Mips64r6 does have a widening DImode multiply which should have been used
instead.  The problem is that the *mulditi3 pattern is missing mips64r6
support.

Alternatively, the expander should try using a muldi3_highpart pattern when the
mulditi3 pattern doesn't work.  Especially when the highpart is the only part
we need as in this example.  The mips64r6 multi3_highpart is present.

Or alternatively, a mulvti3 pattern should be added to the mips port.

See for instance the thread at
    https://www.linux-mips.org/archives/linux-mips/2017-08/msg00041.html

Reply via email to