1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[X86] Add matching support for X86ISD::ANDNP to X86DAGToDAGISel::tryVPTERNLOG.

This commit is contained in:
Craig Topper 2020-07-03 17:50:35 -07:00
parent bb0c10ffc6
commit 1de31bcad8
3 changed files with 79 additions and 11 deletions

View File

@ -3933,7 +3933,6 @@ bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *N) {
// Try to match two logic ops to a VPTERNLOG.
// FIXME: Handle inverted inputs?
// FIXME: Handle more complex patterns that use an operand more than once?
// FIXME: Support X86ISD::ANDNP
bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *N) {
MVT NVT = N->getSimpleValueType(0);
@ -3951,7 +3950,8 @@ bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *N) {
SDValue N1 = N->getOperand(1);
auto isLogicOp = [](unsigned Opc) {
return Opc == ISD::AND || Opc == ISD::OR || Opc == ISD::XOR;
return Opc == ISD::AND || Opc == ISD::OR || Opc == ISD::XOR ||
Opc == X86ISD::ANDNP;
};
SDValue A, B, C;
@ -3975,25 +3975,28 @@ bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *N) {
case ISD::AND:
switch (Opc2) {
default: llvm_unreachable("Unexpected opcode!");
case ISD::AND: Imm = 0x80; break;
case ISD::OR: Imm = 0xe0; break;
case ISD::XOR: Imm = 0x60; break;
case ISD::AND: Imm = 0x80; break;
case ISD::OR: Imm = 0xe0; break;
case ISD::XOR: Imm = 0x60; break;
case X86ISD::ANDNP: Imm = 0x20; break;
}
break;
case ISD::OR:
switch (Opc2) {
default: llvm_unreachable("Unexpected opcode!");
case ISD::AND: Imm = 0xf8; break;
case ISD::OR: Imm = 0xfe; break;
case ISD::XOR: Imm = 0xf6; break;
case ISD::AND: Imm = 0xf8; break;
case ISD::OR: Imm = 0xfe; break;
case ISD::XOR: Imm = 0xf6; break;
case X86ISD::ANDNP: Imm = 0xf2; break;
}
break;
case ISD::XOR:
switch (Opc2) {
default: llvm_unreachable("Unexpected opcode!");
case ISD::AND: Imm = 0x78; break;
case ISD::OR: Imm = 0x1e; break;
case ISD::XOR: Imm = 0x96; break;
case ISD::AND: Imm = 0x78; break;
case ISD::OR: Imm = 0x1e; break;
case ISD::XOR: Imm = 0x96; break;
case X86ISD::ANDNP: Imm = 0xd2; break;
}
break;
}

View File

@ -853,3 +853,35 @@ entry:
ret <16 x float> %4
}
define <16 x i32> @ternlog_and_andn(<16 x i32> %x, <16 x i32> %y, <16 x i32> %z) {
; ALL-LABEL: ternlog_and_andn:
; ALL: ## %bb.0:
; ALL-NEXT: vpternlogd $8, %zmm1, %zmm2, %zmm0
; ALL-NEXT: retq
%a = xor <16 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
%b = and <16 x i32> %y, %a
%c = and <16 x i32> %b, %z
ret <16 x i32> %c
}
define <16 x i32> @ternlog_or_andn(<16 x i32> %x, <16 x i32> %y, <16 x i32> %z) {
; ALL-LABEL: ternlog_or_andn:
; ALL: ## %bb.0:
; ALL-NEXT: vpternlogd $206, %zmm1, %zmm2, %zmm0
; ALL-NEXT: retq
%a = xor <16 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
%b = and <16 x i32> %y, %a
%c = or <16 x i32> %b, %z
ret <16 x i32> %c
}
define <16 x i32> @ternlog_xor_andn(<16 x i32> %x, <16 x i32> %y, <16 x i32> %z) {
; ALL-LABEL: ternlog_xor_andn:
; ALL: ## %bb.0:
; ALL-NEXT: vpternlogd $198, %zmm1, %zmm2, %zmm0
; ALL-NEXT: retq
%a = xor <16 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
%b = and <16 x i32> %y, %a
%c = xor <16 x i32> %b, %z
ret <16 x i32> %c
}

View File

@ -954,3 +954,36 @@ entry:
%4 = select <4 x i1> %extract.i, <4 x float> %2, <4 x float> zeroinitializer
ret <4 x float> %4
}
define <4 x i32> @ternlog_and_andn(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z) {
; CHECK-LABEL: ternlog_and_andn:
; CHECK: ## %bb.0:
; CHECK-NEXT: vpternlogd $8, %xmm1, %xmm2, %xmm0
; CHECK-NEXT: retq
%a = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
%b = and <4 x i32> %y, %a
%c = and <4 x i32> %b, %z
ret <4 x i32> %c
}
define <4 x i32> @ternlog_or_andn(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z) {
; CHECK-LABEL: ternlog_or_andn:
; CHECK: ## %bb.0:
; CHECK-NEXT: vpternlogd $206, %xmm1, %xmm2, %xmm0
; CHECK-NEXT: retq
%a = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
%b = and <4 x i32> %y, %a
%c = or <4 x i32> %b, %z
ret <4 x i32> %c
}
define <4 x i32> @ternlog_xor_andn(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z) {
; CHECK-LABEL: ternlog_xor_andn:
; CHECK: ## %bb.0:
; CHECK-NEXT: vpternlogd $198, %xmm1, %xmm2, %xmm0
; CHECK-NEXT: retq
%a = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
%b = and <4 x i32> %y, %a
%c = xor <4 x i32> %b, %z
ret <4 x i32> %c
}