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.

Reply via email to