| Electronics > Microcontrollers |
| GCC compiler divmod call generation for Cortex-M0 |
| (1/3) > >> |
| cv007:
Any explanation for the following generation of div calls for the following test? https://godbolt.org/z/zbWzhjG9Y line 14 - comment/uncomment to see changes If the base_ var is global, the compiler generates a single call to uidivmod, and if the var is local (or static) it generates a call to uidivmod but also another to uidiv. For some reason it appears the optimization is opposite of what it should be, or normally is. What am I missing here? |
| brucehoult:
Because it sees that 10 is a constant and distributes it to the two divisions before noticing that actually there is no division instruction on that CPU. If you change the CPU to M3 then there is a single division instruction generated for the divide by 10, and a multiply-subtract to get the remainder. Even if you change it to ... --- Code: ---u32 q = u / base_; u32 r = u - q * base_; return q + r; --- End code --- ... it just puts the 2nd division back in again. |
| brucehoult:
Even the latest version of GCC does the same. Every version of Clang from 9 to head generates some variation on: --- Code: ---test1(unsigned int): push {r4, r5, r7, lr} add r7, sp, #8 mov r4, r0 movs r5, #10 mov r1, r5 bl __aeabi_uidiv muls r5, r0, r5 subs r1, r4, r5 adds r0, r1, r0 pop {r4, r5, r7, pc} --- End code --- |
| SiliconWizard:
If you declare base_ 'constexpr', you'll also get the double div thing. Fun. :popcorn: |
| mikerj:
Turn off optimisations and you get the two calls for any combination of global/local/constexpr, so it seems like an optimiser failure. |
| Navigation |
| Message Index |
| Next page |