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; }