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.

Reply via email to