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

            Bug ID: 87236
           Summary: Using union to reinterpret from integer to floating
                    point goes via memory
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jsm28 at gcc dot gnu.org
  Target Milestone: ---
            Target: x86_64-*-*

glibc has architecture-independent C code to handle reinterpreting between
integers and floating-point types via unions, and then some x86_64-specific
code in sysdeps/x86_64/fpu/math_private.h to do the same with with movd and
movq asms.

I wanted to see if the asms were obsolete and GCC could do a good enough thing
with the generic code.  For reinterpreting from floating-point to integer, I
got the expected single instruction generated with trivial testcases.  In the
other direction, however, I got code that unexpectedly goes via memory.  Is
there some reason that's better?  If I use the glibc asms I get a single
movq/movd without the intermediate memory use.  (Note: I don't know if these
minimal tests reflect issues that would also appear in more complicated glibc
use using unions for this purpose.)

Testcase:

union ud { double d; unsigned long long int u; };
double insd (unsigned long long int x) { union ud v = { .u = x }; return v.d; }
union uf { float f; unsigned int u; };
float insf (unsigned int x) { union uf v = { .u = x }; return v.f; }

Compiled with -O2:

        .file   "t.c"
        .text
        .p2align 4
        .globl  insd
        .type   insd, @function
insd:
.LFB0:
        .cfi_startproc
        movq    %rdi, -8(%rsp)
        movsd   -8(%rsp), %xmm0
        ret
        .cfi_endproc
.LFE0:
        .size   insd, .-insd
        .p2align 4
        .globl  insf
        .type   insf, @function
insf:
.LFB1:
        .cfi_startproc
        movl    %edi, -4(%rsp)
        movss   -4(%rsp), %xmm0
        ret
        .cfi_endproc
.LFE1:
        .size   insf, .-insf
        .ident  "GCC: (GNU) 9.0.0 20180904 (experimental) [trunk revision
264074]"
        .section        .note.GNU-stack,"",@progbits

Reply via email to