diff --git a/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp b/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp index 844e6183cff06..9c2f39a897552 100644 --- a/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp +++ b/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp @@ -3002,17 +3002,18 @@ MemRefType SubViewOp::inferRankReducedResultType( assert(dimsToProject.has_value() && "invalid rank reduction"); // Compute the layout and result type. - auto inferredLayout = llvm::cast(inferredType.getLayout()); + int64_t offset; + SmallVector inferredStrides; + (void)inferredType.getStridesAndOffset(inferredStrides, offset); SmallVector rankReducedStrides; rankReducedStrides.reserve(resultShape.size()); - for (auto [idx, value] : llvm::enumerate(inferredLayout.getStrides())) { + for (auto [idx, value] : llvm::enumerate(inferredStrides)) { if (!dimsToProject->contains(idx)) rankReducedStrides.push_back(value); } return MemRefType::get(resultShape, inferredType.getElementType(), - StridedLayoutAttr::get(inferredLayout.getContext(), - inferredLayout.getOffset(), - rankReducedStrides), + StridedLayoutAttr::get(inferredType.getContext(), + offset, rankReducedStrides), inferredType.getMemorySpace()); } @@ -3314,7 +3315,10 @@ static MemRefType getCanonicalSubViewResultType( if (failed(unusedDims)) return nullptr; - auto layout = llvm::cast(nonRankReducedType.getLayout()); + int64_t offset; + SmallVector nonRankReducedStrides; + (void)nonRankReducedType.getStridesAndOffset(nonRankReducedStrides, offset); + SmallVector shape, strides; unsigned numDimsAfterReduction = nonRankReducedType.getRank() - unusedDims->count(); @@ -3322,17 +3326,17 @@ static MemRefType getCanonicalSubViewResultType( strides.reserve(numDimsAfterReduction); for (const auto &[idx, size, stride] : llvm::zip(llvm::seq(0, nonRankReducedType.getRank()), - nonRankReducedType.getShape(), layout.getStrides())) { + nonRankReducedType.getShape(), nonRankReducedStrides)) { if (unusedDims->test(idx)) continue; shape.push_back(size); strides.push_back(stride); } - return MemRefType::get(shape, nonRankReducedType.getElementType(), - StridedLayoutAttr::get(sourceType.getContext(), - layout.getOffset(), strides), - nonRankReducedType.getMemorySpace()); + return MemRefType::get( + shape, nonRankReducedType.getElementType(), + StridedLayoutAttr::get(sourceType.getContext(), offset, strides), + nonRankReducedType.getMemorySpace()); } Value mlir::memref::createCanonicalRankReducingSubViewOp( diff --git a/mlir/lib/IR/BuiltinTypes.cpp b/mlir/lib/IR/BuiltinTypes.cpp index 1e198043c590a..cd58355ca0ff0 100644 --- a/mlir/lib/IR/BuiltinTypes.cpp +++ b/mlir/lib/IR/BuiltinTypes.cpp @@ -566,13 +566,46 @@ unsigned MemRefType::getMemorySpaceAsInt() const { return detail::getMemorySpaceAsInt(getMemorySpace()); } +static size_t getNumContiguousTrailingDimsImpl(ArrayRef shape, + ArrayRef strides) { + const int64_t n = shape.size(); + // A memref with dimensions `d0, d1, ..., dn-1` and strides + // `s0, s1, ..., sn-1` is contiguous up to dimension `k` + // if each stride `si` is the product of the dimensions `di+1, ..., dn-1`, + // for `i` in `[k, n-1]`. + // Ignore stride elements if the corresponding dimension is 1, as they are + // of no consequence. + int64_t dimProduct = 1; + for (int64_t i = n - 1; i >= 0; --i) { + if (shape[i] == 1) + continue; + if (strides[i] != dimProduct) + return n - i - 1; + if (shape[i] == ShapedType::kDynamic) + return n - i; + dimProduct *= shape[i]; + } + return n; +} + MemRefType MemRefType::get(ArrayRef shape, Type elementType, MemRefLayoutAttrInterface layout, Attribute memorySpace) { - // Use default layout for empty attribute. - if (!layout) + if (!layout) { + // Use default layout for empty attribute. layout = AffineMapAttr::get(AffineMap::getMultiDimIdentityMap( shape.size(), elementType.getContext())); + } else if (shape.size() == layout.getAffineMap().getNumDims()) { + // If the layout can be inferred to be an identity, prefer using the + // identity layout. + int64_t offset; + SmallVector strides; + (void)layout.getStridesAndOffset(shape, strides, offset); + if (offset == 0 && strides.size() == shape.size() && + getNumContiguousTrailingDimsImpl(shape, strides) == shape.size()) + layout = AffineMapAttr::get(AffineMap::getMultiDimIdentityMap( + shape.size(), elementType.getContext())); + } // Drop default memory space value and replace it with empty attribute. memorySpace = skipDefaultMemorySpace(memorySpace); @@ -585,10 +618,21 @@ MemRefType MemRefType::getChecked( function_ref emitErrorFn, ArrayRef shape, Type elementType, MemRefLayoutAttrInterface layout, Attribute memorySpace) { - // Use default layout for empty attribute. - if (!layout) + if (!layout) { + // Use default layout for empty attribute. layout = AffineMapAttr::get(AffineMap::getMultiDimIdentityMap( shape.size(), elementType.getContext())); + } else if (shape.size() == layout.getAffineMap().getNumDims()) { + // If the layout can be inferred to be an identity, prefer using the + // identity layout. + int64_t offset; + SmallVector strides; + (void)layout.getStridesAndOffset(shape, strides, offset); + if (offset == 0 && strides.size() == shape.size() && + getNumContiguousTrailingDimsImpl(shape, strides) == shape.size()) + layout = AffineMapAttr::get(AffineMap::getMultiDimIdentityMap( + shape.size(), elementType.getContext())); + } // Drop default memory space value and replace it with empty attribute. memorySpace = skipDefaultMemorySpace(memorySpace); @@ -600,10 +644,22 @@ MemRefType MemRefType::getChecked( MemRefType MemRefType::get(ArrayRef shape, Type elementType, AffineMap map, Attribute memorySpace) { - // Use default layout for empty map. - if (!map) + if (!map) { + // Use default layout for empty map. map = AffineMap::getMultiDimIdentityMap(shape.size(), elementType.getContext()); + } else if (shape.size() == map.getNumDims()) { + // If the layout can be inferred to be an identity, prefer using the + // identity layout. + int64_t offset; + SmallVector strides; + (void)::mlir::detail::getAffineMapStridesAndOffset(map, shape, strides, + offset); + if (offset == 0 && strides.size() == shape.size() && + getNumContiguousTrailingDimsImpl(shape, strides) == shape.size()) + map = AffineMap::getMultiDimIdentityMap(shape.size(), + elementType.getContext()); + } // Wrap AffineMap into Attribute. auto layout = AffineMapAttr::get(map); @@ -620,10 +676,22 @@ MemRefType::getChecked(function_ref emitErrorFn, ArrayRef shape, Type elementType, AffineMap map, Attribute memorySpace) { - // Use default layout for empty map. - if (!map) + if (!map) { + // Use default layout for empty map. map = AffineMap::getMultiDimIdentityMap(shape.size(), elementType.getContext()); + } else if (shape.size() == map.getNumDims()) { + // If the layout can be inferred to be an identity, prefer using the + // identity layout. + int64_t offset; + SmallVector strides; + (void)::mlir::detail::getAffineMapStridesAndOffset(map, shape, strides, + offset); + if (offset == 0 && strides.size() == shape.size() && + getNumContiguousTrailingDimsImpl(shape, strides) == shape.size()) + map = AffineMap::getMultiDimIdentityMap(shape.size(), + elementType.getContext()); + } // Wrap AffineMap into Attribute. auto layout = AffineMapAttr::get(map); @@ -638,10 +706,22 @@ MemRefType::getChecked(function_ref emitErrorFn, MemRefType MemRefType::get(ArrayRef shape, Type elementType, AffineMap map, unsigned memorySpaceInd) { - // Use default layout for empty map. - if (!map) + if (!map) { + // Use default layout for empty map. map = AffineMap::getMultiDimIdentityMap(shape.size(), elementType.getContext()); + } else if (shape.size() == map.getNumDims()) { + // If the layout can be inferred to be an identity, prefer using the + // identity layout. + int64_t offset; + SmallVector strides; + (void)::mlir::detail::getAffineMapStridesAndOffset(map, shape, strides, + offset); + if (offset == 0 && strides.size() == shape.size() && + getNumContiguousTrailingDimsImpl(shape, strides) == shape.size()) + map = AffineMap::getMultiDimIdentityMap(shape.size(), + elementType.getContext()); + } // Wrap AffineMap into Attribute. auto layout = AffineMapAttr::get(map); @@ -659,10 +739,22 @@ MemRefType::getChecked(function_ref emitErrorFn, ArrayRef shape, Type elementType, AffineMap map, unsigned memorySpaceInd) { - // Use default layout for empty map. - if (!map) + if (!map) { + // Use default layout for empty map. map = AffineMap::getMultiDimIdentityMap(shape.size(), elementType.getContext()); + } else if (shape.size() == map.getNumDims()) { + // If the layout can be inferred to be an identity, prefer using the + // identity layout. + int64_t offset; + SmallVector strides; + (void)::mlir::detail::getAffineMapStridesAndOffset(map, shape, strides, + offset); + if (offset == 0 && strides.size() == shape.size() && + getNumContiguousTrailingDimsImpl(shape, strides) == shape.size()) + map = AffineMap::getMultiDimIdentityMap(shape.size(), + elementType.getContext()); + } // Wrap AffineMap into Attribute. auto layout = AffineMapAttr::get(map); @@ -705,7 +797,6 @@ bool MemRefType::areTrailingDimsContiguous(int64_t n) { int64_t MemRefType::getNumContiguousTrailingDims() { const int64_t n = getRank(); - // memrefs with identity layout are entirely contiguous. if (getLayout().isIdentity()) return n; @@ -716,27 +807,7 @@ int64_t MemRefType::getNumContiguousTrailingDims() { SmallVector strides; if (!succeeded(getStridesAndOffset(strides, offset))) return 0; - - ArrayRef shape = getShape(); - - // A memref with dimensions `d0, d1, ..., dn-1` and strides - // `s0, s1, ..., sn-1` is contiguous up to dimension `k` - // if each stride `si` is the product of the dimensions `di+1, ..., dn-1`, - // for `i` in `[k, n-1]`. - // Ignore stride elements if the corresponding dimension is 1, as they are - // of no consequence. - int64_t dimProduct = 1; - for (int64_t i = n - 1; i >= 0; --i) { - if (shape[i] == 1) - continue; - if (strides[i] != dimProduct) - return n - i - 1; - if (shape[i] == ShapedType::kDynamic) - return n - i; - dimProduct *= shape[i]; - } - - return n; + return getNumContiguousTrailingDimsImpl(getShape(), strides); } MemRefType MemRefType::canonicalizeStridedLayout() { diff --git a/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-empty-tensor-elimination.mlir b/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-empty-tensor-elimination.mlir index 3929f5be3b4ef..c84ba3d59ee5d 100644 --- a/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-empty-tensor-elimination.mlir +++ b/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-empty-tensor-elimination.mlir @@ -24,8 +24,8 @@ func.func @buffer_forwarding_conflict( %f = linalg.fill ins(%f0 : f32) outs(%a : tensor) -> tensor // CHECK: memref.copy %[[FUNC_ARG]], %[[ALLOC]] : memref to memref - // CHECK: %[[SV0_ALLOC:.*]] = memref.subview %[[ALLOC]][0] [%[[sz]]] [1] : memref to memref> - // CHECK: memref.copy %[[EXTRACT_SLICE_ALLOC]], %[[SV0_ALLOC]] : memref to memref> + // CHECK: %[[SV0_ALLOC:.*]] = memref.subview %[[ALLOC]][0] [%[[sz]]] [1] : memref to memref + // CHECK: memref.copy %[[EXTRACT_SLICE_ALLOC]], %[[SV0_ALLOC]] : memref to memref %r0 = tensor.insert_slice %f into %t[0][%sz][1]: tensor into tensor // CHECK: %[[T_SUBVIEW:.*]] = memref.subview %[[FUNC_ARG]][42] [%[[sz]]] [1] diff --git a/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-encodings.mlir b/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-encodings.mlir index e97777c3e3d13..5ddde4cc4c65d 100644 --- a/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-encodings.mlir +++ b/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-encodings.mlir @@ -90,8 +90,8 @@ func.func @alloc_tesor_copy_from_non_default_space_no_cast(%arg0: tensor<128xf32 // CHECK: %[[v3:.+]] = bufferization.to_tensor %[[alloc]] : memref<128xf32, 2> to tensor<128xf32, 1 : i64> // CHECK: %[[alloc_0:.+]] = memref.alloc() {alignment = 64 : i64} : memref<128xf32, 1> // CHECK: memref.copy %[[v1]], %[[alloc_0]] : memref<128xf32, strided<[?], offset: ?>, 1> to memref<128xf32, 1> -// CHECK: %[[subview:.+]] = memref.subview %[[alloc_0]][0] [4] [1] : memref<128xf32, 1> to memref<4xf32, strided<[1]>, 1> -// CHECK: memref.copy %[[v0]], %[[subview]] : memref<4xf32, strided<[?], offset: ?>, 1> to memref<4xf32, strided<[1]>, 1> +// CHECK: %[[subview:.+]] = memref.subview %[[alloc_0]][0] [4] [1] : memref<128xf32, 1> to memref<4xf32, 1> +// CHECK: memref.copy %[[v0]], %[[subview]] : memref<4xf32, strided<[?], offset: ?>, 1> to memref<4xf32, 1> // CHECK: return %[[v3]] : tensor<128xf32, 1 : i64> // ----- diff --git a/mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize.mlir b/mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize.mlir index 8db1ebb87a1e5..4d48f76e835ca 100644 --- a/mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize.mlir +++ b/mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize.mlir @@ -561,7 +561,6 @@ func.func @entry(%A : tensor {bufferization.buffer_layout = affine_map<(i // %A, %B and %C are not inplaceable. This test case shows that this kind of // conflict detection has a "transitive" nature. // CHECK-DAG: %[[ALLOC_A:.*]] = memref.alloc -// CHECK-DAG: %[[CASTED_A:.*]] = memref.cast %[[ALLOC_A]] // CHECK-DAG: %[[ALLOC_B:.*]] = memref.alloc // CHECK-DAG: %[[CASTED_B:.*]] = memref.cast %[[ALLOC_B]] // CHECK-DAG: %[[ALLOC_C:.*]] = memref.alloc @@ -569,7 +568,7 @@ func.func @entry(%A : tensor {bufferization.buffer_layout = affine_map<(i // CHECK-DAG: memref.copy %[[A]], %[[ALLOC_A]] // CHECK-DAG: memref.copy %[[B]], %[[ALLOC_B]] // CHECK-DAG: memref.copy %[[C]], %[[ALLOC_C]] -// CHECK-NEXT: call @callee(%[[CASTED_A]], %[[CASTED_B]], %[[CASTED_C]]) +// CHECK-NEXT: call @callee(%[[ALLOC_A]], %[[CASTED_B]], %[[CASTED_C]]) call @callee(%A, %B, %C) : (tensor, tensor, tensor) -> () return } diff --git a/mlir/test/Dialect/Builtin/types.mlir b/mlir/test/Dialect/Builtin/types.mlir index 80840ec32424e..a298cd6676e94 100644 --- a/mlir/test/Dialect/Builtin/types.mlir +++ b/mlir/test/Dialect/Builtin/types.mlir @@ -12,7 +12,7 @@ func.func private @f4() -> memref> func.func private @f5() -> memref> // CHECK: memref> func.func private @f6() -> memref> -// CHECK: memref> +// CHECK: memref func.func private @f7() -> memref> // CHECK: memref> func.func private @f8() -> memref> diff --git a/mlir/test/Dialect/Linalg/drop-unit-extent-dims.mlir b/mlir/test/Dialect/Linalg/drop-unit-extent-dims.mlir index 841d0e5f56512..927094714c98b 100644 --- a/mlir/test/Dialect/Linalg/drop-unit-extent-dims.mlir +++ b/mlir/test/Dialect/Linalg/drop-unit-extent-dims.mlir @@ -959,8 +959,8 @@ func.func @drop_all_loops(%arg0 : memref<1x1xf32, 3>) -> memref<1x1xf32, 3> // CHECK: linalg.generic{{.*}}memref // CHECK-SLICES-LABEL: func @drop_all_loops -// CHECK-SLICES: memref.subview %{{.*}}[0, 0] [1, 1] [1, 1] : memref<1x1xf32, 3> to memref, 3> -// CHECK-SLICES: linalg.generic{{.*}}memref, 3> +// CHECK-SLICES: memref.subview %{{.*}}[0, 0] [1, 1] [1, 1] : memref<1x1xf32, 3> to memref +// CHECK-SLICES: linalg.generic{{.*}}memref // ----- diff --git a/mlir/test/Dialect/MemRef/canonicalize.mlir b/mlir/test/Dialect/MemRef/canonicalize.mlir index 3cfea1e8cd961..c65facc3bbae1 100644 --- a/mlir/test/Dialect/MemRef/canonicalize.mlir +++ b/mlir/test/Dialect/MemRef/canonicalize.mlir @@ -1298,7 +1298,7 @@ func.func @canonicalize_rank_reduced_subview(%arg0 : memref<8x?xf32>, // CHECK-SAME: %[[ARG0:.+]]: memref<8x?xf32> // CHECK-SAME: %[[ARG1:.+]]: index // CHECK: %[[SUBVIEW:.+]] = memref.subview %[[ARG0]][0, 0] [1, %[[ARG1]]] [1, 1] -// CHECK-SAME: memref<8x?xf32> to memref> +// CHECK-SAME: memref<8x?xf32> to memref // ----- @@ -1316,10 +1316,9 @@ func.func @memref_realloc_dead(%src : memref<2xf32>, %v : f32) -> memref<2xf32>{ // ----- // CHECK-LABEL: func @collapse_expand_fold_to_cast( -// CHECK-SAME: %[[m:.*]]: memref, 3> -// CHECK: %[[casted:.*]] = memref.cast %[[m]] : memref, 3> to memref, 3>, %sz0: index) +// CHECK-SAME: %[[m:.*]]: memref +// CHECK: return %[[m]] +func.func @collapse_expand_fold_to_cast(%m: memref, %sz0: index) -> (memref) { %0 = memref.expand_shape %m [[0, 1]] output_shape [1, %sz0] diff --git a/mlir/test/Dialect/MemRef/flatten_memref.mlir b/mlir/test/Dialect/MemRef/flatten_memref.mlir index e45a10ca0d431..4bfcec21e9785 100644 --- a/mlir/test/Dialect/MemRef/flatten_memref.mlir +++ b/mlir/test/Dialect/MemRef/flatten_memref.mlir @@ -110,7 +110,7 @@ func.func @load_vector_from_memref_dynamic(%input: memref<3x7xi2>, %row: index, // CHECK: func @load_vector_from_memref_dynamic // CHECK: %[[IDX:.*]] = affine.apply #[[MAP]]() // CHECK: %[[REINT:.*]] = memref.reinterpret_cast -// CHECK: vector.load %[[REINT]][%[[IDX]]] : memref<21xi2, strided<[1]>>, vector<3xi2> +// CHECK: vector.load %[[REINT]][%[[IDX]]] : memref<21xi2>, vector<3xi2> // ----- @@ -124,7 +124,7 @@ func.func @store_vector_to_memref_odd(%input: memref<3x7xi2>, %value: vector<3xi // CHECK-SAME: (%[[ARG0:.*]]: memref<3x7xi2>, %[[ARG1:.*]]: vector<3xi2>) // CHECK: %[[C10:.*]] = arith.constant 10 : index // CHECK-NEXT: %[[REINT:.*]] = memref.reinterpret_cast -// CHECK-NEXT: vector.store %[[ARG1]], %[[REINT]][%[[C10]]] : memref<21xi2, strided<[1]> +// CHECK-NEXT: vector.store %[[ARG1]], %[[REINT]][%[[C10]]] : memref<21xi2 // ----- @@ -255,8 +255,8 @@ func.func @alloc() -> memref<4x8xf32> { // CHECK-LABEL: func @alloc // CHECK-SAME: () -> memref<4x8xf32> -// CHECK-NEXT: %[[ALLOC:.*]] = memref.alloc() : memref<32xf32, strided<[1]>> -// CHECK-NEXT: %[[REINT:.*]] = memref.reinterpret_cast %[[ALLOC]] to offset: [0], sizes: [4, 8], strides: [8, 1] : memref<32xf32, strided<[1]>> to memref<4x8xf32> +// CHECK-NEXT: %[[ALLOC:.*]] = memref.alloc() : memref<32xf32> +// CHECK-NEXT: %[[REINT:.*]] = memref.reinterpret_cast %[[ALLOC]] to offset: [0], sizes: [4, 8], strides: [8, 1] : memref<32xf32> to memref<4x8xf32> // ----- @@ -266,8 +266,8 @@ func.func @alloca() -> memref<4x8xf32> { } // CHECK-LABEL: func.func @alloca() -> memref<4x8xf32> -// CHECK: %[[ALLOC:.*]] = memref.alloca() : memref<32xf32, strided<[1]>> -// CHECK: %[[REINT:.*]] = memref.reinterpret_cast %[[ALLOC]] to offset: [0], sizes: [4, 8], strides: [8, 1] : memref<32xf32, strided<[1]>> to memref<4x8xf32> +// CHECK: %[[ALLOC:.*]] = memref.alloca() : memref<32xf32> +// CHECK: %[[REINT:.*]] = memref.reinterpret_cast %[[ALLOC]] to offset: [0], sizes: [4, 8], strides: [8, 1] : memref<32xf32> to memref<4x8xf32> // ----- @@ -282,8 +282,8 @@ func.func @chained_alloc_load() -> vector<8xf32> { // CHECK-LABEL: func @chained_alloc_load // CHECK-SAME: () -> vector<8xf32> // CHECK-NEXT: %[[C30:.*]] = arith.constant 30 : index -// CHECK-NEXT: %[[ALLOC:.*]] = memref.alloc() : memref<32xf32, strided<[1]>> -// CHECK-NEXT: vector.load %[[ALLOC]][%[[C30]]] : memref<32xf32, strided<[1]>>, vector<8xf32> +// CHECK-NEXT: %[[ALLOC:.*]] = memref.alloc() : memref<32xf32> +// CHECK-NEXT: vector.load %[[ALLOC]][%[[C30]]] : memref<32xf32>, vector<8xf32> // ----- diff --git a/mlir/test/Dialect/MemRef/make-loop-independent.mlir b/mlir/test/Dialect/MemRef/make-loop-independent.mlir index dca7bc1e67586..c48d417e83014 100644 --- a/mlir/test/Dialect/MemRef/make-loop-independent.mlir +++ b/mlir/test/Dialect/MemRef/make-loop-independent.mlir @@ -12,12 +12,11 @@ func.func @make_alloca_loop_independent(%lb: index, %ub: index, %step: index) { scf.for %i = %lb to %ub step %step { // CHECK: %[[sz:.*]] = affine.apply #[[$map]]()[%[[ub]]] // CHECK: %[[alloca:.*]] = memref.alloca(%[[sz]]) - // CHECK: %[[subview:.*]] = memref.subview %[[alloca]][0] [%[[iv]]] [1] : memref to memref> - // CHECK: %[[cast:.*]] = builtin.unrealized_conversion_cast %[[subview]] : memref> to memref + // CHECK: %[[subview:.*]] = memref.subview %[[alloca]][0] [%[[iv]]] [1] : memref to memref %alloc = memref.alloca(%i) : memref // memref.subview has special handling. - // CHECK: %[[subview2:.*]] = memref.subview %[[subview]][1] [5] [1] : memref> to memref<5xf32, strided<[1], offset: 1>> + // CHECK: %[[subview2:.*]] = memref.subview %[[subview]][1] [5] [1] : memref to memref<5xf32, strided<[1], offset: 1>> %view = memref.subview %alloc[1][5][1] : memref to memref<5xf32, strided<[1], offset: 1>> // This op takes a memref but does not produce one. The new alloc is used @@ -27,7 +26,7 @@ func.func @make_alloca_loop_independent(%lb: index, %ub: index, %step: index) { // This op produces a memref, so the new alloc cannot be used directly. // It is wrapped in a unrealized_conversion_cast. - // CHECK: "test.another_use"(%[[cast]]) : (memref) -> memref + // CHECK: "test.another_use"(%[[subview]]) : (memref) -> memref "test.another_use"(%alloc) : (memref) -> (memref) // CHECK: memref.store %{{.*}}, %[[subview]] @@ -57,7 +56,7 @@ func.func @make_alloca_loop_independent_static(%step: index) { %sz = affine.apply affine_map<(d0)[s0] -> (-d0 + s0)>(%i)[%ub] // CHECK: %[[alloca:.*]] = memref.alloca() : memref<128xf32> - // CHECK: %[[subview:.*]] = memref.subview %[[alloca]][0] [%[[sz]]] [1] : memref<128xf32> to memref> + // CHECK: %[[subview:.*]] = memref.subview %[[alloca]][0] [%[[sz]]] [1] : memref<128xf32> to memref %alloc = memref.alloca(%sz) : memref // CHECK: memref.store %{{.*}}, %[[subview]] diff --git a/mlir/test/Dialect/MemRef/ops.mlir b/mlir/test/Dialect/MemRef/ops.mlir index 14ac6a03d6ae0..47af9fc467cea 100644 --- a/mlir/test/Dialect/MemRef/ops.mlir +++ b/mlir/test/Dialect/MemRef/ops.mlir @@ -485,13 +485,13 @@ func.func @expand_collapse_shape_dynamic(%arg0: memref, memref> // CHECK: memref.collapse_shape {{.*}} {{\[}}[0, 1]] -// CHECK-SAME: memref> into memref> +// CHECK-SAME: memref> into memref %3 = memref.collapse_shape %arg3 [[0, 1]] : memref> into memref> // CHECK: memref.expand_shape {{.*}} {{\[}}[0, 1]] output_shape [%arg6, 42] -// CHECK-SAME: memref> into memref +// CHECK-SAME: memref into memref %r3 = memref.expand_shape %3 [[0, 1]] output_shape [%arg6, 42] : memref> into memref diff --git a/mlir/test/Dialect/Tensor/bufferize.mlir b/mlir/test/Dialect/Tensor/bufferize.mlir index be8ce20d8f154..423615ce7bc6c 100644 --- a/mlir/test/Dialect/Tensor/bufferize.mlir +++ b/mlir/test/Dialect/Tensor/bufferize.mlir @@ -493,7 +493,7 @@ func.func @tensor.collapse_shape_of_slice3(%t1: tensor<1x2xf32>) -> tensor<1xf32 // CHECK: memref.subview {{.*}} : memref<1x2xf32> to memref<1x1xf32, strided<[2, 1]>> %0 = tensor.extract_slice %t1[0, 0][1, 1][1, 1] : tensor<1x2xf32> to tensor<1x1xf32> // CHECK: memref.collapse_shape %{{.*}} [ - // CHECK-SAME: [0, 1]] : memref<1x1xf32, strided<[2, 1]>> into memref<1xf32, strided<[2]>> + // CHECK-SAME: [0, 1]] : memref<1x1xf32, strided<[2, 1]>> into memref<1xf32> %1 = tensor.collapse_shape %0 [[0, 1]] : tensor<1x1xf32> into tensor<1xf32> return %1 : tensor<1xf32> } diff --git a/mlir/test/Dialect/Tensor/one-shot-bufferize.mlir b/mlir/test/Dialect/Tensor/one-shot-bufferize.mlir index f66cf7ae53266..c2d86f629be02 100644 --- a/mlir/test/Dialect/Tensor/one-shot-bufferize.mlir +++ b/mlir/test/Dialect/Tensor/one-shot-bufferize.mlir @@ -116,8 +116,8 @@ func.func @insert_slice_fun_not_inplace( { // CHECK: %[[ALLOC:.*]] = memref.alloc(%{{.*}}) {alignment = 64 : i64} : memref // CHECK: memref.copy %[[A]], %[[ALLOC]] : memref - // CHECK: %[[SV:.*]] = memref.subview %[[ALLOC]][0] [4] [1] : memref to memref<4xf32, strided<[1]>> - // CHECK: memref.copy %[[t]], %[[SV]] : memref<4xf32, strided{{.*}}> to memref<4xf32, strided<[1]>> + // CHECK: %[[SV:.*]] = memref.subview %[[ALLOC]][0] [4] [1] : memref to memref<4xf32> + // CHECK: memref.copy %[[t]], %[[SV]] : memref<4xf32, strided{{.*}}> to memref<4xf32> %r0 = tensor.insert_slice %t into %A[0][4][1] : tensor<4xf32> into tensor // CHECK: return %{{.*}} : memref 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 18c28799a62e5..ae0824e7329b8 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 @@ -129,8 +129,8 @@ func.func @contiguous_inner_most_zero_idx_in_bounds(%src: memref<16x1xf32>, %i:i // CHECK-SAME: %[[MEM:.*]]: memref<16x1xf32>, // CHECK-SAME: %[[IDX:.*]]: index) -> vector<8x1xf32> { // CHECK: %[[PAD:.*]] = arith.constant 0.000000e+00 : f32 -// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32, strided<[1]>> -// CHECK: %[[READ:.*]] = vector.transfer_read %[[SV]]{{\[}}%[[IDX]]], %[[PAD]] {in_bounds = [true]} : memref<16xf32, strided<[1]>>, vector<8xf32> +// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32> +// CHECK: %[[READ:.*]] = vector.transfer_read %[[SV]]{{\[}}%[[IDX]]], %[[PAD]] {in_bounds = [true]} : memref<16xf32>, vector<8xf32> // CHECK: vector.shape_cast %[[READ]] : vector<8xf32> to vector<8x1xf32> // The index to be dropped is == 0, so it's safe to collapse. The "out of @@ -146,8 +146,8 @@ func.func @contiguous_inner_most_zero_idx_out_of_bounds(%src: memref<16x1xf32>, // CHECK-SAME: %[[MEM:.*]]: memref<16x1xf32>, // CHECK-SAME: %[[IDX:.*]]: index) -> vector<8x1xf32> { // CHECK: %[[PAD:.*]] = arith.constant 0.000000e+00 : f32 -// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32, strided<[1]>> -// CHECK: %[[READ:.*]] = vector.transfer_read %[[SV]]{{\[}}%[[IDX]]], %[[PAD]] {in_bounds = [true]} : memref<16xf32, strided<[1]>>, vector<8xf32> +// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32> +// CHECK: %[[READ:.*]] = vector.transfer_read %[[SV]]{{\[}}%[[IDX]]], %[[PAD]] {in_bounds = [true]} : memref<16xf32>, vector<8xf32> // CHECK: vector.shape_cast %[[READ]] : vector<8xf32> to vector<8x1xf32> // The index to be dropped is unknown, but since it's "in bounds", it has to be @@ -161,8 +161,8 @@ func.func @contiguous_inner_most_non_zero_idx_in_bounds(%src: memref<16x1xf32>, // CHECK-SAME: %[[MEM:.*]]: memref<16x1xf32>, // CHECK-SAME: %[[IDX:.*]]: index) -> vector<8x1xf32> { // CHECK: %[[PAD:.*]] = arith.constant 0.000000e+00 : f32 -// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32, strided<[1]>> -// CHECK: %[[READ:.*]] = vector.transfer_read %[[SV]]{{\[}}%[[IDX]]], %[[PAD]] {in_bounds = [true]} : memref<16xf32, strided<[1]>>, vector<8xf32> +// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32> +// CHECK: %[[READ:.*]] = vector.transfer_read %[[SV]]{{\[}}%[[IDX]]], %[[PAD]] {in_bounds = [true]} : memref<16xf32>, vector<8xf32> // CHECK: vector.shape_cast %[[READ]] : vector<8xf32> to vector<8x1xf32> // Same as the top example within this split, but with the outer vector @@ -178,8 +178,8 @@ func.func @contiguous_inner_most_non_zero_idx_in_bounds_scalable(%src: memref<16 // CHECK-SAME: %[[MEM:.*]]: memref<16x1xf32>, // CHECK-SAME: %[[IDX:.*]]: index) -> vector<[8]x1xf32> { // CHECK: %[[PAD:.*]] = arith.constant 0.000000e+00 : f32 -// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32, strided<[1]>> -// CHECK: %[[READ:.*]] = vector.transfer_read %[[SV]]{{\[}}%[[IDX]]], %[[PAD]] {in_bounds = [true]} : memref<16xf32, strided<[1]>>, vector<[8]xf32> +// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32> +// CHECK: %[[READ:.*]] = vector.transfer_read %[[SV]]{{\[}}%[[IDX]]], %[[PAD]] {in_bounds = [true]} : memref<16xf32>, vector<[8]xf32> // CHECK: vector.shape_cast %[[READ]] : vector<[8]xf32> to vector<[8]x1xf32> // The index to be dropped is unknown and "out of bounds" - not safe to @@ -437,9 +437,9 @@ func.func @contiguous_inner_most_zero_idx_in_bounds(%dest: memref<16x1xf32>, %v: // CHECK-SAME: %[[MEM:.*]]: memref<16x1xf32>, // CHECK-SAME: %[[VEC:.*]]: vector<8x1xf32>, // CHECK-SAME: %[[IDX:.*]]: index) { -// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32, strided<[1]>> +// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32> // CHECK: %[[SC:.*]] = vector.shape_cast %[[VEC]] : vector<8x1xf32> to vector<8xf32> -// CHECK: vector.transfer_write %[[SC]], %[[SV]]{{\[}}%[[IDX]]] {in_bounds = [true]} : vector<8xf32>, memref<16xf32, strided<[1]>> +// CHECK: vector.transfer_write %[[SC]], %[[SV]]{{\[}}%[[IDX]]] {in_bounds = [true]} : vector<8xf32>, memref<16xf32> // The index to be dropped is == 0, so it's safe to collapse. The "out of // bounds" attribute is too conservative and will be folded to "in bounds" @@ -453,9 +453,9 @@ func.func @contiguous_inner_most_zero_idx_out_of_bounds(%dest: memref<16x1xf32>, // CHECK-SAME: %[[MEM:.*]]: memref<16x1xf32>, // CHECK-SAME: %[[VEC:.*]]: vector<8x1xf32>, // CHECK-SAME: %[[IDX:.*]]: index) { -// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32, strided<[1]>> +// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32> // CHECK: %[[SC:.*]] = vector.shape_cast %[[VEC]] : vector<8x1xf32> to vector<8xf32> -// CHECK: vector.transfer_write %[[SC]], %[[SV]]{{\[}}%[[IDX]]] {in_bounds = [true]} : vector<8xf32>, memref<16xf32, strided<[1]>> +// CHECK: vector.transfer_write %[[SC]], %[[SV]]{{\[}}%[[IDX]]] {in_bounds = [true]} : vector<8xf32>, memref<16xf32> // The index to be dropped is unknown, but since it's "in bounds", it has to be // == 0. It's safe to collapse the corresponding dim. @@ -467,9 +467,9 @@ func.func @contiguous_inner_most_dim_non_zero_idx_in_bounds(%dest: memref<16x1xf // CHECK-SAME: %[[MEM:.*]]: memref<16x1xf32>, // CHECK-SAME: %[[VEC:.*]]: vector<8x1xf32>, // CHECK-SAME: %[[IDX:.*]]: index) { -// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32, strided<[1]>> +// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32> // CHECK: %[[SC:.*]] = vector.shape_cast %[[VEC]] : vector<8x1xf32> to vector<8xf32> -// CHECK: vector.transfer_write %[[SC]], %[[SV]]{{\[}}%[[IDX]]] {in_bounds = [true]} : vector<8xf32>, memref<16xf32, strided<[1]>> +// CHECK: vector.transfer_write %[[SC]], %[[SV]]{{\[}}%[[IDX]]] {in_bounds = [true]} : vector<8xf32>, memref<16xf32> // Same as the top example within this split, but with the outer vector // dim scalable. Note that this example only makes sense when "8 = [8]" (i.e. @@ -483,9 +483,9 @@ func.func @contiguous_inner_most_non_zero_idx_in_bounds_scalable(%dest: memref<1 // CHECK-SAME: %[[MEM:.*]]: memref<16x1xf32>, // CHECK-SAME: %[[VEC:.*]]: vector<[8]x1xf32> // CHECK-SAME: %[[IDX:.*]]: index) { -// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32, strided<[1]>> +// CHECK: %[[SV:.*]] = memref.subview %[[MEM]][0, 0] [16, 1] [1, 1] : memref<16x1xf32> to memref<16xf32> // CHECK: %[[SC:.*]] = vector.shape_cast %[[VEC]] : vector<[8]x1xf32> to vector<[8]xf32> -// CHECK: vector.transfer_write %[[SC]], %[[SV]]{{\[}}%[[IDX]]] {in_bounds = [true]} : vector<[8]xf32>, memref<16xf32, strided<[1]>> +// CHECK: vector.transfer_write %[[SC]], %[[SV]]{{\[}}%[[IDX]]] {in_bounds = [true]} : vector<[8]xf32>, memref<16xf32> // The index to be dropped is unknown and "out of bounds" - not safe to // collapse. diff --git a/mlir/test/IR/affine-map.mlir b/mlir/test/IR/affine-map.mlir index 86bdaafd79f32..a810a02207be0 100644 --- a/mlir/test/IR/affine-map.mlir +++ b/mlir/test/IR/affine-map.mlir @@ -4,7 +4,6 @@ #map0 = affine_map<(i, j) -> (i, j)> #map1 = affine_map<(i, j)[s0] -> (i, j)> -// CHECK: #map{{[0-9]*}} = affine_map<() -> (0)> // A map may have 0 inputs. // However, an affine.apply always takes at least one input. #map2 = affine_map<() -> (0)> @@ -236,7 +235,7 @@ func.func private @f0(memref<2x4xi8, #map0, 1>) // CHECK: @f1(memref<2x4xi8, 1>) func.func private @f1(memref<2x4xi8, #map1, 1>) -// CHECK: @f2(memref) +// CHECK: @f2(memref) func.func private @f2(memref) // CHECK: @f3(memref<2x4xi8, #map{{[0-9]*}}, 1>) diff --git a/mlir/test/lib/Dialect/Test/TestAttributes.cpp b/mlir/test/lib/Dialect/Test/TestAttributes.cpp index 178029d3c5d90..0469f4a098411 100644 --- a/mlir/test/lib/Dialect/Test/TestAttributes.cpp +++ b/mlir/test/lib/Dialect/Test/TestAttributes.cpp @@ -599,7 +599,8 @@ ::llvm::LogicalResult TestTensorEncodingAttr::verifyEncoding( //===----------------------------------------------------------------------===// mlir::AffineMap TestMemRefLayoutAttr::getAffineMap() const { - return mlir::AffineMap::getMultiDimIdentityMap(1, getContext()); + // Construct a non-identity AffineMap to prevent it from being folded. + return mlir::AffineMap::get(1, 0, {getAffineConstantExpr(0, getContext())}); } //===----------------------------------------------------------------------===//