Custom lower PCMPEQ/PCMPGT intrinsics to target specific nodes and remove the intrins...
[oota-llvm.git] / lib / Target / X86 / X86ISelLowering.cpp
index eccb5468f95c18dd57f5c388e77f0a35325cb2db..2655ce961041520c693ac48ddd26c5b5fad07a0a 100644 (file)
@@ -9318,6 +9318,26 @@ X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const
   case Intrinsic::x86_avx2_psrav_d_256:
     return DAG.getNode(ISD::SRA, dl, Op.getValueType(),
                       Op.getOperand(1), Op.getOperand(2));
+  case Intrinsic::x86_sse2_pcmpeq_b:
+  case Intrinsic::x86_sse2_pcmpeq_w:
+  case Intrinsic::x86_sse2_pcmpeq_d:
+  case Intrinsic::x86_sse41_pcmpeqq:
+  case Intrinsic::x86_avx2_pcmpeq_b:
+  case Intrinsic::x86_avx2_pcmpeq_w:
+  case Intrinsic::x86_avx2_pcmpeq_d:
+  case Intrinsic::x86_avx2_pcmpeq_q:
+    return DAG.getNode(X86ISD::PCMPEQ, dl, Op.getValueType(),
+                       Op.getOperand(1), Op.getOperand(2));
+  case Intrinsic::x86_sse2_pcmpgt_b:
+  case Intrinsic::x86_sse2_pcmpgt_w:
+  case Intrinsic::x86_sse2_pcmpgt_d:
+  case Intrinsic::x86_sse42_pcmpgtq:
+  case Intrinsic::x86_avx2_pcmpgt_b:
+  case Intrinsic::x86_avx2_pcmpgt_w:
+  case Intrinsic::x86_avx2_pcmpgt_d:
+  case Intrinsic::x86_avx2_pcmpgt_q:
+    return DAG.getNode(X86ISD::PCMPGT, dl, Op.getValueType(),
+                       Op.getOperand(1), Op.getOperand(2));
 
   // ptest and testp intrinsics. The intrinsic these come from are designed to
   // return an integer value, not just an instruction so lower it to the ptest
@@ -9934,12 +9954,10 @@ SDValue X86TargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) const {
     //  AhiBlo = __builtin_ia32_psllqi256( AhiBlo, 32 );
     //  return AloBlo + AloBhi + AhiBlo;
 
-    SDValue Ahi = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
-                         DAG.getConstant(Intrinsic::x86_avx2_psrli_q, MVT::i32),
-                         A, DAG.getConstant(32, MVT::i32));
-    SDValue Bhi = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
-                         DAG.getConstant(Intrinsic::x86_avx2_psrli_q, MVT::i32),
-                         B, DAG.getConstant(32, MVT::i32));
+    SDValue Ahi = DAG.getNode(X86ISD::VSRLI, dl, VT, A,
+                              DAG.getConstant(32, MVT::i32));
+    SDValue Bhi = DAG.getNode(X86ISD::VSRLI, dl, VT, B,
+                              DAG.getConstant(32, MVT::i32));
     SDValue AloBlo = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
                          DAG.getConstant(Intrinsic::x86_avx2_pmulu_dq, MVT::i32),
                          A, B);
@@ -9949,12 +9967,10 @@ SDValue X86TargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) const {
     SDValue AhiBlo = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
                          DAG.getConstant(Intrinsic::x86_avx2_pmulu_dq, MVT::i32),
                          Ahi, B);
-    AloBhi = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
-                         DAG.getConstant(Intrinsic::x86_avx2_pslli_q, MVT::i32),
-                         AloBhi, DAG.getConstant(32, MVT::i32));
-    AhiBlo = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
-                         DAG.getConstant(Intrinsic::x86_avx2_pslli_q, MVT::i32),
-                         AhiBlo, DAG.getConstant(32, MVT::i32));
+    AloBhi = DAG.getNode(X86ISD::VSHLI, dl, VT, AloBhi,
+                         DAG.getConstant(32, MVT::i32));
+    AhiBlo = DAG.getNode(X86ISD::VSHLI, dl, VT, AhiBlo,
+                         DAG.getConstant(32, MVT::i32));
     SDValue Res = DAG.getNode(ISD::ADD, dl, VT, AloBlo, AloBhi);
     Res = DAG.getNode(ISD::ADD, dl, VT, Res, AhiBlo);
     return Res;
@@ -9972,12 +9988,10 @@ SDValue X86TargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) const {
   //  AhiBlo = __builtin_ia32_psllqi128( AhiBlo, 32 );
   //  return AloBlo + AloBhi + AhiBlo;
 
-  SDValue Ahi = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
-                       DAG.getConstant(Intrinsic::x86_sse2_psrli_q, MVT::i32),
-                       A, DAG.getConstant(32, MVT::i32));
-  SDValue Bhi = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
-                       DAG.getConstant(Intrinsic::x86_sse2_psrli_q, MVT::i32),
-                       B, DAG.getConstant(32, MVT::i32));
+  SDValue Ahi = DAG.getNode(X86ISD::VSRLI, dl, VT, A,
+                            DAG.getConstant(32, MVT::i32));
+  SDValue Bhi = DAG.getNode(X86ISD::VSRLI, dl, VT, B,
+                            DAG.getConstant(32, MVT::i32));
   SDValue AloBlo = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
                        DAG.getConstant(Intrinsic::x86_sse2_pmulu_dq, MVT::i32),
                        A, B);
@@ -9987,12 +10001,10 @@ SDValue X86TargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) const {
   SDValue AhiBlo = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
                        DAG.getConstant(Intrinsic::x86_sse2_pmulu_dq, MVT::i32),
                        Ahi, B);
-  AloBhi = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
-                       DAG.getConstant(Intrinsic::x86_sse2_pslli_q, MVT::i32),
-                       AloBhi, DAG.getConstant(32, MVT::i32));
-  AhiBlo = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT,
-                       DAG.getConstant(Intrinsic::x86_sse2_pslli_q, MVT::i32),
-                       AhiBlo, DAG.getConstant(32, MVT::i32));
+  AloBhi = DAG.getNode(X86ISD::VSHLI, dl, VT, AloBhi,
+                       DAG.getConstant(32, MVT::i32));
+  AhiBlo = DAG.getNode(X86ISD::VSHLI, dl, VT, AhiBlo,
+                       DAG.getConstant(32, MVT::i32));
   SDValue Res = DAG.getNode(ISD::ADD, dl, VT, AloBlo, AloBhi);
   Res = DAG.getNode(ISD::ADD, dl, VT, Res, AhiBlo);
   return Res;
@@ -13688,26 +13700,11 @@ static SDValue PerformOrCombine(SDNode *N, SelectionDAG &DAG,
       // Validate that the Mask operand is a vector sra node.
       // FIXME: what to do for bytes, since there is a psignb/pblendvb, but
       // there is no psrai.b
-      SDValue SraSrc, SraC;
-      if (Mask.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
-        switch (cast<ConstantSDNode>(Mask.getOperand(0))->getZExtValue()) {
-        case Intrinsic::x86_sse2_psrai_w:
-        case Intrinsic::x86_sse2_psrai_d:
-        case Intrinsic::x86_avx2_psrai_w:
-        case Intrinsic::x86_avx2_psrai_d:
-          break;
-        default: return SDValue();
-        }
-
-        SraSrc = Mask.getOperand(1);
-        SraC = Mask.getOperand(2);
-      } else if (Mask.getOpcode() == X86ISD::VSRAI) {
-        SraSrc = Mask.getOperand(0);
-        SraC = Mask.getOperand(1);
-      } else
+      if (Mask.getOpcode() != X86ISD::VSRAI)
         return SDValue();
 
       // Check that the SRA is all signbits.
+      SDValue SraC = Mask.getOperand(1);
       unsigned SraAmt  = cast<ConstantSDNode>(SraC)->getZExtValue();
       unsigned EltBits = MaskVT.getVectorElementType().getSizeInBits();
       if ((SraAmt + 1) != EltBits)
@@ -13725,7 +13722,7 @@ static SDValue PerformOrCombine(SDNode *N, SelectionDAG &DAG,
           X.getValueType() == MaskVT && Y.getValueType() == MaskVT) {
         assert((EltBits == 8 || EltBits == 16 || EltBits == 32) &&
                "Unsupported VT for PSIGN");
-        Mask = DAG.getNode(X86ISD::PSIGN, DL, MaskVT, X, SraSrc);
+        Mask = DAG.getNode(X86ISD::PSIGN, DL, MaskVT, X, Mask.getOperand(0));
         return DAG.getNode(ISD::BITCAST, DL, VT, Mask);
       }
       // PBLENDVB only available on SSE 4.1