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
```