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