https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66112
Bug ID: 66112 Summary: __builtin_mul_overflow for int16_t emits poor code Product: gcc Version: 5.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: gcc.hall at gmail dot com Target Milestone: --- I am using all the three signed integer overflow builtin's for the four types: int8_t, int16_t, int32_t and int64_t on Intel x64. In all cases except one this produces optimal code, the operation followed by "jo". See the test case below. For the int32_t type, from the last atoi down: call atoi # imull %eax, %ebx # b, tmp100 jo .L3 #, However, for int16_t this produces much larger code that does a 32 bit multiply and checks for overflow by hand: call atoi # movswl %bx, %esi # D.5222, D.5222 cwtl imull %esi, %eax # D.5222, tmp109 movl %eax, %edx # tmp109, tmp110 movl %eax, %ecx # tmp109, tmp111 sarl $16, %edx #, tmp110 sarw $15, %cx #, tmp111 cmpw %dx, %cx # tmp110, tmp111 jne .L7 #, Even though a simple "imulw" followed by "jo" would work. ------------------------------------------------------------------- #include <stdio.h> #include <inttypes.h> int main( int argc, const char *argv[] ) { int16_t result, a = (int16_t)atoi(argv[1]), b = (int16_t)atoi( argv[2] ); if( __builtin_mul_overflow( a, b, &result ) ) printf( "Overflow\n"); else printf( "Product is %d\n", result ); }