[X86] Add matching support for X86ISD::ANDNP to X86DAGToDAGISel::tryVPTERNLOG.
authorCraig Topper <craig.topper@intel.com>
Sat, 4 Jul 2020 00:50:35 +0000 (17:50 -0700)
committerCraig Topper <craig.topper@intel.com>
Sat, 4 Jul 2020 00:50:35 +0000 (17:50 -0700)
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
llvm/test/CodeGen/X86/avx512-logic.ll
llvm/test/CodeGen/X86/avx512vl-logic.ll

index 409da74..5a57ca7 100644 (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;
   }
index c7aa636..c2a4da1 100644 (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
+}
index 52b135c..0647f4e 100644 (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
+}