[SDAG] At the suggestion of Hal, switch to an output parameter that
authorChandler Carruth <chandlerc@gmail.com>
Wed, 9 Jul 2014 00:41:34 +0000 (00:41 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Wed, 9 Jul 2014 00:41:34 +0000 (00:41 +0000)
tracks which elements of the build vector are in fact undef.

This should make actually inpsecting them (likely in my next patch)
reasonably pretty. Also makes the output parameter optional as it is
clear now that *most* users are happy with undefs in their splats.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212581 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/CodeGen/SelectionDAG/TargetLowering.cpp

index a49d18bbb95af51d70fd2074b54406522c51fac5..223151105b0de81d0fb442bfd27b15f554ea07a4 100644 (file)
@@ -20,6 +20,7 @@
 #define LLVM_CODEGEN_SELECTIONDAGNODES_H
 
 #include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/STLExtras.h"
@@ -1584,15 +1585,26 @@ public:
                        bool isBigEndian = false) const;
 
   /// \brief Returns the splatted value or a null value if this is not a splat.
-  SDValue getSplatValue(bool &HasUndefElements) const;
+  ///
+  /// If passed a non-null UndefElements bitvector, it will resize it to match
+  /// the vector width and set the bits where elements are undef.
+  SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
 
   /// \brief Returns the splatted constant or null if this is not a constant
   /// splat.
-  ConstantSDNode *getConstantSplatNode(bool &HasUndefElements) const;
+  ///
+  /// If passed a non-null UndefElements bitvector, it will resize it to match
+  /// the vector width and set the bits where elements are undef.
+  ConstantSDNode *
+  getConstantSplatNode(BitVector *UndefElements = nullptr) const;
 
   /// \brief Returns the splatted constant FP or null if this is not a constant
   /// FP splat.
-  ConstantFPSDNode *getConstantFPSplatNode(bool &HasUndefElements) const;
+  ///
+  /// If passed a non-null UndefElements bitvector, it will resize it to match
+  /// the vector width and set the bits where elements are undef.
+  ConstantFPSDNode *
+  getConstantFPSplatNode(BitVector *UndefElements = nullptr) const;
 
   bool isConstant() const;
 
index d58824a92d6f4068f5c11f5053048442ddc012ff..7497feb1e661b12444ada53bb3314323d1a3c2da 100644 (file)
@@ -655,13 +655,13 @@ static ConstantSDNode *isConstOrConstSplat(SDValue N) {
     return CN;
 
   if (BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N)) {
-    bool HasUndefElements;
-    ConstantSDNode *CN = BV->getConstantSplatNode(HasUndefElements);
+    BitVector UndefElements;
+    ConstantSDNode *CN = BV->getConstantSplatNode(&UndefElements);
 
     // BuildVectors can truncate their operands. Ignore that case here.
     // FIXME: We blindly ignore splats which include undef which is overly
     // pessimistic.
-    if (CN && !HasUndefElements &&
+    if (CN && UndefElements.none() &&
         CN->getValueType(0) == N.getValueType().getScalarType())
       return CN;
   }
index 15baf14f2d90c8b15596f378d00576009eb82a3e..c2cb0d8d7799522495f3fba49a652393431339d4 100644 (file)
@@ -1521,15 +1521,15 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, SDLoc dl, SDValue N1,
 
     // A splat should always show up as a build vector node.
     if (auto *BV = dyn_cast<BuildVectorSDNode>(V)) {
-      bool SplatHasUndefs;
-      SDValue Splat = BV->getSplatValue(SplatHasUndefs);
+      BitVector UndefElements;
+      SDValue Splat = BV->getSplatValue(&UndefElements);
       // If this is a splat of an undef, shuffling it is also undef.
       if (Splat && Splat.getOpcode() == ISD::UNDEF)
         return getUNDEF(VT);
 
       // We only have a splat which can skip shuffles if there is a splatted
       // value and no undef lanes rearranged by the shuffle.
-      if (Splat && !SplatHasUndefs) {
+      if (Splat && UndefElements.none()) {
         // Splat of <x, x, ..., x>, return <x, x, ..., x>, provided that the
         // number of elements match or the value splatted is a zero constant.
         if (V.getValueType().getVectorNumElements() ==
@@ -6635,17 +6635,22 @@ bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue,
   return true;
 }
 
-SDValue BuildVectorSDNode::getSplatValue(bool &HasUndefElements) const {
-  HasUndefElements = false;
+SDValue BuildVectorSDNode::getSplatValue(BitVector *UndefElements) const {
+  if (UndefElements) {
+    UndefElements->clear();
+    UndefElements->resize(getNumOperands());
+  }
   SDValue Splatted;
   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
     SDValue Op = getOperand(i);
-    if (Op.getOpcode() == ISD::UNDEF)
-      HasUndefElements = true;
-    else if (!Splatted)
+    if (Op.getOpcode() == ISD::UNDEF) {
+      if (UndefElements)
+        (*UndefElements)[i] = true;
+    } else if (!Splatted) {
       Splatted = Op;
-    else if (Splatted != Op)
+    } else if (Splatted != Op) {
       return SDValue();
+    }
   }
 
   if (!Splatted) {
@@ -6658,15 +6663,15 @@ SDValue BuildVectorSDNode::getSplatValue(bool &HasUndefElements) const {
 }
 
 ConstantSDNode *
-BuildVectorSDNode::getConstantSplatNode(bool &HasUndefElements) const {
+BuildVectorSDNode::getConstantSplatNode(BitVector *UndefElements) const {
   return dyn_cast_or_null<ConstantSDNode>(
-      getSplatValue(HasUndefElements).getNode());
+      getSplatValue(UndefElements).getNode());
 }
 
 ConstantFPSDNode *
-BuildVectorSDNode::getConstantFPSplatNode(bool &HasUndefElements) const {
+BuildVectorSDNode::getConstantFPSplatNode(BitVector *UndefElements) const {
   return dyn_cast_or_null<ConstantFPSDNode>(
-      getSplatValue(HasUndefElements).getNode());
+      getSplatValue(UndefElements).getNode());
 }
 
 bool BuildVectorSDNode::isConstant() const {
index 9aee3894b649ad25266fc6a978abf51abf44ba2e..578821a19f5cc06fde7274d3d5c5c4e38e33058c 100644 (file)
@@ -1158,11 +1158,11 @@ bool TargetLowering::isConstTrueVal(const SDNode *N) const {
       return false;
 
     IsVec = true;
-    bool HasUndefElements;
-    CN = BV->getConstantSplatNode(HasUndefElements);
+    BitVector UndefElements;
+    CN = BV->getConstantSplatNode(&UndefElements);
     // Only interested in constant splats, and we don't try to handle undef
     // elements in identifying boolean constants.
-    if (!CN || HasUndefElements)
+    if (!CN || UndefElements.none())
       return false;
   }
 
@@ -1190,11 +1190,11 @@ bool TargetLowering::isConstFalseVal(const SDNode *N) const {
       return false;
 
     IsVec = true;
-    bool HasUndefElements;
-    CN = BV->getConstantSplatNode(HasUndefElements);
+    BitVector UndefElements;
+    CN = BV->getConstantSplatNode(&UndefElements);
     // Only interested in constant splats, and we don't try to handle undef
     // elements in identifying boolean constants.
-    if (!CN || HasUndefElements)
+    if (!CN || UndefElements.none())
       return false;
   }