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

            Bug ID: 92905
           Summary: [10 Regression] Spills float-int union to memory
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Keywords: missed-optimization, ra
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: amonakov at gcc dot gnu.org
  Target Milestone: ---

gcc-10 branch regressed for code that needs bitwise operations on floats:

float f(float x)
{
    union {float f; unsigned i;} u = {x};
    u.i |= 0x80000000;
    return u.f;
}

float my_copysign(float x, float y)
{
    union {float f; unsigned i;} ux = {x}, uy ={y};
    ux.i &= 0x7fffffff;
    ux.i |= 0x80000000 & uy.i;
    return ux.f;
}


For function 'f' gcc-10 -O2 -mtune=intel generates
f:
        movd    %xmm0, -4(%rsp)
        movl    $-2147483648, %eax
        orl     -4(%rsp), %eax
        movd    %eax, %xmm0
        ret

while gcc-9 and earlier generate code without stack use, even without
-mtune=intel:
f:
        movd    %xmm0, %eax
        orl     $-2147483648, %eax
        movd    %eax, %xmm0
        ret

Likewise for the more realistic my_copysign, where ux is spilled, but uy is
not.

Eventually it would be nicer to use SSE bitwise operations for this, for
example LLVM already generates
f:
        orps    .LCPI0_0(%rip), %xmm0

Reply via email to