Fix endian conversion of sub-byte types
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Sun, 12 Jun 2022 14:03:30 +0000 (16:03 +0200)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Sun, 12 Jun 2022 14:08:23 +0000 (16:08 +0200)
When convertEndianOfCharForBEmachine is called with elementBitWidth
smaller than CHAR_BIT, the default case is invoked, but this does
nothing at all and leaves the output array unchanged.

Fix DenseIntOrFPElementsAttr::convertEndianOfArrayRefForBEmachine
by not calling convertEndianOfCharForBEmachine in this case, and
instead simply copying the input to the output (for sub-byte types,
endian conversion is in fact a no-op).

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D125676

mlir/lib/IR/BuiltinAttributes.cpp
mlir/test/IR/parse-literal.mlir [new file with mode: 0644]

index 8fa4e03..4358460 100644 (file)
@@ -1188,8 +1188,11 @@ void DenseIntOrFPElementsAttr::convertEndianOfArrayRefForBEmachine(
   size_t elementBitWidth = getDenseElementStorageWidth(elementType);
   assert(numElements * elementBitWidth == inRawData.size() * CHAR_BIT &&
          inRawData.size() <= outRawData.size());
-  convertEndianOfCharForBEmachine(inRawData.begin(), outRawData.begin(),
-                                  elementBitWidth, numElements);
+  if (elementBitWidth <= CHAR_BIT)
+    std::memcpy(outRawData.begin(), inRawData.begin(), inRawData.size());
+  else
+    convertEndianOfCharForBEmachine(inRawData.begin(), outRawData.begin(),
+                                    elementBitWidth, numElements);
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/test/IR/parse-literal.mlir b/mlir/test/IR/parse-literal.mlir
new file mode 100644 (file)
index 0000000..71b25e1
--- /dev/null
@@ -0,0 +1,43 @@
+// RUN: mlir-opt %s | FileCheck %s
+
+// CHECK-LABEL: @parse_i64_tensor
+func.func @parse_i64_tensor() -> tensor<4xi64> {
+  // CHECK: dense<255> : tensor<4xi64>
+  %0 = arith.constant dense<"0xFF00000000000000FF00000000000000FF00000000000000FF00000000000000"> : tensor<4xi64>
+  return %0 : tensor<4xi64>
+}
+
+// CHECK-LABEL: @parse_i32_tensor
+func.func @parse_i32_tensor() -> tensor<8xi32> {
+  // CHECK: dense<255> : tensor<8xi32>
+  %0 = arith.constant dense<"0xFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000"> : tensor<8xi32>
+  return %0 : tensor<8xi32>
+}
+
+// CHECK-LABEL: @parse_i16_tensor
+func.func @parse_i16_tensor() -> tensor<16xi16> {
+  // CHECK: dense<255> : tensor<16xi16>
+  %0 = arith.constant dense<"0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00"> : tensor<16xi16>
+  return %0 : tensor<16xi16>
+}
+
+// CHECK-LABEL: @parse_i8_tensor
+func.func @parse_i8_tensor() -> tensor<32xi8> {
+  // CHECK: dense<15> : tensor<32xi8>
+  %0 = arith.constant dense<"0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F"> : tensor<32xi8>
+  return %0 : tensor<32xi8>
+}
+
+// CHECK-LABEL: @parse_i4_tensor
+func.func @parse_i4_tensor() -> tensor<32xi4> {
+  // CHECK: dense<-1> : tensor<32xi4>
+  %0 = arith.constant dense<"0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F"> : tensor<32xi4>
+  return %0 : 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>
+}