https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83710
Bug ID: 83710 Summary: Unsigned with Signed multiplication followed by right shift Product: gcc Version: 6.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: chanpreet.singh at nxp dot com Target Milestone: --- Hello, For a multiplication between signed and unsigned, I expect the 'sign' of the result to be same as 'sign' of the signed number. But in following case it does not happen. Looks like a bug to me! ###################### #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <stdint.h> // sample code int main () { int a = -1; unsigned int b = 5; int c ; c = (a * b)>>1; std::cout << "c=" << c << " (0x" << std::hex << c << ")" << std::endl; return 1; } -------------------------- Output: c=2147483645 (0x7ffffffd) ########################## I am expecting the output to be -3! The assembly code generated has two arithmetic instructions: imull (signed multiply), and shrl (shift right without sign extension) for x86. While I am expecting the shift instructions to be arithmetic shift right (with sign extension). g++ test.cpp -S ------------------------------- <some instructions> call __main movl $-1, -4(%rbp) movl $5, -8(%rbp) movl -4(%rbp), %eax imull -8(%rbp), %eax shrl %eax movl %eax, -12(%rbp) <some instructions> ------------------------------- Same holds true for long int.