https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69442
--- Comment #2 from Zdenek Sojka <zsojka at seznam dot cz> --- (In reply to ktkachov from comment #1) > Does this occur for other optimisations levels? It happens only with -Og. Difference -O1 -> -Og: @@ -22,6 +22,8 @@ @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. push {r4, r5} + mvn r0, r0, lsr #16 + mvn r0, r0, lsl #16 subs r2, r2, #255 sbc r3, r3, #0 mvn r4, #24 @@ -29,15 +31,12 @@ movt r5, 65535 cmp r3, r5 cmpeq r2, r4 - movcs r1, #1 - movcc r1, #0 - mvn r4, #24 - umull r4, r5, r1, r4 - sub r5, r5, r1, lsl #16 + movcs r4, #1 + movcc r4, #0 + mvn r1, #24 + umull r4, r5, r4, r1 subs r2, r2, r4 sbc r3, r3, r5 - mvn r0, r0, lsr #16 - mvn r0, r0, lsl #16 adds r4, r2, r0 adc r5, r3, #0 mov r0, r4 The code is the same, except; - sub r5, r5, r1, lsl #16 which is missing in the -Og code. > The modulo by a power of 2 expansion was changed for arm for GCC 6 but that > was for signed values, whereas the testcase uses unsigned variables and the > modulo operation is not by a power of 2... Maybe the problem is in the older GCC branches as well, but it is not exposed on this particular testcase.