https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109972
Bug ID: 109972
Summary: RISC-V: Could use umodsi3/udivsi3/divsi3 libcalls for
32-bit division/remainder on RV64 without M extension
Product: gcc
Version: 14.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: craig.topper at gmail dot com
Target Milestone: ---
There's an opportunity to improve code size for 32-bit division and remainder
on RV64 without the M extension.
Currently gcc calls the umoddi3/udivdi3/divdi3 functions by zero/sign extending
the operands. In the case of the unsigned functions this requires two shifts to
zero the upper bits. For signed, it's two sext.w if the operands are not
already sign extended.
All 3 functions are followed by a sext.w if the result needs be sign extended.
libgcc contains umodsi3/udivsi3/divsi3 functions that handle the zero extending
of inputs and sign extending the result. Internally they call the di3 functions
to do the computation. These functions could be used to reduce code size at the
caller.
There is no signed modsi3 function in libgcc. Probably because umoddi3(sext(X),
sext(Y)) is guaranteed to produce a result that is sign extended. gcc seems to
not know this and still emits a sext.w after the call to umoddi3.
godbolt https://godbolt.org/z/ax3Khc6cM
unsigned divu(unsigned x, unsigned y) {
return x / y;
}
unsigned remu(unsigned x, unsigned y) {
return x % y;
}
int div(int x, int y) {
return x / y;
}
int rem(int x, int y) {
return x % y;
}