https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126809

            Bug ID: 126809
           Summary: fold a division of a value clamped at the divisor
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: enhancement
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ktkachov at gcc dot gnu.org
  Target Milestone: ---

A value clamped at C reaches C exactly when the unclamped one does, so the
quotient by C is one there and zero below, which is a comparison, and the
remainder is the mirror:

  MIN (X, C) / C  ->  X >= C
  MIN (X, C) % C  ->  X < C ? X : 0

unsigned f (unsigned a) { unsigned t = a < 100 ? a : 100; return t / 100; }

at -O2 on aarch64 generates:
f:
        cmp     w0, 100
        mov     w1, 100
        csel    w0, w0, w1, ls
        mov     w1, 34079
        movk    w1, 0x51eb, lsl 16
        umull   x0, w0, w1
        lsr     x0, x0, 37
        ret

but Clang can do:
f:
        cmp     w0, #99
        cset    w0, hi
        ret

Reply via email to