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: [email protected]
ReportedBy: [email protected]
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.