This is a ping of a patch from April (a dependency of another stage1 patch):
https://gcc.gnu.org/pipermail/gcc-patches/2022-April/593123.html

This patch has been refreshed/retested against gcc 13 trunk on
x86_64-pc-linux-gnu with make bootstrap and make -k check,
both with and without --target_board=unix{-m32}, with no new failures.
Ok for mainline?

2022-05-23  Roger Sayle  <ro...@nextmovesoftware.com>

gcc/ChangeLog
        * config/i386/sse.md (peephole2): Convert suitable pand followed
        by pxor into pandn, i.e. (X&Y)^X into X & ~Y.

Many thanks in advance,
Roger
--

diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 191371b..4203fe0 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -17021,6 +17021,44 @@
                        (match_dup 2)))]
   "operands[3] = gen_reg_rtx (<MODE>mode);")
 
+;; Combine pand;pxor into pandn.  (X&Y)^X -> X & ~Y.
+(define_peephole2
+  [(set (match_operand:VMOVE 0 "register_operand")
+       (and:VMOVE (match_operand:VMOVE 1 "register_operand")
+                  (match_operand:VMOVE 2 "register_operand")))
+   (set (match_operand:VMOVE 3 "register_operand")
+       (xor:VMOVE (match_operand:VMOVE 4 "register_operand")
+                  (match_operand:VMOVE 5 "register_operand")))]
+  "TARGET_SSE
+   && REGNO (operands[1]) != REGNO (operands[2])
+   && REGNO (operands[4]) != REGNO (operands[5])
+   && (REGNO (operands[0]) == REGNO (operands[3])
+       || peep2_reg_dead_p (2, operands[0]))"
+  [(set (match_dup 3)
+       (and:VMOVE (not:VMOVE (match_dup 6)) (match_dup 7)))]
+{
+  if (REGNO (operands[0]) != REGNO (operands[1])
+      && ((REGNO (operands[4]) == REGNO (operands[0])
+          && REGNO (operands[5]) == REGNO (operands[1]))
+         || (REGNO (operands[4]) == REGNO (operands[1])
+             && REGNO (operands[5]) == REGNO (operands[0]))))
+    {
+      operands[6] = operands[2];
+      operands[7] = operands[1];
+    }
+  else if (REGNO (operands[0]) != REGNO (operands[2])
+          && ((REGNO (operands[4]) == REGNO (operands[0])
+               && REGNO (operands[5]) == REGNO (operands[2]))
+              || (REGNO (operands[4]) == REGNO (operands[2])
+                  && REGNO (operands[5]) == REGNO (operands[0]))))
+    {
+      operands[6] = operands[1];
+      operands[7] = operands[2];
+    }
+  else
+    FAIL;
+})
+
 (define_insn "*andnot<mode>3_mask"
   [(set (match_operand:VI48_AVX512VL 0 "register_operand" "=v")
        (vec_merge:VI48_AVX512VL

Reply via email to