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

            Bug ID: 122004
           Summary: x86 optimization: (x > INT_MAX - c) can utilize
                    overflow flag to save code size
           Product: gcc
           Version: 15.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Explorer09 at gmail dot com
  Target Milestone: ---

When `x` is a signed integer, and the conditional is `(x > INT_MAX - c)` (`c`
is a compile time constant and 0 < c <= 0x7F), it's possible to check whether
`(x + c)` will overflow. This can save code size by using a one-byte immediate
operand instead of four-byte operand.

The conditional `(x < INT_MIN + c)` (1 < c <= 0x7F) can optimize in a similar
way, by checking whether `(x - c)` will overflow. (If c == 1, the `(x ==
INT_MIN)` case can use even smaller code by using the NEG instruction - see the
example code below.)

Although I file this optimization request for x86, I'm sure such optimization
is possible also for ARM and AArch64 targets (where there are CMP (immediate)
instructions).

```c
#include <stdbool.h>
#include <stdint.h>

bool func1a(int32_t x) {
    return x > 0x7FFFFFFF - 0x7F;
}
bool func1b(int32_t x) {
    int32_t res;
    return __builtin_sub_overflow(x, -0x7F, &res);
}

bool func2a(int32_t x) {
    return x < (-0x7FFFFFFF - 1) + 0x7F;
}
bool func2b(int32_t x) {
    int32_t res;
    return __builtin_sub_overflow(x, 0x7F, &res);
}

bool func3a(int32_t x) {
    return x < (-0x7FFFFFFF - 1) + 1;
}
bool func3b(int32_t x) {
    int32_t res;
    return __builtin_sub_overflow(x, 1, &res);
}
bool func3c(int32_t x) {
    int32_t res;
    return __builtin_sub_overflow(0, x, &res);
}
```

```assembly
func1a:
    cmpl $2147483520, %edi
    setg %al
    ret
func1b:
    addl $127, %edi
    seto %al
    ret
func2a:
    cmpl $-2147483521, %edi
    setl %al
    ret
func2b:
    addl $-127, %edi
    seto %al
    ret
func3a:
    cmpl $-2147483648, %edi
    sete %al
    ret
func3b:
    addl $-1, %edi
    seto %al
    ret
func3c:
    negl %edi
    seto %al
    ret
```

I would like to thank to this report for pointing out such optimization
opportunity: https://github.com/llvm/llvm-project/issues/159578

Reply via email to