[llvm] ed80761 - [DAG] Split BuildVectorSDNode::getConstantRawBits into BuildVectorSDNode::recastRawBits helper. NFC.

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 10 05:08:53 PST 2021


Author: Simon Pilgrim
Date: 2021-11-10T13:06:19Z
New Revision: ed80761b507b65fd12b6e6d30d479c8e56747b8d

URL: https://github.com/llvm/llvm-project/commit/ed80761b507b65fd12b6e6d30d479c8e56747b8d
DIFF: https://github.com/llvm/llvm-project/commit/ed80761b507b65fd12b6e6d30d479c8e56747b8d.diff

LOG: [DAG] Split BuildVectorSDNode::getConstantRawBits into BuildVectorSDNode::recastRawBits helper. NFC.

NFC refactor of D113351, pulling out the APInt split/merge code from the BuildVectorSDNode bits extraction into a BuildVectorSDNode::recastRawBits helper. This is to allow us to reuse the code when we're packing constant folded APInt data back together.

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/SelectionDAGNodes.h
    llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index c2c5dbc264785..115ea9cfedf14 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -2059,6 +2059,15 @@ class BuildVectorSDNode : public SDNode {
 
   bool isConstant() const;
 
+  /// Recast bit data \p SrcBitElements to \p DstEltSizeInBits wide elements.
+  /// Undef elements are treated as zero, and entirely undefined elements are
+  /// flagged in \p DstUndefElements.
+  static void recastRawBits(bool IsLittleEndian, unsigned DstEltSizeInBits,
+                            SmallVectorImpl<APInt> &DstBitElements,
+                            ArrayRef<APInt> SrcBitElements,
+                            BitVector &DstUndefElements,
+                            const BitVector &SrcUndefElements);
+
   static bool classof(const SDNode *N) {
     return N->getOpcode() == ISD::BUILD_VECTOR;
   }

diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 0d5513d9e39ef..0fa9abf612974 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -10830,59 +10830,83 @@ bool BuildVectorSDNode::getConstantRawBits(
   assert(((NumSrcOps * SrcEltSizeInBits) % DstEltSizeInBits) == 0 &&
          "Invalid bitcast scale");
 
+  // Extract raw src bits.
+  SmallVector<APInt> SrcBitElements(NumSrcOps,
+                                    APInt::getNullValue(SrcEltSizeInBits));
+  BitVector SrcUndeElements(NumSrcOps, false);
+
+  for (unsigned I = 0; I != NumSrcOps; ++I) {
+    SDValue Op = getOperand(I);
+    if (Op.isUndef()) {
+      SrcUndeElements.set(I);
+      continue;
+    }
+    auto *CInt = dyn_cast<ConstantSDNode>(Op);
+    auto *CFP = dyn_cast<ConstantFPSDNode>(Op);
+    assert((CInt || CFP) && "Unknown constant");
+    SrcBitElements[I] =
+        CInt ? CInt->getAPIntValue().truncOrSelf(SrcEltSizeInBits)
+             : CFP->getValueAPF().bitcastToAPInt();
+  }
+
+  // Recast to dst width.
+  recastRawBits(IsLittleEndian, DstEltSizeInBits, RawBitElements,
+                SrcBitElements, UndefElements, SrcUndeElements);
+  return true;
+}
+
+void BuildVectorSDNode::recastRawBits(bool IsLittleEndian,
+                                      unsigned DstEltSizeInBits,
+                                      SmallVectorImpl<APInt> &DstBitElements,
+                                      ArrayRef<APInt> SrcBitElements,
+                                      BitVector &DstUndefElements,
+                                      const BitVector &SrcUndefElements) {
+  unsigned NumSrcOps = SrcBitElements.size();
+  unsigned SrcEltSizeInBits = SrcBitElements[0].getBitWidth();
+  assert(((NumSrcOps * SrcEltSizeInBits) % DstEltSizeInBits) == 0 &&
+         "Invalid bitcast scale");
+  assert(NumSrcOps == SrcUndefElements.size() &&
+         "Vector size mismatch");
+
   unsigned NumDstOps = (NumSrcOps * SrcEltSizeInBits) / DstEltSizeInBits;
-  UndefElements.clear();
-  UndefElements.resize(NumDstOps, false);
-  RawBitElements.assign(NumDstOps, APInt::getNullValue(DstEltSizeInBits));
+  DstUndefElements.clear();
+  DstUndefElements.resize(NumDstOps, false);
+  DstBitElements.assign(NumDstOps, APInt::getNullValue(DstEltSizeInBits));
 
   // Concatenate src elements constant bits together into dst element.
   if (SrcEltSizeInBits <= DstEltSizeInBits) {
     unsigned Scale = DstEltSizeInBits / SrcEltSizeInBits;
     for (unsigned I = 0; I != NumDstOps; ++I) {
-      UndefElements.set(I);
-      APInt &RawBits = RawBitElements[I];
+      DstUndefElements.set(I);
+      APInt &DstBits = DstBitElements[I];
       for (unsigned J = 0; J != Scale; ++J) {
         unsigned Idx = (I * Scale) + (IsLittleEndian ? J : (Scale - J - 1));
-        SDValue Op = getOperand(Idx);
-        if (Op.isUndef())
+        if (SrcUndefElements[Idx])
           continue;
-        UndefElements.reset(I);
-        auto *CInt = dyn_cast<ConstantSDNode>(Op);
-        auto *CFP = dyn_cast<ConstantFPSDNode>(Op);
-        assert((CInt || CFP) && "Unknown constant");
-        APInt EltBits =
-            CInt ? CInt->getAPIntValue().truncOrSelf(SrcEltSizeInBits)
-                 : CFP->getValueAPF().bitcastToAPInt();
-        assert(EltBits.getBitWidth() == SrcEltSizeInBits &&
+        DstUndefElements.reset(I);
+        const APInt &SrcBits = SrcBitElements[Idx];
+        assert(SrcBits.getBitWidth() == SrcEltSizeInBits &&
                "Illegal constant bitwidths");
-        RawBits.insertBits(EltBits, J * SrcEltSizeInBits);
+        DstBits.insertBits(SrcBits, J * SrcEltSizeInBits);
       }
     }
-    return true;
+    return;
   }
 
   // Split src element constant bits into dst elements.
   unsigned Scale = SrcEltSizeInBits / DstEltSizeInBits;
   for (unsigned I = 0; I != NumSrcOps; ++I) {
-    SDValue Op = getOperand(I);
-    if (Op.isUndef()) {
-      UndefElements.set(I * Scale, (I + 1) * Scale);
+    if (SrcUndefElements[I]) {
+      DstUndefElements.set(I * Scale, (I + 1) * Scale);
       continue;
     }
-    auto *CInt = dyn_cast<ConstantSDNode>(Op);
-    auto *CFP = dyn_cast<ConstantFPSDNode>(Op);
-    assert((CInt || CFP) && "Unknown constant");
-    APInt EltBits =
-        CInt ? CInt->getAPIntValue() : CFP->getValueAPF().bitcastToAPInt();
-
+    const APInt &SrcBits = SrcBitElements[I];
     for (unsigned J = 0; J != Scale; ++J) {
       unsigned Idx = (I * Scale) + (IsLittleEndian ? J : (Scale - J - 1));
-      APInt &RawBits = RawBitElements[Idx];
-      RawBits = EltBits.extractBits(DstEltSizeInBits, J * DstEltSizeInBits);
+      APInt &DstBits = DstBitElements[Idx];
+      DstBits = SrcBits.extractBits(DstEltSizeInBits, J * DstEltSizeInBits);
     }
   }
-
-  return true;
 }
 
 bool BuildVectorSDNode::isConstant() const {


        


More information about the llvm-commits mailing list