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:
parent
bb0c10ffc6
commit
1de31bcad8
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user