https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85791
Bug ID: 85791
Summary: multiply overflow (128 bit)
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: nruslan_devel at yahoo dot com
Target Milestone: ---
Just noticed that code is generated differently when using
__builtin_mul_overflow and an explicit check:
1. unsigned long long func(unsigned long long a, unsigned long long b)
{
unsigned long long c;
if (__builtin_mul_overflow(a, b, &c))
return 0;
return c;
}
yields:
func:
.LFB0:
.cfi_startproc
movq %rdi, %rax
mulq %rsi
jo .L7
rep ret
.L7:
xorl %eax, %eax
ret
2. unsigned long long func(unsigned long long a, unsigned long long b)
{
__uint128_t c = (__uint128_t) a * b;
if (c > (unsigned long long) -1LL) {
return 0;
}
return (unsigned long long) c;
}
yields slightly less efficient code:
func:
.LFB0:
.cfi_startproc
movq %rdi, %rax
mulq %rsi
cmpq $0, %rdx
jbe .L2
xorl %eax, %eax
.L2:
rep ret
3. clang/llvm can generate better code (identical) in both cases:
func: # @func
.cfi_startproc
# %bb.0:
xorl %ecx, %ecx
movq %rdi, %rax
mulq %rsi
cmovoq %rcx, %rax
retq