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

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
float func(float a)
{
  union { float f; unsigned u; } u;
  u.f = a;
  u.u ^= 0x80000000;
  return u.f;
}

is the example w/o TBAA issue and down to the point WRT refusing negate via
XOR.

        movd    %xmm0, %eax
        addl    $-2147483648, %eax
        movd    %eax, %xmm0
        ret

The core issue (besides transforming XOR to ADD) is that *xorsi_1 does not
have a xmm alternative:

(insn 7 6 11 2 (parallel [
            (set (subreg:SI (reg:SF 84 [ <retval> ]) 0) 
                (xor:SI (subreg:SI (reg:SF 88) 0)
                    (const_int -2147483647 [0xffffffff80000001])))
            (clobber (reg:CC 17 flags))
        ]) "t.c":6:12 529 {*xorsi_1}

and this we are forced to allocate a GPR.  The XOR to ADD is done via
the *lea<mode>_general_4 splitters I think.  Not sure if adding xmm
alternatives really makes sense but STV doesn't consider the above since
there are subregs involved already and it checks for REG_P instead of
REG_OR_SUBREG_P.

It might be a idea to specifically split the subreg case into yet another
insn variant ...

Reply via email to