https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83210
Bug ID: 83210 Summary: __builtin_mul_overflow() generates suboptimal code when exactly one argument is the constant 2 Product: gcc Version: 7.2.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: lh_mouse at 126 dot com Target Milestone: --- This snippet illustrates the problem: <https://godbolt.org/g/TssrYv> ``` bool mul_and_check(unsigned *dst, unsigned src){ return __builtin_mul_overflow(src, 2, dst); } ``` With `g++ -O3`, this compiles to: ``` mul_and_check(unsigned int*, unsigned int): mov eax, esi mov edx, 2 xor ecx, ecx mul edx mov esi, eax jo .L5 .L2: mov eax, ecx mov DWORD PTR [rdi], esi and eax, 1 ret .L5: mov ecx, 1 jmp .L2 ``` This is very suboptimal. GCC could have used a bitwise shift operation instead, as follows: ``` mul_and_check(unsigned int*, unsigned int): xor eax, eax # EAX = 0 shl esi, 1 # CF = MSB(src) # src = src * 2; rol eax, 1 # EAX = CF mov dword ptr[rdi], esi # *dst = src ret ```