diff --git a/mlir/include/mlir/Dialect/Vector/VectorOps.td b/mlir/include/mlir/Dialect/Vector/VectorOps.td --- a/mlir/include/mlir/Dialect/Vector/VectorOps.td +++ b/mlir/include/mlir/Dialect/Vector/VectorOps.td @@ -1055,7 +1055,8 @@ def Vector_TransferReadOp : Vector_Op<"transfer_read", [ DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods + DeclareOpInterfaceMethods, + DeclareOpInterfaceMethods ]>, Arguments<(ins AnyShaped:$source, Variadic:$indices, AffineMapAttr:$permutation_map, AnyType:$padding, @@ -1224,7 +1225,8 @@ def Vector_TransferWriteOp : Vector_Op<"transfer_write", [ DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods + DeclareOpInterfaceMethods, + DeclareOpInterfaceMethods ]>, Arguments<(ins AnyVector:$vector, AnyShaped:$source, Variadic:$indices, diff --git a/mlir/lib/Dialect/Vector/VectorOps.cpp b/mlir/lib/Dialect/Vector/VectorOps.cpp --- a/mlir/lib/Dialect/Vector/VectorOps.cpp +++ b/mlir/lib/Dialect/Vector/VectorOps.cpp @@ -2227,6 +2227,14 @@ return SmallVector{s.begin(), s.end()}; } +void TransferReadOp::getEffects( + SmallVectorImpl> + &effects) { + if (getShapedType().isa()) + effects.emplace_back(MemoryEffects::Read::get(), source(), + SideEffects::DefaultResource::get()); +} + //===----------------------------------------------------------------------===// // TransferWriteOp //===----------------------------------------------------------------------===// @@ -2341,6 +2349,14 @@ return llvm::to_vector<4>(getVectorType().getShape()); } +void TransferWriteOp::getEffects( + SmallVectorImpl> + &effects) { + if (getShapedType().isa()) + effects.emplace_back(MemoryEffects::Write::get(), source(), + SideEffects::DefaultResource::get()); +} + //===----------------------------------------------------------------------===// // MaskedLoadOp //===----------------------------------------------------------------------===// diff --git a/mlir/test/Conversion/VectorToSCF/vector-to-loops.mlir b/mlir/test/Conversion/VectorToSCF/vector-to-loops.mlir --- a/mlir/test/Conversion/VectorToSCF/vector-to-loops.mlir +++ b/mlir/test/Conversion/VectorToSCF/vector-to-loops.mlir @@ -1,5 +1,5 @@ -// RUN: mlir-opt %s -convert-vector-to-scf -split-input-file | FileCheck %s -// RUN: mlir-opt %s -convert-vector-to-scf=full-unroll=true -split-input-file | FileCheck %s --check-prefix=FULL-UNROLL +// RUN: mlir-opt %s -convert-vector-to-scf -split-input-file -allow-unregistered-dialect | FileCheck %s +// RUN: mlir-opt %s -convert-vector-to-scf=full-unroll=true -split-input-file -allow-unregistered-dialect | FileCheck %s --check-prefix=FULL-UNROLL // CHECK-LABEL: func @materialize_read_1d() { func @materialize_read_1d() { @@ -22,6 +22,9 @@ // CHECK-NEXT: else // CHECK-NEXT: vector.insertelement // CHECK-NEXT: store + // Add a dummy use to prevent dead code elimination from removing transfer + // read ops. + "dummy_use"(%f1, %f2, %f3, %f4) : (vector<4xf32>, vector<4xf32>, vector<4xf32>, vector<4xf32>) -> () } } return @@ -41,6 +44,9 @@ %f1 = vector.transfer_read %A[%i0, %i1, %i2, %i3, %i4], %f0 {permutation_map = affine_map<(d0, d1, d2, d3, d4) -> (d3)>} : memref<7x?x?x42x?xf32>, vector<4xf32> %i3p1 = affine.apply affine_map<(d0) -> (d0 + 1)> (%i3) %f2 = vector.transfer_read %A[%i0, %i1, %i2, %i3p1, %i4], %f0 {permutation_map = affine_map<(d0, d1, d2, d3, d4) -> (d3)>} : memref<7x?x?x42x?xf32>, vector<4xf32> + // Add a dummy use to prevent dead code elimination from removing + // transfer read ops. + "dummy_use"(%f1, %f2) : (vector<4xf32>, vector<4xf32>) -> () } } } @@ -88,6 +94,9 @@ // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: } + // CHECK-NEXT: %[[ALLOC_CAST:.*]] = vector.type_cast %[[ALLOC]] : memref<5x4xvector<3xf32>> to memref> + // CHECK-NEXT: %[[LD:.*]] = load %[[ALLOC_CAST]][] : memref> + // CHECK-NEXT: "dummy_use"(%[[LD]]) : (vector<5x4x3xf32>) -> () // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: } @@ -104,6 +113,9 @@ affine.for %i2 = 0 to %O { affine.for %i3 = 0 to %P step 5 { %f = vector.transfer_read %A[%i0, %i1, %i2, %i3], %f0 {permutation_map = affine_map<(d0, d1, d2, d3) -> (d3, 0, d0)>} : memref, vector<5x4x3xf32> + // Add a dummy use to prevent dead code elimination from removing + // transfer read ops. + "dummy_use"(%f) : (vector<5x4x3xf32>) -> () } } } diff --git a/mlir/test/Dialect/Vector/canonicalize.mlir b/mlir/test/Dialect/Vector/canonicalize.mlir --- a/mlir/test/Dialect/Vector/canonicalize.mlir +++ b/mlir/test/Dialect/Vector/canonicalize.mlir @@ -661,3 +661,19 @@ return %0 : vector<1x4x4xf16> } +// ----- + +// CHECK-LABEL: func @dead_transfer_op +// CHECK-NOT: vector.transfer_read +// CHECK-NOT: vector.transfer_write +// CHECK: return +func @dead_transfer_op(%arg0 : tensor<4x4xf32>, %arg1 : memref<4x4xf32>, + %v0 : vector<1x4xf32>) { + %c0 = constant 0 : index + %cf0 = constant 0.0 : f32 + %r = vector.transfer_read %arg1[%c0, %c0], %cf0 : + memref<4x4xf32>, vector<1x4xf32> + %w = vector.transfer_write %v0, %arg0[%c0, %c0] : + vector<1x4xf32>, tensor<4x4xf32> + return +}