[llvm-bugs] [Bug 28672] New: Integer divide by constant close to UINT*_MAX can be compare rather than divide

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Jul 22 13:48:04 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=28672

            Bug ID: 28672
           Summary: Integer divide by constant close to UINT*_MAX can be
                    compare rather than divide
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: simon.hosie at arm.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

When doing unsigned division by an integer which is greater than `UINT_MAX / 2`
(or another range limit in place of UINT_MAX, as appropriate), the result can
be only 0 or 1, and this can be evaluated with a compare rather than a
reciprocal-multiply (or divide).

For example:

    uint32_t f(uint32_t x) { return (x + 1) % 4000569407; }

is equivalent to:

    uint32_t f(uint32_t x) { x++; return x < 4000569407 ? x : x - 4000569407; }

Clang gives me:

        clang --target=arm-linux-gnueabihf -O3 -S -o- p1modk.c

        ldr     r1, .LCPI0_0        // 316062335
        add     r0, r0, #1
        umull   r1, r2, r0, r1
        sub     r1, r0, r2
        add     r1, r2, r1, lsr #1
        ldr     r2, .LCPI0_1        // 4000569407
        lsr     r1, r1, #31
        mul     r1, r1, r2
        sub     r0, r0, r1

I expect something more like:

        ldr     r1, =4000569407
        add     r0, r0, #1
        cmp     r0, r1
        subhs   r0, r0, r1


Note that this applicable in loops containing the `x = (x + 1) % k;` idiom if x
can be shown to be never greater than k (even if k is variable, I think).

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160722/1aa08d81/attachment.html>


More information about the llvm-bugs mailing list