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

            Bug ID: 90878
           Summary: [8/9/10 Regression] integer -> SSE register move isn't
                    generated
           Product: gcc
           Version: 8.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hjl.tools at gmail dot com
                CC: skpgkp1 at gmail dot com, ubizjak at gmail dot com
  Target Milestone: ---

[hjl@gnu-cfl-1 sse-move]$ cat x.i
union ieee754_float
  {
    float f;

    struct
      {
        unsigned int mantissa:23;
        unsigned int exponent:8;
        unsigned int negative:1;
      } ieee;
};

double
foo (float f)
{
  union ieee754_float u;
  u.f = f;
  u.ieee.negative = 0;
  return u.f;
}
[hjl@gnu-cfl-1 sse-move]$ /usr/gcc-9.1.1-x32-tuning/bin/gcc -S -O2
-march=skylake x.i
[hjl@gnu-cfl-1 sse-move]$ cat x.s
        .file   "x.i"
        .text
        .p2align 4
        .globl  foo
        .type   foo, @function
foo:
.LFB0:
        .cfi_startproc
        vmovd   %xmm0, %eax
        andl    $2147483647, %eax
        movl    %eax, -4(%rsp)
        vcvtss2sd       -4(%rsp), %xmm0, %xmm0
        ret
        .cfi_endproc
.LFE0:
        .size   foo, .-foo
        .ident  "GCC: (GNU) 9.1.1 20190517"
        .section        .note.GNU-stack,"",@progbits
[hjl@gnu-cfl-1 sse-move]$ 

Skylake cost has

 2, 2,                                 /* SSE->integer and integer->SSE moves
*/

which are the same cost as the normal register move.  But integer->SSE
isn't used since ix86_register_move_cost has

  /* Moves between SSE/MMX and integer unit are expensive.  */
  if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
      || SSE_CLASS_P (class1) != SSE_CLASS_P (class2))

    /* ??? By keeping returned value relatively high, we limit the number
       of moves between integer and MMX/SSE registers for all targets.
       Additionally, high value prevents problem with x86_modes_tieable_p(),
       where integer modes in MMX/SSE registers are not tieable
       because of missing QImode and HImode moves to, from or between
       MMX/SSE registers.  */
    return MAX (8, MMX_CLASS_P (class1) || MMX_CLASS_P (class2)
                ? ix86_cost->mmxsse_to_integer : ix86_cost->ssemmx_to_integer);

integer->SSE is always 8 which much more expensive than integer
register store whose cost is 3.

Reply via email to