[Mlir-commits] [mlir] 2bac720 - [mlir][vector] Take dim sizes into account in DropInnerMostUnitDims. (#71752)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Nov 10 09:28:04 PST 2023
Author: Han-Chung Wang
Date: 2023-11-10T09:27:59-08:00
New Revision: 2bac7201018dcab549895c30c0eb26bee45d842f
URL: https://github.com/llvm/llvm-project/commit/2bac7201018dcab549895c30c0eb26bee45d842f
DIFF: https://github.com/llvm/llvm-project/commit/2bac7201018dcab549895c30c0eb26bee45d842f.diff
LOG: [mlir][vector] Take dim sizes into account in DropInnerMostUnitDims. (#71752)
The `stride == 1` does not imply that we can drop it. Because it could
load more than 1 elements. We should also take source sizes and vector
sizes into account. Otherwise it generates invalid IRs. E.g.,
```mlir
func.func @foo(%arg0: memref<1x1xf32>) -> vector<4x8xf32> {
%c0 = arith.constant 0 : index
%cst = arith.constant 0.000000e+00 : f32
%0 = vector.transfer_read %arg0[%c0, %c0], %cst : memref<1x1xf32>, vector<4x8xf32>
return %0 : vector<4x8xf32>
}
```
Fixes https://github.com/openxla/iree/issues/15493
Added:
Modified:
mlir/lib/Dialect/Vector/Transforms/VectorTransforms.cpp
mlir/test/Dialect/Vector/vector-transfer-collapse-inner-most-dims.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Dialect/Vector/Transforms/VectorTransforms.cpp b/mlir/lib/Dialect/Vector/Transforms/VectorTransforms.cpp
index 16f9d7e4d57eef7..713f9cb72c82cec 100644
--- a/mlir/lib/Dialect/Vector/Transforms/VectorTransforms.cpp
+++ b/mlir/lib/Dialect/Vector/Transforms/VectorTransforms.cpp
@@ -1184,10 +1184,19 @@ class DropInnerMostUnitDims : public OpRewritePattern<vector::TransferReadOp> {
if (failed(getStridesAndOffset(srcType, srcStrides, srcOffset)))
return failure();
+ // According to vector.transfer_read semantics, the result can be a slice.
+ // It pads the indices with `1` starting from beginning. Thus, we have to
+ // offset the check index with `rankDiff` in `srcStrides` and source dim
+ // sizes.
size_t dimsToDrop = 0;
- for (size_t i = 1; i < srcStrides.size(); ++i) {
- int dim = srcType.getRank() - i - 1;
- if (srcStrides[dim] == 1) {
+ int rankDiff = srcType.getRank() - targetType.getRank();
+ for (int64_t i = 0, e = targetType.getRank(); i < e; ++i) {
+ // Check that the inner dim size is 1 for both memref/tensor type and
+ // vector slice. It can be folded only if they are 1 and the stride is 1.
+ int dim = targetType.getRank() - i - 1;
+ if (srcStrides[dim + rankDiff] == 1 &&
+ srcType.getDimSize(dim + rankDiff) == 1 &&
+ targetType.getDimSize(dim) == 1) {
dimsToDrop++;
} else {
break;
diff --git a/mlir/test/Dialect/Vector/vector-transfer-collapse-inner-most-dims.mlir b/mlir/test/Dialect/Vector/vector-transfer-collapse-inner-most-dims.mlir
index ef0bd9ddf8abf4b..0d2743b9fe2e7f5 100644
--- a/mlir/test/Dialect/Vector/vector-transfer-collapse-inner-most-dims.mlir
+++ b/mlir/test/Dialect/Vector/vector-transfer-collapse-inner-most-dims.mlir
@@ -60,3 +60,19 @@ func.func @contiguous_inner_most_dim_bounds_2d(%A: memref<1000x1x1xf32>, %i:inde
// CHECK: %[[V:.+]] = vector.transfer_read %[[SRC_1]]
// CHECK-SAME: {in_bounds = [true]}
// CHECK-SAME: vector<4xf32>
+
+// -----
+
+func.func @contiguous_inner_most_dim_out_of_bounds_2d(%arg0: memref<1x1xf32>) -> vector<4x8xf32> {
+ %c0 = arith.constant 0 : index
+ %cst = arith.constant 0.000000e+00 : f32
+ %0 = vector.transfer_read %arg0[%c0, %c0], %cst : memref<1x1xf32>, vector<4x8xf32>
+ return %0 : vector<4x8xf32>
+}
+// The inner most unit dim can not be dropped. In this context, we do not
+// generate rank-reduced memref.subview ops.
+// CHECK: func.func @contiguous_inner_most_dim_out_of_bounds_2d
+// CHECK-SAME: %[[SRC:[a-zA-Z0-9]+]]
+// CHECK-NOT: memref.subview
+// CHECK: %[[READ:.+]] = vector.transfer_read %[[SRC]]
+// CHECK: return %[[READ]] : vector<4x8xf32>
More information about the Mlir-commits
mailing list