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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The problem is actually about not catering to op0 == op1.
In that case what we really want is x & 0x80000000 rather than x ^ (x &
0x80000000).
Unfortunately after RA the mask needs to be already emitted, I think e.g.
because of PIC etc. we can't easily use a different constant at that point, and
for non-AVX pandn insn the negation is on the "0" constrained operand.
So
--- gcc/config/i386/i386-expand.c.jj    2021-09-06 14:47:43.184050185 +0200
+++ gcc/config/i386/i386-expand.c       2021-09-07 11:35:30.798849245 +0200
@@ -2289,12 +2289,20 @@ ix86_split_xorsign (rtx operands[])
   mode = GET_MODE (dest);
   vmode = GET_MODE (mask);

-  op1 = lowpart_subreg (vmode, op1, mode);
-  x = gen_rtx_AND (vmode, op1, mask);
-  emit_insn (gen_rtx_SET (op1, x));
+  if (rtx_equal_p (op0, op1))
+    {
+      op0 = lowpart_subreg (vmode, op0, mode);
+      x = gen_rtx_AND (vmode, op0, gen_rtx_NOT (vmode, mask));
+    }
+  else
+    {
+      op1 = lowpart_subreg (vmode, op1, mode);
+      x = gen_rtx_AND (vmode, op1, mask);
+      emit_insn (gen_rtx_SET (op1, x));

-  op0 = lowpart_subreg (vmode, op0, mode);
-  x = gen_rtx_XOR (vmode, op1, op0);
+      op0 = lowpart_subreg (vmode, op0, mode);
+      x = gen_rtx_XOR (vmode, op1, op0);
+    }

   dest = lowpart_subreg (vmode, dest, mode);
   emit_insn (gen_rtx_SET (dest, x));
doesn't work without -mavx.

Reply via email to