[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