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.