http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48580

           Summary: missed optimization: integer overflow checks
           Product: gcc
           Version: 4.6.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: za...@panix.com


To the best of my knowledge, this is the only safe way (without -fwrapv) to
check whether the product of two signed integers overflowed:

bool product_does_not_overflow(signed x, signed y)
{
  unsigned tmp = x * unsigned(y);

  return signed(tmp) > 0 && tmp / x == unsigned(y);
}

(I believe C and C++ are the same in this regard but I could be wrong.  If
there is a better way to write this test I would love to know about it.)

g++ 4.6 produces this assembly dump on x86-64:

_Z25product_does_not_overflowii:
    movl    %esi, %edx
    xorl    %eax, %eax
    imull    %edi, %edx
    testl    %edx, %edx
    jle    .L2
    movl    %edx, %eax
    xorl    %edx, %edx
    divl    %edi
    cmpl    %eax, %esi
    sete    %al
.L2:
    rep
    ret

but, if I understand the semantics of IMUL correctly, it could do this instead:

_Z25product_does_not_overflowii:
    xorl    %eax, %eax
    imull    %edi, %esi
    setno    %al
    ret

which is a pretty substantial micro-win, particularly in getting rid of a
divide.

Reply via email to