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);") +;; 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 "*andnot3_mask" [(set (match_operand:VI48_AVX512VL 0 "register_operand" "=v") (vec_merge:VI48_AVX512VL