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.