https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104674

            Bug ID: 104674
           Summary: i686 sse2: The two results of __divmoddi4 are mixed up
           Product: gcc
           Version: 11.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: xavier.leroy at inria dot fr
  Target Milestone: ---

Created attachment 52505
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52505&action=edit
Repro case

Configuration: GCC 11.2.0 configured for i686-pc-cygwin, as packaged by Cygwin,
running under Cygwin.

When compiled with 

gcc -O2 -mfpmath=sse -msse2

the attached repro case incorrectly prints

888888.08889

The correct result is 888888.00000.

"gcc -O2" and "gcc -O1 -mfpmath=sse -msse2" produce the correct result.

Looking at the assembly code generated by "gcc -O2 -mfpmath=sse -msse2", we see
that the two results of __divmoddi4 (the quotient and the remainder) end up
stored at the same stack location:

        leal    40(%esp), %eax       <-- address where to store the remainder
        movl    68(%esp), %edx
        movl    $10000000, 8(%esp)
        movl    %eax, 16(%esp)
        movl    64(%esp), %eax
        movl    $0, 12(%esp)
        movl    %eax, (%esp)
        movl    %edx, 4(%esp)
        call    ___divmoddi4         <-- quotient is in edx:eax
        movsd   LC1, %xmm2
        movd    %eax, %xmm0
        movd    %edx, %xmm3
        punpckldq       %xmm3, %xmm0 <-- quotient is in xmm0
        movq    %xmm0, 40(%esp)      <-- overwrites the remainder

Regards,

- Xavier Leroy

Reply via email to