[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp

Evan Cheng evan.cheng at apple.com
Thu May 17 11:46:09 PDT 2007



Changes in directory llvm/lib/Target/X86:

X86ISelLowering.cpp updated: 1.403 -> 1.404
---
Log message:

Fix a bogus check that prevented folding VECTOR_SHUFFLE to UNDEF; add an optimization to fold VECTOR_SHUFFLE to a zero vector.

---
Diffs of the changes:  (+61 -24)

 X86ISelLowering.cpp |   85 +++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 61 insertions(+), 24 deletions(-)


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.403 llvm/lib/Target/X86/X86ISelLowering.cpp:1.404
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.403	Thu May 17 12:13:13 2007
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Thu May 17 13:45:50 2007
@@ -1630,7 +1630,7 @@
   return ::isSHUFPMask(N->op_begin(), N->getNumOperands());
 }
 
-/// isCommutedSHUFP - Returns true if the shuffle mask is except
+/// isCommutedSHUFP - Returns true if the shuffle mask is exactly
 /// the reverse of what x86 shuffles want. x86 shuffles requires the lower
 /// half elements to come from vector 1 (which would equal the dest.) and
 /// the upper half to come from vector 2.
@@ -2188,7 +2188,7 @@
 /// isUndefShuffle - Returns true if N is a VECTOR_SHUFFLE that can be resolved
 /// to an undef.
 static bool isUndefShuffle(SDNode *N) {
-  if (N->getOpcode() != ISD::BUILD_VECTOR)
+  if (N->getOpcode() != ISD::VECTOR_SHUFFLE)
     return false;
 
   SDOperand V1 = N->getOperand(0);
@@ -2208,6 +2208,61 @@
   return true;
 }
 
+/// isZeroNode - Returns true if Elt is a constant zero or a floating point
+/// constant +0.0.
+static inline bool isZeroNode(SDOperand Elt) {
+  return ((isa<ConstantSDNode>(Elt) &&
+           cast<ConstantSDNode>(Elt)->getValue() == 0) ||
+          (isa<ConstantFPSDNode>(Elt) &&
+           cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0)));
+}
+
+/// isZeroShuffle - Returns true if N is a VECTOR_SHUFFLE that can be resolved
+/// to an zero vector.
+static bool isZeroShuffle(SDNode *N) {
+  if (N->getOpcode() != ISD::VECTOR_SHUFFLE)
+    return false;
+
+  SDOperand V1 = N->getOperand(0);
+  SDOperand V2 = N->getOperand(1);
+  SDOperand Mask = N->getOperand(2);
+  unsigned NumElems = Mask.getNumOperands();
+  for (unsigned i = 0; i != NumElems; ++i) {
+    SDOperand Arg = Mask.getOperand(i);
+    if (Arg.getOpcode() != ISD::UNDEF) {
+      unsigned Idx = cast<ConstantSDNode>(Arg)->getValue();
+      if (Idx < NumElems) {
+        unsigned Opc = V1.Val->getOpcode();
+        if (Opc == ISD::UNDEF)
+          continue;
+        if (Opc != ISD::BUILD_VECTOR ||
+            !isZeroNode(V1.Val->getOperand(Idx)))
+          return false;
+      } else if (Idx >= NumElems) {
+        unsigned Opc = V2.Val->getOpcode();
+        if (Opc == ISD::UNDEF)
+          continue;
+        if (Opc != ISD::BUILD_VECTOR ||
+            !isZeroNode(V2.Val->getOperand(Idx - NumElems)))
+          return false;
+      }
+    }
+  }
+  return true;
+}
+
+/// getZeroVector - Returns a vector of specified type with all zero elements.
+///
+static SDOperand getZeroVector(MVT::ValueType VT, SelectionDAG &DAG) {
+  assert(MVT::isVector(VT) && "Expected a vector type");
+  unsigned NumElems = getVectorNumElements(VT);
+  MVT::ValueType EVT = MVT::getVectorBaseType(VT);
+  bool isFP = MVT::isFloatingPoint(EVT);
+  SDOperand Zero = isFP ? DAG.getConstantFP(0.0, EVT) : DAG.getConstant(0, EVT);
+  SmallVector<SDOperand, 8> ZeroVec(NumElems, Zero);
+  return DAG.getNode(ISD::BUILD_VECTOR, VT, &ZeroVec[0], ZeroVec.size());
+}
+
 /// NormalizeMask - V2 is a splat, modify the mask (if needed) so all elements
 /// that point to V2 points to its first element.
 static SDOperand NormalizeMask(SDOperand Mask, SelectionDAG &DAG) {
@@ -2274,18 +2329,6 @@
   return DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], MaskVec.size());
 }
 
-/// getZeroVector - Returns a vector of specified type with all zero elements.
-///
-static SDOperand getZeroVector(MVT::ValueType VT, SelectionDAG &DAG) {
-  assert(MVT::isVector(VT) && "Expected a vector type");
-  unsigned NumElems = getVectorNumElements(VT);
-  MVT::ValueType EVT = MVT::getVectorBaseType(VT);
-  bool isFP = MVT::isFloatingPoint(EVT);
-  SDOperand Zero = isFP ? DAG.getConstantFP(0.0, EVT) : DAG.getConstant(0, EVT);
-  SmallVector<SDOperand, 8> ZeroVec(NumElems, Zero);
-  return DAG.getNode(ISD::BUILD_VECTOR, VT, &ZeroVec[0], ZeroVec.size());
-}
-
 /// PromoteSplat - Promote a splat of v8i16 or v16i8 to v4i32.
 ///
 static SDOperand PromoteSplat(SDOperand Op, SelectionDAG &DAG) {
@@ -2307,17 +2350,8 @@
   return DAG.getNode(ISD::BIT_CONVERT, VT, Shuffle);
 }
 
-/// isZeroNode - Returns true if Elt is a constant zero or a floating point
-/// constant +0.0.
-static inline bool isZeroNode(SDOperand Elt) {
-  return ((isa<ConstantSDNode>(Elt) &&
-           cast<ConstantSDNode>(Elt)->getValue() == 0) ||
-          (isa<ConstantFPSDNode>(Elt) &&
-           cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0)));
-}
-
 /// getShuffleVectorZeroOrUndef - Return a vector_shuffle of the specified
-/// vector and zero or undef vector.
+/// vector of zero or undef vector.
 static SDOperand getShuffleVectorZeroOrUndef(SDOperand V2, MVT::ValueType VT,
                                              unsigned NumElems, unsigned Idx,
                                              bool isZero, SelectionDAG &DAG) {
@@ -2584,6 +2618,9 @@
   if (isUndefShuffle(Op.Val))
     return DAG.getNode(ISD::UNDEF, VT);
 
+  if (isZeroShuffle(Op.Val))
+    return getZeroVector(VT, DAG);
+
   if (isSplatMask(PermMask.Val)) {
     if (NumElems <= 4) return Op;
     // Promote it to a v4i32 splat.






More information about the llvm-commits mailing list