Handle BUILD_VECTOR with all zero elements.
authorEvan Cheng <evan.cheng@apple.com>
Fri, 24 Mar 2006 07:29:27 +0000 (07:29 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 24 Mar 2006 07:29:27 +0000 (07:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27056 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
lib/Target/X86/X86InstrFPStack.td
lib/Target/X86/X86InstrSSE.td

index 5649d6461e5cba760b1c1396630f7ad06900a0e4..e9178f217a3f321b89464e05eec92a6c9b2dd3b1 100644 (file)
@@ -277,7 +277,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::SUB,              MVT::v4f32, Legal);
     setOperationAction(ISD::MUL,              MVT::v4f32, Legal);
     setOperationAction(ISD::LOAD,             MVT::v4f32, Legal);
-    setOperationAction(ISD::BUILD_VECTOR,     MVT::v4f32, Expand);
+    setOperationAction(ISD::BUILD_VECTOR,     MVT::v4f32, Custom);
     setOperationAction(ISD::VECTOR_SHUFFLE,   MVT::v4f32, Custom);
   }
 
@@ -300,10 +300,11 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::LOAD,             MVT::v8i16, Legal);
     setOperationAction(ISD::LOAD,             MVT::v4i32, Legal);
     setOperationAction(ISD::LOAD,             MVT::v2i64, Legal);
-    setOperationAction(ISD::BUILD_VECTOR,     MVT::v2f64, Expand);
-    setOperationAction(ISD::BUILD_VECTOR,     MVT::v16i8, Expand);
-    setOperationAction(ISD::BUILD_VECTOR,     MVT::v8i16, Expand);
-    setOperationAction(ISD::BUILD_VECTOR,     MVT::v4i32, Expand);
+    setOperationAction(ISD::BUILD_VECTOR,     MVT::v2f64, Custom);
+    setOperationAction(ISD::BUILD_VECTOR,     MVT::v16i8, Custom);
+    setOperationAction(ISD::BUILD_VECTOR,     MVT::v8i16, Custom);
+    setOperationAction(ISD::BUILD_VECTOR,     MVT::v4i32, Custom);
+    setOperationAction(ISD::BUILD_VECTOR,     MVT::v2i64, Custom);
     setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v16i8, Custom);
     setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v8i16, Custom);
     setOperationAction(ISD::VECTOR_SHUFFLE,   MVT::v2f64, Custom);
@@ -1529,6 +1530,23 @@ unsigned X86::getShuffleSHUFImmediate(SDNode *N) {
   return Mask;
 }
 
+/// isZeroVector - Return true if all elements of BUILD_VECTOR are 0 or +0.0.
+bool X86::isZeroVector(SDNode *N) {
+  for (SDNode::op_iterator I = N->op_begin(), E = N->op_end();
+       I != E; ++I) {
+    if (ConstantFPSDNode *FPC = dyn_cast<ConstantFPSDNode>(*I)) {
+      if (!FPC->isExactlyValue(+0.0))
+        return false;
+    } else if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(*I)) {
+      if (!C->isNullValue())
+        return false;
+    } else
+      return false;
+  }
+
+  return true;
+}
+
 /// LowerOperation - Provide custom lowering hooks for some operations.
 ///
 SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
@@ -2348,10 +2366,28 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
       return SDOperand();
     }
 
-    // TODO.
-    assert(0 && "TODO");
+    assert(0 && "Unexpected VECTOR_SHUFFLE to lower");
     abort();
   }
+  case ISD::BUILD_VECTOR: {
+    bool isZero = true;
+    unsigned NumElems = Op.getNumOperands();
+    for (unsigned i = 0; i < NumElems; ++i) {
+      SDOperand V = Op.getOperand(i);
+      if (ConstantFPSDNode *FPC = dyn_cast<ConstantFPSDNode>(V)) {
+        if (!FPC->isExactlyValue(+0.0))
+          isZero = false;
+      } else if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V)) {
+        if (!C->isNullValue())
+          isZero = false;
+      } else
+        isZero = false;
+    }
+
+    if (isZero)
+      return Op;
+    return SDOperand();
+  }
   }
 }
 
index bc4a7461d1d6a7b936b3e2a2e5c4250800fafb3d..854f76da2be3dd6d5669c1e6e9f549208e51fee3 100644 (file)
@@ -208,6 +208,9 @@ namespace llvm {
    /// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP*
    /// instructions.
    unsigned getShuffleSHUFImmediate(SDNode *N);
+
+   /// isZeroVector - Return true if all elements of BUILD_VECTOR are 0 or +0.0.
+   bool isZeroVector(SDNode *N);
  }
 
   //===----------------------------------------------------------------------===//
index 03b615cddb84281a2a2a6f88290817c514a7da0b..3283ed6b4797823cfbdae58d33781a961d0288bb 100644 (file)
@@ -50,10 +50,6 @@ def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem,
 // FPStack pattern fragments
 //===----------------------------------------------------------------------===//
 
-def fp32imm0 : PatLeaf<(f32 fpimm), [{
-  return N->isExactlyValue(+0.0);
-}]>;
-
 def fp64imm0 : PatLeaf<(f64 fpimm), [{
   return N->isExactlyValue(+0.0);
 }]>;
index e2ec85df82f4679b9ff52d05bef6ee16da0a35a9..2011f1e5a8fb3b46ce8a63b7181f9f81bd52605a 100644 (file)
@@ -45,6 +45,14 @@ def loadv8i16    : PatFrag<(ops node:$ptr), (v8i16 (load node:$ptr))>;
 def loadv4i32    : PatFrag<(ops node:$ptr), (v4i32 (load node:$ptr))>;
 def loadv2i64    : PatFrag<(ops node:$ptr), (v2i64 (load node:$ptr))>;
 
+def fp32imm0 : PatLeaf<(f32 fpimm), [{
+  return N->isExactlyValue(+0.0);
+}]>;
+
+def vecimm0 : PatLeaf<(build_vector), [{
+  return X86::isZeroVector(N);
+}]>;
+
 // SHUFFLE_get_shuf_imm xform function: convert vector_shuffle mask to PSHUF*,
 // SHUFP* etc. imm.
 def SHUFFLE_get_shuf_imm : SDNodeXForm<build_vector, [{
@@ -834,6 +842,25 @@ def PADDDrm : PDI<0xFE, MRMSrcMem, (ops VR128:$dst, VR128:$src1, f128mem:$src2),
 // Alias Instructions
 //===----------------------------------------------------------------------===//
 
+// Alias instructions that map zero vector to xorp* for sse.
+// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
+def VZEROv16i8 : I<0xEF, MRMInitReg, (ops VR128:$dst),
+                   "pxor $dst, $dst", [(set VR128:$dst, (v16i8 vecimm0))]>,
+                 Requires<[HasSSE2]>, TB, OpSize;
+def VZEROv8i16 : I<0xEF, MRMInitReg, (ops VR128:$dst),
+                   "pxor $dst, $dst", [(set VR128:$dst, (v8i16 vecimm0))]>,
+                 Requires<[HasSSE2]>, TB, OpSize;
+def VZEROv4i32 : I<0xEF, MRMInitReg, (ops VR128:$dst),
+                   "pxor $dst, $dst", [(set VR128:$dst, (v4i32 vecimm0))]>,
+                 Requires<[HasSSE2]>, TB, OpSize;
+def VZEROv2i64 : I<0xEF, MRMInitReg, (ops VR128:$dst),
+                   "pxor $dst, $dst", [(set VR128:$dst, (v2i64 vecimm0))]>,
+                 Requires<[HasSSE2]>, TB, OpSize;
+def VZEROv4f32 : PSI<0x57, MRMInitReg, (ops VR128:$dst),
+                     "xorps $dst, $dst", [(set VR128:$dst, (v4f32 vecimm0))]>;
+def VZEROv2f64 : PDI<0x57, MRMInitReg, (ops VR128:$dst),
+                     "xorpd $dst, $dst", [(set VR128:$dst, (v2f64 vecimm0))]>;
+
 def FR32ToV4F32 : PSI<0x28, MRMSrcReg, (ops VR128:$dst, FR32:$src),
                       "movaps {$src, $dst|$dst, $src}",
                       [(set VR128:$dst,