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