From 7095a1ff82b9fe292f871f0e873c2ac56328e8a6 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Sun, 12 Jun 2022 16:03:30 +0200 Subject: [PATCH] Fix endian conversion of sub-byte types 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 | 7 +++++-- mlir/test/IR/parse-literal.mlir | 43 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 mlir/test/IR/parse-literal.mlir diff --git a/mlir/lib/IR/BuiltinAttributes.cpp b/mlir/lib/IR/BuiltinAttributes.cpp index 8fa4e03..4358460 100644 --- a/mlir/lib/IR/BuiltinAttributes.cpp +++ b/mlir/lib/IR/BuiltinAttributes.cpp @@ -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 index 0000000..71b25e1 --- /dev/null +++ b/mlir/test/IR/parse-literal.mlir @@ -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> +} -- 2.7.4