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
There was an error while thanking
Thanking...

Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod