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

Reply via email to