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

            Bug ID: 117529
           Summary: Missed optimization: (y != 0 && x > (unsigned)(-1) /
                    y) (multiplication overflow check)
           Product: gcc
           Version: 14.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Explorer09 at gmail dot com
  Target Milestone: ---

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

bool func1(unsigned long long x, unsigned long long y)
{
    return x > (ULLONG_MAX / y);
}

bool func2(unsigned long long x, unsigned long long y)
{
    return y != 0 && x > (ULLONG_MAX / y);
}

bool func3(unsigned long long x, unsigned long long y)
{
    unsigned long long res;
    return __builtin_umulll_overflow(x, y, &res);
}
```

Expected result: All three functions produce the same code.

Actual result: func1() and func3() optimize to same code, but func2() had a
redundant (y != 0) check that is not optimized out.

x86-64 gcc with "-Os" option (tested in Compiler Explorer, a.k.a. godbolt.org)

```x86asm
func1:
        movq    %rdi, %rax
        mulq    %rsi
        seto    %al
        ret
func2:
        xorl    %eax, %eax
        testq   %rsi, %rsi
        je      .L5
        movq    %rsi, %rax
        mulq    %rdi
        seto    %al
        movzbl  %al, %eax
.L5:
        andl    $1, %eax
        ret
```

Reply via email to