https://github.com/matthias-springer updated 
https://github.com/llvm/llvm-project/pull/180397

>From d512398839cef325206020cac743965130069010 Mon Sep 17 00:00:00 2001
From: Matthias Springer <[email protected]>
Date: Sun, 8 Feb 2026 09:07:31 +0000
Subject: [PATCH] [mlir][IR] `DenseElementsAttr`: Remove `i1` dense packing
 special case

---
 .../mlir/Bindings/Python/IRAttributes.h       | 12 ---
 mlir/lib/Bindings/Python/IRAttributes.cpp     | 98 ++-----------------
 mlir/lib/IR/AttributeDetail.h                 | 55 +----------
 mlir/lib/IR/BuiltinAttributes.cpp             | 88 ++---------------
 mlir/test/IR/attribute-roundtrip.mlir         | 10 --
 mlir/test/IR/parse-literal.mlir               |  8 +-
 mlir/test/python/ir/array_attributes.py       |  7 +-
 mlir/unittests/IR/AttributeTest.cpp           | 14 ---
 8 files changed, 23 insertions(+), 269 deletions(-)
 delete mode 100644 mlir/test/IR/attribute-roundtrip.mlir

diff --git a/mlir/include/mlir/Bindings/Python/IRAttributes.h 
b/mlir/include/mlir/Bindings/Python/IRAttributes.h
index d5d5548602114..6c272f226e5a9 100644
--- a/mlir/include/mlir/Bindings/Python/IRAttributes.h
+++ b/mlir/include/mlir/Bindings/Python/IRAttributes.h
@@ -442,18 +442,6 @@ class MLIR_PYTHON_API_EXPORTED PyDenseElementsAttribute
       const std::optional<std::vector<int64_t>> &explicitShape,
       MlirContext &context);
 
-  // There is a complication for boolean numpy arrays, as numpy represents
-  // them as 8 bits (1 byte) per boolean, whereas MLIR bitpacks them into 8
-  // booleans per byte.
-  static MlirAttribute getBitpackedAttributeFromBooleanBuffer(
-      Py_buffer &view, std::optional<std::vector<int64_t>> explicitShape,
-      MlirContext &context);
-
-  // This does the opposite transformation of
-  // `getBitpackedAttributeFromBooleanBuffer`
-  std::unique_ptr<nb_buffer_info>
-  getBooleanBufferFromBitpackedAttribute() const;
-
   template <typename Type>
   std::unique_ptr<nb_buffer_info>
   bufferInfo(MlirType shapedType, const char *explicitFormat = nullptr) {
diff --git a/mlir/lib/Bindings/Python/IRAttributes.cpp 
b/mlir/lib/Bindings/Python/IRAttributes.cpp
index c271497fcc9f8..16e406c244894 100644
--- a/mlir/lib/Bindings/Python/IRAttributes.cpp
+++ b/mlir/lib/Bindings/Python/IRAttributes.cpp
@@ -45,16 +45,12 @@ For conversions outside of these types, a `type=` must be 
explicitly provided
 and the buffer contents must be bit-castable to the MLIR internal
 representation:
 
-  * Integer types (except for i1): the buffer must be byte aligned to the
-    next byte boundary.
+  * Integer types: the buffer must be byte aligned to the next byte boundary.
   * Floating point types: Must be bit-castable to the given floating point
     size.
-  * i1 (bool): Bit packed into 8bit words where the bit pattern matches a
-    row major ordering. An arbitrary Numpy `bool_` array can be bit packed to
-    this specification with: `np.packbits(ary, axis=None, bitorder='little')`.
+  * i1 (bool): Each boolean value is stored as a single byte (0 or 1).
 
-If a single element buffer is passed (or for i1, a single byte with value 0
-or 255), then a splat will be created.
+If a single element buffer is passed, then a splat will be created.
 
 Args:
   array: The array or buffer to convert.
@@ -63,8 +59,7 @@ or 255), then a splat will be created.
   type: Skips inference of the MLIR element type and uses this instead. The
     storage size must be consistent with the actual contents of the buffer.
   shape: Overrides the shape of the buffer when constructing the MLIR
-    shaped type. This is needed when the physical and logical shape differ (as
-    for i1).
+    shaped type. This is needed when the physical and logical shape differ.
   context: Explicit context, if not from context manager.
 
 Returns:
@@ -736,10 +731,7 @@ std::unique_ptr<nb_buffer_info> 
PyDenseElementsAttribute::accessBuffer() {
   } else if (mlirTypeIsAInteger(elementType) &&
              mlirIntegerTypeGetWidth(elementType) == 1) {
     // i1 / bool
-    // We can not send the buffer directly back to Python, because the i1
-    // values are bitpacked within MLIR. We call numpy's unpackbits function
-    // to convert the bytes.
-    return getBooleanBufferFromBitpackedAttribute();
+    return bufferInfo<bool>(shapedType);
   }
 
   // TODO: Currently crashes the program.
@@ -853,9 +845,7 @@ MlirAttribute 
PyDenseElementsAttribute::getAttributeFromBuffer(
       bulkLoadElementType = mlirF16TypeGet(context);
     } else if (format == "?") {
       // i1
-      // The i1 type needs to be bit-packed, so we will handle it separately
-      return getBitpackedAttributeFromBooleanBuffer(view, explicitShape,
-                                                    context);
+      bulkLoadElementType = mlirIntegerTypeGet(context, 1);
     } else if (isSignedIntegerFormat(format)) {
       if (view.itemsize == 4) {
         // i32
@@ -907,82 +897,6 @@ MlirAttribute 
PyDenseElementsAttribute::getAttributeFromBuffer(
   return mlirDenseElementsAttrRawBufferGet(type, view.len, view.buf);
 }
 
-MlirAttribute PyDenseElementsAttribute::getBitpackedAttributeFromBooleanBuffer(
-    Py_buffer &view, std::optional<std::vector<int64_t>> explicitShape,
-    MlirContext &context) {
-  if (llvm::endianness::native != llvm::endianness::little) {
-    // Given we have no good way of testing the behavior on big-endian
-    // systems we will throw
-    throw nb::type_error("Constructing a bit-packed MLIR attribute is "
-                         "unsupported on big-endian systems");
-  }
-  nb::ndarray<uint8_t, nb::numpy, nb::ndim<1>, nb::c_contig> unpackedArray(
-      /*data=*/static_cast<uint8_t *>(view.buf),
-      /*shape=*/{static_cast<size_t>(view.len)});
-
-  nb::module_ numpy = nb::module_::import_("numpy");
-  nb::object packbitsFunc = numpy.attr("packbits");
-  nb::object packedBooleans =
-      packbitsFunc(nb::cast(unpackedArray), "bitorder"_a = "little");
-  nb_buffer_info pythonBuffer = nb::cast<nb_buffer>(packedBooleans).request();
-
-  MlirType bitpackedType = getShapedType(mlirIntegerTypeGet(context, 1),
-                                         std::move(explicitShape), view);
-  assert(pythonBuffer.itemsize == 1 && "Packbits must return uint8");
-  // Notice that `mlirDenseElementsAttrRawBufferGet` copies the memory of
-  // packedBooleans, hence the MlirAttribute will remain valid even when
-  // packedBooleans get reclaimed by the end of the function.
-  return mlirDenseElementsAttrRawBufferGet(bitpackedType, pythonBuffer.size,
-                                           pythonBuffer.ptr);
-}
-
-std::unique_ptr<nb_buffer_info>
-PyDenseElementsAttribute::getBooleanBufferFromBitpackedAttribute() const {
-  if (llvm::endianness::native != llvm::endianness::little) {
-    // Given we have no good way of testing the behavior on big-endian
-    // systems we will throw
-    throw nb::type_error("Constructing a numpy array from a MLIR attribute "
-                         "is unsupported on big-endian systems");
-  }
-
-  int64_t numBooleans = mlirElementsAttrGetNumElements(*this);
-  int64_t numBitpackedBytes = llvm::divideCeil(numBooleans, 8);
-  uint8_t *bitpackedData = static_cast<uint8_t *>(
-      const_cast<void *>(mlirDenseElementsAttrGetRawData(*this)));
-  nb::ndarray<uint8_t, nb::numpy, nb::ndim<1>, nb::c_contig> packedArray(
-      /*data=*/bitpackedData,
-      /*shape=*/{static_cast<size_t>(numBitpackedBytes)});
-
-  nb::module_ numpy = nb::module_::import_("numpy");
-  nb::object unpackbitsFunc = numpy.attr("unpackbits");
-  nb::object equalFunc = numpy.attr("equal");
-  nb::object reshapeFunc = numpy.attr("reshape");
-  nb::object unpackedBooleans =
-      unpackbitsFunc(nb::cast(packedArray), "bitorder"_a = "little");
-
-  // Unpackbits operates on bytes and gives back a flat 0 / 1 integer array.
-  // We need to:
-  //   1. Slice away the padded bits
-  //   2. Make the boolean array have the correct shape
-  //   3. Convert the array to a boolean array
-  unpackedBooleans = unpackedBooleans[nb::slice(
-      nb::int_(0), nb::int_(numBooleans), nb::int_(1))];
-  unpackedBooleans = equalFunc(unpackedBooleans, 1);
-
-  MlirType shapedType = mlirAttributeGetType(*this);
-  intptr_t rank = mlirShapedTypeGetRank(shapedType);
-  std::vector<intptr_t> shape(rank);
-  for (intptr_t i = 0; i < rank; ++i) {
-    shape[i] = mlirShapedTypeGetDimSize(shapedType, i);
-  }
-  unpackedBooleans = reshapeFunc(unpackedBooleans, shape);
-
-  // Make sure the returned nb::buffer_view claims ownership of the data
-  // in `pythonBuffer` so it remains valid when Python reads it
-  nb_buffer pythonBuffer = nb::cast<nb_buffer>(unpackedBooleans);
-  return std::make_unique<nb_buffer_info>(pythonBuffer.request());
-}
-
 PyType_Slot PyDenseElementsAttribute::slots[] = {
 // Python 3.8 doesn't allow setting the buffer protocol slots from a type spec.
 #if PY_VERSION_HEX >= 0x03090000
diff --git a/mlir/lib/IR/AttributeDetail.h b/mlir/lib/IR/AttributeDetail.h
index cb9d21bf3e611..c0d8f7d6e5da4 100644
--- a/mlir/lib/IR/AttributeDetail.h
+++ b/mlir/lib/IR/AttributeDetail.h
@@ -90,10 +90,7 @@ struct DenseIntOrFPElementsAttrStorage : public 
DenseElementsAttributeStorage {
 
     // If the data is already known to be a splat, the key hash value is
     // directly the data buffer.
-    bool isBoolData = ty.getElementType().isInteger(1);
     if (isKnownSplat) {
-      if (isBoolData)
-        return getKeyForSplatBoolData(ty, data[0] != 0);
       return KeyTy(ty, data, llvm::hash_value(data), isKnownSplat);
     }
 
@@ -103,12 +100,8 @@ struct DenseIntOrFPElementsAttrStorage : public 
DenseElementsAttributeStorage {
     size_t numElements = ty.getNumElements();
     assert(numElements != 1 && "splat of 1 element should already be 
detected");
 
-    // Handle boolean values directly as they are packed to 1-bit.
-    if (isBoolData)
-      return getKeyForBoolData(ty, data, numElements);
-
     size_t elementWidth = getDenseElementBitWidth(ty.getElementType());
-    // Non 1-bit dense elements are padded to 8-bits.
+    // Dense elements are padded to 8-bits.
     size_t storageSize = llvm::divideCeil(elementWidth, CHAR_BIT);
     assert(((data.size() / storageSize) == numElements) &&
            "data does not hold expected number of elements");
@@ -127,45 +120,6 @@ struct DenseIntOrFPElementsAttrStorage : public 
DenseElementsAttributeStorage {
     return KeyTy(ty, firstElt, hashVal, /*isSplat=*/true);
   }
 
-  /// Construct a key with a set of boolean data.
-  static KeyTy getKeyForBoolData(ShapedType ty, ArrayRef<char> data,
-                                 size_t numElements) {
-    ArrayRef<char> splatData = data;
-    bool splatValue = splatData.front() & 1;
-
-    // Check the simple case where the data matches the known splat value.
-    if (splatData == ArrayRef<char>(splatValue ? kSplatTrue : kSplatFalse))
-      return getKeyForSplatBoolData(ty, splatValue);
-
-    // Handle the case where the potential splat value is 1 and the number of
-    // elements is non 8-bit aligned.
-    size_t numOddElements = numElements % CHAR_BIT;
-    if (splatValue && numOddElements != 0) {
-      // Check that all bits are set in the last value.
-      char lastElt = splatData.back();
-      if (lastElt != llvm::maskTrailingOnes<unsigned char>(numOddElements))
-        return KeyTy(ty, data, llvm::hash_value(data));
-
-      // If this is the only element, the data is known to be a splat.
-      if (splatData.size() == 1)
-        return getKeyForSplatBoolData(ty, splatValue);
-      splatData = splatData.drop_back();
-    }
-
-    // Check that the data buffer corresponds to a splat of the proper mask.
-    char mask = splatValue ? ~0 : 0;
-    return llvm::all_of(splatData, [mask](char c) { return c == mask; })
-               ? getKeyForSplatBoolData(ty, splatValue)
-               : KeyTy(ty, data, llvm::hash_value(data));
-  }
-
-  /// Return a key to use for a boolean splat of the given value.
-  static KeyTy getKeyForSplatBoolData(ShapedType type, bool splatValue) {
-    const char &splatData = splatValue ? kSplatTrue : kSplatFalse;
-    return KeyTy(type, splatData, llvm::hash_value(splatData),
-                 /*isSplat=*/true);
-  }
-
   /// Hash the key for the storage.
   static llvm::hash_code hashKey(const KeyTy &key) {
     return llvm::hash_combine(key.type, key.hashCode);
@@ -189,13 +143,6 @@ struct DenseIntOrFPElementsAttrStorage : public 
DenseElementsAttributeStorage {
   }
 
   ArrayRef<char> data;
-
-  /// The values used to denote a boolean splat value.
-  // This is not using constexpr declaration due to compilation failure
-  // encountered with MSVC where it would inline these values, which makes it
-  // unsafe to refer by reference in KeyTy.
-  static const char kSplatTrue;
-  static const char kSplatFalse;
 };
 
 /// An attribute representing a reference to a dense vector or tensor object
diff --git a/mlir/lib/IR/BuiltinAttributes.cpp 
b/mlir/lib/IR/BuiltinAttributes.cpp
index 6f880f810d651..d7a86b547e1c2 100644
--- a/mlir/lib/IR/BuiltinAttributes.cpp
+++ b/mlir/lib/IR/BuiltinAttributes.cpp
@@ -453,31 +453,15 @@ LogicalResult 
OpaqueAttr::verify(function_ref<InFlightDiagnostic()> emitError,
 // DenseElementsAttr Utilities
 
//===----------------------------------------------------------------------===//
 
-const char DenseIntOrFPElementsAttrStorage::kSplatTrue = ~0;
-const char DenseIntOrFPElementsAttrStorage::kSplatFalse = 0;
-
 /// Get the bitwidth of a dense element type within the buffer.
 /// DenseElementsAttr requires bitwidths greater than 1 to be aligned by 8.
 static size_t getDenseElementStorageWidth(size_t origWidth) {
-  return origWidth == 1 ? origWidth : llvm::alignTo<8>(origWidth);
+  return llvm::alignTo<8>(origWidth);
 }
 static size_t getDenseElementStorageWidth(Type elementType) {
   return getDenseElementStorageWidth(getDenseElementBitWidth(elementType));
 }
 
-/// Set a bit to a specific value.
-static void setBit(char *rawData, size_t bitPos, bool value) {
-  if (value)
-    rawData[bitPos / CHAR_BIT] |= (1 << (bitPos % CHAR_BIT));
-  else
-    rawData[bitPos / CHAR_BIT] &= ~(1 << (bitPos % CHAR_BIT));
-}
-
-/// Return the value of the specified bit.
-static bool getBit(const char *rawData, size_t bitPos) {
-  return (rawData[bitPos / CHAR_BIT] & (1 << (bitPos % CHAR_BIT))) != 0;
-}
-
 /// Copy actual `numBytes` data from `value` (APInt) to char array(`result`) 
for
 /// BE format.
 static void copyAPIntToArrayForBEmachine(APInt value, size_t numBytes,
@@ -546,11 +530,7 @@ static void copyArrayToAPIntForBEmachine(const char 
*inArray, size_t numBytes,
 static void writeBits(char *rawData, size_t bitPos, APInt value) {
   size_t bitWidth = value.getBitWidth();
 
-  // If the bitwidth is 1 we just toggle the specific bit.
-  if (bitWidth == 1)
-    return setBit(rawData, bitPos, value.isOne());
-
-  // Otherwise, the bit position is guaranteed to be byte aligned.
+  // The bit position is guaranteed to be byte aligned.
   assert((bitPos % CHAR_BIT) == 0 && "expected bitPos to be 8-bit aligned");
   if (llvm::endianness::native == llvm::endianness::big) {
     // Copy from `value` to `rawData + (bitPos / CHAR_BIT)`.
@@ -570,11 +550,7 @@ static void writeBits(char *rawData, size_t bitPos, APInt 
value) {
 /// Reads the next `bitWidth` bits from the bit position `bitPos` in array
 /// `rawData`.
 static APInt readBits(const char *rawData, size_t bitPos, size_t bitWidth) {
-  // Handle a boolean bit position.
-  if (bitWidth == 1)
-    return APInt(1, getBit(rawData, bitPos) ? 1 : 0);
-
-  // Otherwise, the bit position must be 8-bit aligned.
+  // The bit position is guaranteed to be byte aligned.
   assert((bitPos % CHAR_BIT) == 0 && "expected bitPos to be 8-bit aligned");
   APInt result(bitWidth, 0);
   if (llvm::endianness::native == llvm::endianness::big) {
@@ -664,7 +640,7 @@ DenseElementsAttr::BoolElementIterator::BoolElementIterator(
           attr.getRawData().data(), attr.isSplat(), dataIndex) {}
 
 bool DenseElementsAttr::BoolElementIterator::operator*() const {
-  return getBit(getData(), getDataIndex());
+  return static_cast<bool>(getData()[getDataIndex()]);
 }
 
 
//===----------------------------------------------------------------------===//
@@ -910,7 +886,6 @@ bool DenseElementsAttr::classof(Attribute attr) {
 DenseElementsAttr DenseElementsAttr::get(ShapedType type,
                                          ArrayRef<Attribute> values) {
   assert(hasSameNumElementsOrSplat(type, values));
-
   Type eltType = type.getElementType();
 
   // Take care complex type case first.
@@ -984,10 +959,6 @@ DenseElementsAttr DenseElementsAttr::get(ShapedType type,
     writeBits(data.data(), i * storageBitWidth, intVal);
   }
 
-  // Handle the special encoding of splat of bool.
-  if (values.size() == 1 && eltType.isInteger(1))
-    data[0] = data[0] ? -1 : 0;
-
   return DenseIntOrFPElementsAttr::getRaw(type, data);
 }
 
@@ -995,25 +966,9 @@ DenseElementsAttr DenseElementsAttr::get(ShapedType type,
                                          ArrayRef<bool> values) {
   assert(hasSameNumElementsOrSplat(type, values));
   assert(type.getElementType().isInteger(1));
-
-  SmallVector<char> buff(llvm::divideCeil(values.size(), CHAR_BIT));
-
-  if (!values.empty()) {
-    bool isSplat = true;
-    bool firstValue = values[0];
-    for (int i = 0, e = values.size(); i != e; ++i) {
-      isSplat &= values[i] == firstValue;
-      setBit(buff.data(), i, values[i]);
-    }
-
-    // Splat of bool is encoded as a byte with all-ones in it.
-    if (isSplat) {
-      buff.resize(1);
-      buff[0] = values[0] ? -1 : 0;
-    }
-  }
-
-  return DenseIntOrFPElementsAttr::getRaw(type, buff);
+  return DenseIntOrFPElementsAttr::getRaw(
+      type, ArrayRef<char>(reinterpret_cast<const char *>(values.data()),
+                           values.size()));
 }
 
 DenseElementsAttr DenseElementsAttr::get(ShapedType type,
@@ -1084,23 +1039,7 @@ bool DenseElementsAttr::isValidRawBuffer(ShapedType type,
   // The initializer is always a splat if the result type has a single element.
   detectedSplat = numElements == 1;
 
-  // Storage width of 1 is special as it is packed by the bit.
-  if (storageWidth == 1) {
-    // Check for a splat, or a buffer equal to the number of elements which
-    // consists of either all 0's or all 1's.
-    if (rawBuffer.size() == 1) {
-      auto rawByte = static_cast<uint8_t>(rawBuffer[0]);
-      if (rawByte == 0 || rawByte == 0xff) {
-        detectedSplat = true;
-        return true;
-      }
-    }
-
-    // This is a valid non-splat buffer if it has the right size.
-    return rawBufferWidth == llvm::alignTo<8>(numElements);
-  }
-
-  // All other types are 8-bit aligned, so we can just check the buffer width
+  // All types are 8-bit aligned, so we can just check the buffer width
   // to know if only a single initializer element was passed in.
   if (rawBufferWidth == storageWidth) {
     detectedSplat = true;
@@ -1319,10 +1258,6 @@ static void writeAPIntsToBuffer(size_t storageWidth,
     assert((*it).getBitWidth() <= storageWidth);
     writeBits(data.data(), offset, *it);
   }
-
-  // Handle the special encoding of splat of a boolean.
-  if (numValues == 1 && (*values.begin()).getBitWidth() == 1)
-    data[0] = data[0] ? -1 : 0;
 }
 
 /// Constructs a dense elements attribute from an array of raw APFloat values.
@@ -1480,12 +1415,7 @@ static ShapedType mappingHelper(Fn mapping, Attr &attr, 
ShapedType inType,
 
   // Check for the splat case.
   if (attr.isSplat()) {
-    if (bitWidth == 1) {
-      // Handle the special encoding of splat of bool.
-      data[0] = mapping(*attr.begin()).isZero() ? 0 : -1;
-    } else {
-      processElt(*attr.begin(), /*index=*/0);
-    }
+    processElt(*attr.begin(), /*index=*/0);
     return newArrayType;
   }
 
diff --git a/mlir/test/IR/attribute-roundtrip.mlir 
b/mlir/test/IR/attribute-roundtrip.mlir
deleted file mode 100644
index 974dbcae6cf0a..0000000000000
--- a/mlir/test/IR/attribute-roundtrip.mlir
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: mlir-opt -canonicalize %s | mlir-opt | FileCheck %s
-
-// CHECK-LABEL: @large_i1_tensor_roundtrip
-func.func @large_i1_tensor_roundtrip() -> tensor<160xi1> {
-  %cst_0 = arith.constant dense<"0xFFF00000FF000000FF000000FF000000FF000000"> 
: tensor<160xi1>
-  %cst_1 = arith.constant dense<"0xFF000000FF000000FF000000FF000000FF0000F0"> 
: tensor<160xi1>
-  // CHECK: dense<"0xFF000000FF000000FF000000FF000000FF000000">
-  %0 = arith.andi %cst_0, %cst_1 : tensor<160xi1>
-  return %0 : tensor<160xi1>
-}
diff --git a/mlir/test/IR/parse-literal.mlir b/mlir/test/IR/parse-literal.mlir
index 71b25e1d86480..36867c56075d0 100644
--- a/mlir/test/IR/parse-literal.mlir
+++ b/mlir/test/IR/parse-literal.mlir
@@ -36,8 +36,8 @@ func.func @parse_i4_tensor() -> tensor<32xi4> {
 }
 
 // CHECK-LABEL: @parse_i1_tensor
-func.func @parse_i1_tensor() -> tensor<256xi1> {
-  // CHECK: 
dense<"0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F"> : 
tensor<256xi1>
-  %0 = arith.constant 
dense<"0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F"> : 
tensor<256xi1>
-  return %0 : tensor<256xi1>
+func.func @parse_i1_tensor() -> tensor<32xi1> {
+  // CHECK: dense<[true, false, true, false, true, true, true, true, true, 
true, true, true, true, true, true, true, true, true, true, true, true, true, 
true, true, true, false, false, false, false, false, false, true]> : 
tensor<32xi1>
+  %0 = arith.constant 
dense<"0x0100010001010101010101010101010101010101010101010100000000000001"> : 
tensor<32xi1>
+  return %0 : tensor<32xi1>
 }
diff --git a/mlir/test/python/ir/array_attributes.py 
b/mlir/test/python/ir/array_attributes.py
index 66f7ec8e7fff1..c1e2dd5f5ae5e 100644
--- a/mlir/test/python/ir/array_attributes.py
+++ b/mlir/test/python/ir/array_attributes.py
@@ -258,11 +258,10 @@ def testGetDenseElementsInteger4():
 @run
 def testGetDenseElementsBool():
     with Context():
-        bool_array = np.array([[1, 0, 1], [0, 1, 0]], dtype=np.bool_)
-        array = np.packbits(bool_array, axis=None, bitorder="little")
-        attr = DenseElementsAttr.get(
-            array, type=IntegerType.get_signless(1), shape=bool_array.shape
+        bool_array = np.array(
+            [[True, False, True], [False, True, False]], dtype=np.bool_
         )
+        attr = DenseElementsAttr.get(bool_array)
         # CHECK: dense<{{\[}}[true, false, true], [false, true, false]]> : 
tensor<2x3xi1>
         print(attr)
 
diff --git a/mlir/unittests/IR/AttributeTest.cpp 
b/mlir/unittests/IR/AttributeTest.cpp
index fd40404bf3008..404aa8c0dcf3d 100644
--- a/mlir/unittests/IR/AttributeTest.cpp
+++ b/mlir/unittests/IR/AttributeTest.cpp
@@ -76,20 +76,6 @@ TEST(DenseSplatTest, BoolSplatRawRoundtrip) {
   EXPECT_EQ(trueSplat, trueSplatFromRaw);
 }
 
-TEST(DenseSplatTest, BoolSplatSmall) {
-  MLIRContext context;
-  Builder builder(&context);
-
-  // Check that splats that don't fill entire byte are handled properly.
-  auto tensorType = RankedTensorType::get({4}, builder.getI1Type());
-  std::vector<char> data{0b00001111};
-  auto trueSplatFromRaw =
-      DenseIntOrFPElementsAttr::getFromRawBuffer(tensorType, data);
-  EXPECT_TRUE(trueSplatFromRaw.isSplat());
-  DenseElementsAttr trueSplat = DenseElementsAttr::get(tensorType, true);
-  EXPECT_EQ(trueSplat, trueSplatFromRaw);
-}
-
 TEST(DenseSplatTest, LargeBoolSplat) {
   constexpr int64_t boolCount = 56;
 

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to