@@ -16887,6 +16887,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