Move linalg.slice to ODS
authorNicolas Vasilache <ntv@google.com>
Wed, 14 Aug 2019 13:02:40 +0000 (06:02 -0700)
committerA. Unique TensorFlower <gardener@tensorflow.org>
Wed, 14 Aug 2019 13:03:12 +0000 (06:03 -0700)
PiperOrigin-RevId: 263334168

mlir/include/mlir/Linalg/IR/LinalgBase.td
mlir/include/mlir/Linalg/IR/LinalgOps.h
mlir/include/mlir/Linalg/IR/LinalgOps.td
mlir/lib/Linalg/Analysis/DependenceAnalysis.cpp
mlir/lib/Linalg/IR/LinalgOps.cpp
mlir/lib/Linalg/IR/LinalgTypes.cpp
mlir/lib/Linalg/Transforms/LowerToLLVMDialect.cpp
mlir/test/Linalg/invalid.mlir [moved from mlir/test/Linalg/invalid-generic-op.mlir with 69% similarity]

index 4ea6651..ac6eeda 100644 (file)
@@ -44,4 +44,4 @@ def Range : Type<LinalgIsRangeTypePred, "range">;
 def LinalgIsViewTypePred : CPred<"$_self.isa<ViewType>()">;
 def View : Type<LinalgIsViewTypePred, "view">;
 
-#endif // LINALG_BASE
\ No newline at end of file
+#endif // LINALG_BASE
index 3187f4f..092fcd3 100644 (file)
@@ -23,6 +23,8 @@
 #include "mlir/IR/Function.h"
 #include "mlir/IR/Module.h"
 #include "mlir/IR/OpDefinition.h"
+#include "mlir/IR/StandardTypes.h"
+#include "mlir/IR/Types.h"
 #include "mlir/Linalg/IR/LinalgTraits.h"
 #include "mlir/Linalg/IR/LinalgTypes.h"
 #include "mlir/Support/LLVM.h"
@@ -31,6 +33,7 @@ namespace mlir {
 class OperationFolder;
 
 namespace linalg {
+class ViewOp;
 
 /// A linalg.LoadOp is the counterpart of load but operating on ViewType
 /// instead of MemRefType.
@@ -85,78 +88,6 @@ public:
   Value *step() { return getOperand(2); }
 };
 
-/// The "linalg.slice" op produces a linalg.view which is a subview of a given
-/// base view. This allows defining a subregion within the underlying buffer to
-/// operate on only a subset of the buffer.
-///
-/// A "linalg.slice" op takes a base view and a variadic number of indexings and
-/// produces a linalg.view of the same elemental type as the buffer. An indexing
-/// is either:
-///   1. a linalg.range, in which case it does not reduce the rank of the parent
-///      view.
-///   2. an index, in which case it reduces the rank of the parent view by one.
-///
-/// The parent view must be a base view (i.e. either a function argument or has
-/// been produced by a linalg.view op). In other words, chains of
-/// linalg.slice operations cannot be constructed in the IR. This defines away
-/// problems related to keeping track of which dimensions of the base view have
-/// been rank-reduced.
-///
-/// Examples:
-///   1. rank-preserving slice:
-///
-/// ```{.mlir}
-///    %4 = linalg.slice %0[%1, %2] : !linalg.view<?x?xf32>, !linalg.range,
-///    !linalg.range, !linalg.view<?x?xf32>
-/// ```
-///
-///   2. rank-reducing slice (from 2-D to 1-D):
-///
-/// ```{.mlir}
-///    %4 = linalg.slice %0[%1, %2] : !linalg.view<?x?xf32>, index,
-///    !linalg.range, !linalg.view<?xf32>
-/// ```
-///
-///   3. rank-reducing slice (from 2-D to 0-D):
-///
-/// ```{.mlir}
-///    %4 = linalg.slice %0[%1, %2] : !linalg.view<?x?xf32>, index, index,
-///    !linalg.view<f32>
-/// ```
-class ViewOp;
-class SliceOp : public Op<SliceOp, OpTrait::VariadicOperands,
-                          OpTrait::OneResult, OpTrait::HasNoSideEffect> {
-  enum { FirstIndexingOperand = 1 };
-
-public:
-  using Op::Op;
-
-  // Hooks to customize the behavior of this op.
-  static llvm::StringRef getOperationName() { return "linalg.slice"; }
-  static void build(Builder *b, OperationState *result, Value *base,
-                    llvm::ArrayRef<Value *> indexings);
-  LogicalResult verify();
-  static ParseResult parse(OpAsmParser *parser, OperationState *result);
-  void print(OpAsmPrinter *p);
-
-  // Op-specific functionality.
-  unsigned getRank() { return getViewType().getRank(); }
-  Type getElementType() { return getViewType().getElementType(); }
-  ViewType getViewType() { return getType().cast<ViewType>(); }
-  Value *getBaseView() { return getOperand(0); }
-  ViewOp getBaseViewOp();
-  ViewType getBaseViewType();
-  unsigned getBaseViewRank() { return getBaseViewType().getRank(); }
-  // Get the underlying indexing at a given rank.
-  Value *getIndexing(unsigned rank) { return *(getIndexings().begin() + rank); }
-  // Get all the indexings in this view.
-  Operation::operand_range getIndexings() {
-    return {operand_begin() + SliceOp::FirstIndexingOperand, operand_end()};
-  }
-  // Get the subset of indexings that are of RangeType.
-  SmallVector<Value *, 8> getRanges();
-};
-
 /// A linalg.StoreOp is the counterpart of affine.store but operating on
 /// ViewType instead of MemRefType.
 ///
index f7a07fc..a8e93a4 100644 (file)
@@ -150,6 +150,71 @@ def DimOp : Linalg_Op<"dim", [NoSideEffect]>,
   let hasCanonicalizer = 1;
 }
 
+def SliceOp : Linalg_Op<"slice", [NoSideEffect]>,
+    Arguments<(ins View:$view, Variadic<AnyTypeOf<[Range, Index]>>:$indexings)>,
+    Results<(outs View)> {
+  let summary = "Produce a linalg.view which is a subview of a base view.";
+  let description = [{
+    The "linalg.slice" op produces a linalg.view which is a subview of a given
+    base view. This allows defining a subregion within the underlying buffer to
+    operate on only a subset of the buffer.
+
+    A "linalg.slice" op takes a base view and a variadic number of indexings and
+    produces a linalg.view of the same elemental type as the buffer. An indexing
+    is either:
+      1. a linalg.range, in which case it does not reduce the rank of the parent
+         view.
+      2. an index, in which case it reduces the rank of the parent view by one.
+
+    The parent view must be a base view (i.e. either a function argument or has
+    been produced by a linalg.view op). In other words, chains of
+    linalg.slice operations cannot be constructed in the IR. This defines away
+    problems related to keeping track of which dimensions of the base view have
+    been rank-reduced.
+
+    Examples:
+      1. rank-preserving slice:
+
+       %4 = linalg.slice %0[%1, %2] : !linalg.view<?x?xf32>, !linalg.range,
+              !linalg.range, !linalg.view<?x?xf32>
+
+      2. rank-reducing slice (from 2-D to 1-D):
+
+       %4 = linalg.slice %0[%1, %2] : !linalg.view<?x?xf32>, index,
+              !linalg.range, !linalg.view<?xf32>
+
+      3. rank-reducing slice (from 2-D to 0-D):
+
+       %4 = linalg.slice %0[%1, %2] : !linalg.view<?x?xf32>, index, index,
+              !linalg.view<f32>
+  }];
+
+  let builders = [OpBuilder<
+    "Builder *b, OperationState *result, Value *base, "
+    "ArrayRef<Value *> indexings">];
+
+  let extraClassDeclaration = [{
+    enum { FirstIndexingOperand = 1 };
+    unsigned getRank() { return getViewType().getRank(); }
+    Type getElementType() { return getViewType().getElementType(); }
+    ViewType getViewType() { return getType().cast<ViewType>(); }
+    unsigned getBaseViewRank() { return getBaseViewType().getRank(); }
+    ViewType getBaseViewType() { return view()->getType().cast<ViewType>(); }
+
+    // Get the underlying indexing at a given rank.
+    Value *indexing(unsigned rank) { return *(indexings().begin() + rank); }
+
+    // Get the subset of indexings that are of RangeType.
+    SmallVector<Value *, 8> getRanges() {
+      llvm::SmallVector<Value *, 8> res;
+      for (auto *operand : indexings())
+        if (!operand->getType().isa<IndexType>())
+          res.push_back(operand);
+      return res;
+    }
+  }];
+}
+
 def SubViewOp : Linalg_Op<"subview", [NoSideEffect]>,
     Arguments<(ins View:$view, Variadic<Index>:$ranges)>,
     Results<(outs View)> {
index 5a272a4..a9ed86e 100644 (file)
@@ -49,7 +49,7 @@ Value *Aliases::find(Value *v) {
     if (isa<BlockArgument>(v))
       return v;
     if (auto slice = dyn_cast_or_null<SliceOp>(v->getDefiningOp())) {
-      auto it = aliases.insert(std::make_pair(v, find(slice.getBaseView())));
+      auto it = aliases.insert(std::make_pair(v, find(slice.view())));
       return it.first->second;
     }
     if (auto view = dyn_cast_or_null<ViewOp>(v->getDefiningOp())) {
index bce2b32..ca9bb96 100644 (file)
@@ -224,129 +224,6 @@ ParseResult mlir::linalg::RangeOp::parse(OpAsmParser *parser,
       parser->addTypeToList(type, result->types));
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// SliceOp
-//////////////////////////////////////////////////////////////////////////////
-void mlir::linalg::SliceOp::build(Builder *b, OperationState *result,
-                                  Value *base, ArrayRef<Value *> indexings) {
-  result->addOperands({base});
-  result->addOperands(indexings);
-
-  ViewType viewType = base->getType().cast<ViewType>();
-  unsigned rank = viewType.getRank();
-  for (auto *i : indexings)
-    if (!i->getType().isa<RangeType>())
-      rank--;
-  Type elementType = viewType.getElementType();
-  result->addTypes({ViewType::get(b->getContext(), elementType, rank)});
-}
-
-LogicalResult mlir::linalg::SliceOp::verify() {
-  if (llvm::empty(getOperands()))
-    return emitOpError(
-        "requires at least a view operand followed by 'rank' indices");
-  unsigned rank = getBaseViewRank();
-  if (llvm::size(getIndexings()) != rank) {
-    return emitOpError("requires at least a view operand followed by ")
-           << rank << " indexings";
-  }
-  unsigned index = 0;
-  for (auto indexing : getIndexings()) {
-    if (!indexing->getType().isa<RangeType>() &&
-        !indexing->getType().isa<IndexType>()) {
-      return emitOpError() << index
-                           << "^th index must be of range or index type";
-    }
-    if (indexing->getType().isa<IndexType>())
-      --rank;
-    ++index;
-  }
-  if (getRank() != rank) {
-    return emitOpError()
-           << "the rank of the view must be the number of its range indices ("
-           << rank << ") but got: " << getRank();
-  }
-  return success();
-}
-
-ParseResult mlir::linalg::SliceOp::parse(OpAsmParser *parser,
-                                         OperationState *result) {
-  OpAsmParser::OperandType baseInfo;
-  SmallVector<OpAsmParser::OperandType, 8> indexingsInfo;
-  SmallVector<Type, 8> types;
-  if (parser->parseOperand(baseInfo) ||
-      parser->parseOperandList(indexingsInfo, OpAsmParser::Delimiter::Square) ||
-      parser->parseOptionalAttributeDict(result->attributes) ||
-      parser->parseColonTypeList(types))
-    return failure();
-
-  if (types.size() != 2 + indexingsInfo.size())
-    return parser->emitError(parser->getNameLoc(),
-                             "unexpected number of types ");
-  ViewType baseViewType = types[0].dyn_cast<ViewType>();
-  if (!baseViewType)
-    return parser->emitError(parser->getNameLoc(),
-                             "view type expected for first type");
-  if (indexingsInfo.size() != baseViewType.getRank())
-    return parser->emitError(parser->getNameLoc(), "expected ")
-           << baseViewType.getRank() << " indexings";
-  ViewType viewType = types.back().dyn_cast<ViewType>();
-  if (!viewType)
-    return parser->emitError(parser->getNameLoc(), "view type expected");
-
-  ArrayRef<Type> indexingTypes =
-      ArrayRef<Type>(types).drop_front(1).drop_back(1);
-  if (indexingTypes.size() != baseViewType.getRank())
-    return parser->emitError(parser->getNameLoc(), "expected ")
-           << baseViewType.getRank() << " indexing types";
-  return failure(
-      parser->resolveOperand(baseInfo, baseViewType, result->operands) ||
-      (!indexingsInfo.empty() &&
-       parser->resolveOperands(indexingsInfo, indexingTypes,
-                               indexingsInfo.front().location,
-                               result->operands)) ||
-      parser->addTypeToList(viewType, result->types));
-}
-
-// A SliceOp prints as:
-//
-// ```{.mlir}
-//   linalg.slice %0[%1, %2] :
-//     !linalg.view<?x?xf32>, [indexing-types], !linalg.view<?x?xf32>
-// ```
-//
-// Where %0 is an ssa-value holding a view created from a buffer, %1 and %2 are
-// ssa-value each holding a range.
-void mlir::linalg::SliceOp::print(OpAsmPrinter *p) {
-  *p << getOperationName() << " " << *getBaseView() << "[";
-  interleave(
-      getIndexings().begin(), getIndexings().end(), [p](Value *v) { *p << *v; },
-      [p]() { *p << ", "; });
-  *p << "] : " << getBaseViewType();
-  for (auto indexing : getIndexings()) {
-    *p << ", " << indexing->getType();
-  }
-  *p << ", " << getType();
-}
-
-ViewOp mlir::linalg::SliceOp::getBaseViewOp() {
-  return cast<ViewOp>(getOperand(0)->getDefiningOp());
-}
-
-ViewType mlir::linalg::SliceOp::getBaseViewType() {
-  return getOperand(0)->getType().cast<ViewType>();
-}
-
-SmallVector<Value *, 8> mlir::linalg::SliceOp::getRanges() {
-  llvm::SmallVector<Value *, 8> res;
-  for (auto *operand : getIndexings()) {
-    if (!operand->getType().isa<IndexType>()) {
-      res.push_back(operand);
-    }
-  }
-  return res;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // StoreOp.
 ////////////////////////////////////////////////////////////////////////////////
@@ -675,6 +552,83 @@ static LogicalResult verify(GenericOp op) {
 }
 
 //===----------------------------------------------------------------------===//
+// SliceOp
+//===----------------------------------------------------------------------===//
+
+void mlir::linalg::SliceOp::build(Builder *b, OperationState *result,
+                                  Value *base, ArrayRef<Value *> indexings) {
+  result->addOperands(base);
+  result->addOperands(indexings);
+
+  ViewType viewType = base->getType().cast<ViewType>();
+  unsigned rank = viewType.getRank();
+  for (auto *i : indexings)
+    if (!i->getType().isa<RangeType>())
+      rank--;
+  Type elementType = viewType.getElementType();
+  result->addTypes({ViewType::get(b->getContext(), elementType, rank)});
+}
+
+// A SliceOp prints as:
+//
+// ```{.mlir}
+//   linalg.slice %0[%1, %2] :
+//     !linalg.view<?x?xf32>, [indexing-types], !linalg.view<?x?xf32>
+// ```
+//
+// Where %0 is an ssa-value holding a view created from a buffer, %1 and %2 are
+// ssa-value each holding a range.
+static void print(OpAsmPrinter *p, SliceOp op) {
+  *p << SliceOp::getOperationName() << " " << *op.view() << "[";
+  p->printOperands(op.indexings());
+  *p << "] : " << op.getBaseViewType();
+  for (auto indexing : op.indexings()) {
+    *p << ", " << indexing->getType();
+  }
+  *p << ", " << op.getType();
+}
+
+static ParseResult parseSliceOp(OpAsmParser *parser, OperationState *result) {
+  OpAsmParser::OperandType baseInfo;
+  SmallVector<OpAsmParser::OperandType, 8> operands;
+  SmallVector<Type, 8> types;
+  if (parser->parseOperand(baseInfo) ||
+      parser->parseOperandList(operands, OpAsmParser::Delimiter::Square) ||
+      parser->parseOptionalAttributeDict(result->attributes) ||
+      parser->parseColonTypeList(types))
+    return failure();
+
+  if (types.size() < 2)
+    return parser->emitError(parser->getCurrentLocation(),
+                             "expected at least input and result view types");
+
+  ArrayRef<Type> indexingTypes = ArrayRef<Type>(types).drop_front().drop_back();
+  return failure(
+      parser->resolveOperand(baseInfo, types.front(), result->operands) ||
+      (!operands.empty() &&
+       parser->resolveOperands(operands, indexingTypes,
+                               operands.front().location, result->operands)) ||
+      parser->addTypeToList(types.back(), result->types));
+}
+
+static LogicalResult verify(SliceOp op) {
+  unsigned rank = op.getBaseViewRank();
+  if (llvm::size(op.indexings()) != rank)
+    return op.emitOpError("expected number of indexings to match view rank");
+  unsigned index = 0;
+  for (auto indexing : op.indexings()) {
+    if (indexing->getType().isa<IndexType>())
+      --rank;
+    ++index;
+  }
+  if (op.getRank() != rank)
+    return op.emitOpError()
+           << "expected rank of the view(" << op.getRank()
+           << ") to be the number of its range indices(" << rank << ")";
+  return success();
+}
+
+//===----------------------------------------------------------------------===//
 // ViewOp
 //===----------------------------------------------------------------------===//
 void mlir::linalg::ViewOp::build(Builder *b, OperationState *result,
index ca54c33..5abd35a 100644 (file)
@@ -35,7 +35,7 @@ using namespace mlir::linalg;
 mlir::linalg::LinalgDialect::LinalgDialect(MLIRContext *context)
     : Dialect(getDialectNamespace(), context) {
   addTypes<BufferType, RangeType, ViewType>();
-  addOperations<LoadOp, RangeOp, StoreOp, SliceOp>();
+  addOperations<LoadOp, RangeOp, StoreOp>();
   addOperations<
 #define GET_OP_LIST
 #include "mlir/Linalg/IR/LinalgOps.cpp.inc"
index 5663929..ac71c32 100644 (file)
@@ -421,7 +421,7 @@ public:
     for (int j = 0, e = viewType.getRank(); j < e; ++j) {
       Value *indexing = operands[1 + j];
       Value *min =
-          sliceOp.getIndexing(j)->getType().isa<RangeType>()
+          sliceOp.indexing(j)->getType().isa<RangeType>()
               ? static_cast<Value *>(extractvalue(int64Ty, indexing, pos(0)))
               : indexing;
       Value *product = mul(min, strides[j]);
@@ -432,7 +432,7 @@ public:
     // Compute and insert view sizes (max - min along the range).  Skip the
     // non-range operands as they will be projected away from the view.
     int i = 0, j = 0;
-    for (Value *index : sliceOp.getIndexings()) {
+    for (Value *index : sliceOp.indexings()) {
       if (!index->getType().isa<RangeType>()) {
         ++j;
         continue;
@@ -452,7 +452,7 @@ public:
     // to non-range operands as they are projected away from the view.
     i = 0;
     for (int j = 0, e = strides.size(); j < e; ++j) {
-      if (!sliceOp.getIndexing(j)->getType().isa<RangeType>())
+      if (!sliceOp.indexing(j)->getType().isa<RangeType>())
         continue;
       Value *step = extractvalue(int64Ty, operands[1 + j], pos(2));
       Value *stride = mul(strides[j], step);
similarity index 69%
rename from mlir/test/Linalg/invalid-generic-op.mlir
rename to mlir/test/Linalg/invalid.mlir
index e513209..6b5b0d4 100644 (file)
@@ -6,8 +6,28 @@
 
 // -----
 
-// CHECK-LABEL: at_least_2_operands
-func @at_least_2_operands(%arg0: !linalg.view<f32>) {
+// CHECK-LABEL: slice_number_of_indexings
+func @slice_number_of_indexings(%arg0: !linalg.view<?x?xf32>) {
+  // expected-error @+2 {{expected number of indexings to match view rank}}
+  %c0 = constant 0: index
+  %0 = linalg.slice %arg0[%c0] : !linalg.view<?x?xf32>, index, !linalg.view<?x?xf32>
+  return
+}
+
+// -----
+
+// CHECK-LABEL: slice_rank_vs_range_indices
+func @slice_rank_vs_range_indices(%arg0: !linalg.view<?x?xf32>) {
+  // expected-error @+2 {{expected rank of the view(1) to be the number of its range indices(0)}}
+  %c0 = constant 0: index
+  %0 = linalg.slice %arg0[%c0, %c0] : !linalg.view<?x?xf32>, index, index, !linalg.view<?xf32>
+  return
+}
+
+// -----
+
+// CHECK-LABEL: generic_at_least_2_operands
+func @generic_at_least_2_operands(%arg0: !linalg.view<f32>) {
   // expected-error @+1 {{op expected 2 or more operands}}
   linalg.generic {
     fun = @foo,
@@ -20,8 +40,8 @@ func @at_least_2_operands(%arg0: !linalg.view<f32>) {
 
 // -----
 
-// CHECK-LABEL: exactly_2_views
-func @exactly_2_views(%arg0: !linalg.view<f32>) {
+// CHECK-LABEL: generic_exactly_2_views
+func @generic_exactly_2_views(%arg0: !linalg.view<f32>) {
   // expected-error @+1 {{op expected exactly 2 view operands}}
   linalg.generic {
     fun = @foo,
@@ -34,8 +54,8 @@ func @exactly_2_views(%arg0: !linalg.view<f32>) {
 
 // -----
 
-// CHECK-LABEL: undefined_fun
-func @undefined_fun(%arg0: !linalg.view<f32>) {
+// CHECK-LABEL: generic_undefined_fun
+func @generic_undefined_fun(%arg0: !linalg.view<f32>) {
   // expected-error @+1 {{op expected fun attribute to refer to a defined symbol}}
   linalg.generic {
     fun = @foo,
@@ -50,8 +70,8 @@ func @undefined_fun(%arg0: !linalg.view<f32>) {
 
 func @foo() { return }
 
-// CHECK-LABEL: mismatched_num_arguments
-func @mismatched_num_arguments(%arg0: !linalg.view<f32>) {
+// CHECK-LABEL: generic_mismatched_num_arguments
+func @generic_mismatched_num_arguments(%arg0: !linalg.view<f32>) {
   // expected-error @+1 {{op expected fun arguments to match number of views}}
   linalg.generic {
     fun = @foo,
@@ -66,8 +86,8 @@ func @mismatched_num_arguments(%arg0: !linalg.view<f32>) {
 
 func @foo(%0: i32) { return }
 
-// CHECK-LABEL: mismatched_num_returns
-func @mismatched_num_returns(%arg0: !linalg.view<f32>) {
+// CHECK-LABEL: generic_mismatched_num_returns
+func @generic_mismatched_num_returns(%arg0: !linalg.view<f32>) {
   // expected-error @+1 {{op expected fun results to match number of output views}}
   linalg.generic {
     fun = @foo,
@@ -82,8 +102,8 @@ func @mismatched_num_returns(%arg0: !linalg.view<f32>) {
 
 func @foo(%0: i32) -> i32 { return %0: i32 }
 
-// CHECK-LABEL: symbol_in_map
-func @symbol_in_map(%arg0: !linalg.view<f32>) {
+// CHECK-LABEL: generic_symbol_in_map
+func @generic_symbol_in_map(%arg0: !linalg.view<f32>) {
   // expected-error @+1 {{op expected indexing_map #0 to have no symbols}}
   linalg.generic {
     fun = @foo,
@@ -98,8 +118,8 @@ func @symbol_in_map(%arg0: !linalg.view<f32>) {
 
 func @foo(%0: i32) -> i32 { return %0: i32 }
 
-// CHECK-LABEL: wrong_dim_in_map
-func @wrong_dim_in_map(%arg0: !linalg.view<f32>) {
+// CHECK-LABEL: generic_wrong_dim_in_map
+func @generic_wrong_dim_in_map(%arg0: !linalg.view<f32>) {
   // expected-error @+1 {{op expected indexing_map #0 to have 1 dim(s) to match the number of loops}}
   linalg.generic {
     fun = @foo,
@@ -114,8 +134,8 @@ func @wrong_dim_in_map(%arg0: !linalg.view<f32>) {
 
 func @foo(%0: i32) -> i32 { return %0: i32 }
 
-// CHECK-LABEL: zero_d_view
-func @zero_d_view(%arg0: !linalg.view<f32>) {
+// CHECK-LABEL: generic_zero_d_view
+func @generic_zero_d_view(%arg0: !linalg.view<f32>) {
   // expected-error @+1 {{op expected indexing_map #0 to be 0 to match 0-D view: '!linalg.view<f32>'}}
   linalg.generic {
     fun = @foo,
@@ -130,8 +150,8 @@ func @zero_d_view(%arg0: !linalg.view<f32>) {
 
 func @foo(%0: f32) -> f32 { return %0: f32 }
 
-// CHECK-LABEL: one_d_view
-func @one_d_view(%arg0: !linalg.view<?xf32>) {
+// CHECK-LABEL: generic_one_d_view
+func @generic_one_d_view(%arg0: !linalg.view<?xf32>) {
   // expected-error @+1 {{op expected indexing_map #0 results to match view rank: '!linalg.view<?xf32>'}}
   linalg.generic {
     fun = @foo,
@@ -149,8 +169,8 @@ func @foo(%0: i32) -> f32 {
   return %1: f32
 }
 
-// CHECK-LABEL: fun_arg_0_element_type
-func @fun_arg_0_element_type(%arg0: !linalg.view<?xf32>) {
+// CHECK-LABEL: generic_fun_arg_0_element_type
+func @generic_fun_arg_0_element_type(%arg0: !linalg.view<?xf32>) {
   // expected-error @+1 {{op expected fun argument 0 to match view element type: 'f32'}}
   linalg.generic {
     fun = @foo,
@@ -168,8 +188,8 @@ func @foo(%0: f32) -> i4 {
   return %1: i4
 }
 
-// CHECK-LABEL: fun_result_0_element_type
-func @fun_result_0_element_type(%arg0: !linalg.view<?xf32>) {
+// CHECK-LABEL: generic_fun_result_0_element_type
+func @generic_fun_result_0_element_type(%arg0: !linalg.view<?xf32>) {
   // expected-error @+1 {{op expected fun result 0 to match output view element type: 'f32'}}
   linalg.generic {
     fun = @foo,
@@ -184,8 +204,8 @@ func @fun_result_0_element_type(%arg0: !linalg.view<?xf32>) {
 
 func @foo(%0: f32, %1: f32) -> f32 { return %1: f32 }
 
-// CHECK-LABEL: singular_maps
-func @singular_maps(%arg0: !linalg.view<?xf32>, %arg1: !linalg.view<?xf32>) {
+// CHECK-LABEL: generic_singular_maps
+func @generic_singular_maps(%arg0: !linalg.view<?xf32>, %arg1: !linalg.view<?xf32>) {
   // expected-error @+1 {{op expected the concatenation of maps in indexing_map to be invertible}}
   linalg.generic {
     fun = @foo,
@@ -205,8 +225,8 @@ func @singular_maps(%arg0: !linalg.view<?xf32>, %arg1: !linalg.view<?xf32>) {
 
 // -----
 
-// CHECK-LABEL: empty_region
-func @empty_region(%arg0: !linalg.view<f32>) {
+// CHECK-LABEL: generic_empty_region
+func @generic_empty_region(%arg0: !linalg.view<f32>) {
   // expected-error @+1 {{op expected region with 1 block}}
   linalg.generic {
     indexing_maps =  [ () -> (0) ],
@@ -221,8 +241,8 @@ func @empty_region(%arg0: !linalg.view<f32>) {
 
 // -----
 
-// CHECK-LABEL: mismatched_num_arguments
-func @mismatched_num_arguments(%arg0: !linalg.view<f32>) {
+// CHECK-LABEL: generic_mismatched_num_arguments
+func @generic_mismatched_num_arguments(%arg0: !linalg.view<f32>) {
   // expected-error @+1 {{op expected number of block arguments to match number of views}}
   linalg.generic {
     indexing_maps =  [ () -> (0) ],
@@ -236,8 +256,8 @@ func @mismatched_num_arguments(%arg0: !linalg.view<f32>) {
 
 // -----
 
-// CHECK-LABEL: block_arg_type
-func @block_arg_type(%arg0: !linalg.view<f32>) {
+// CHECK-LABEL: generic_block_arg_type
+func @generic_block_arg_type(%arg0: !linalg.view<f32>) {
   // expected-error @+1 {{op expected block argument 0 of the same type as elemental type of output view: '!linalg.view<f32>'}}
   linalg.generic {
     indexing_maps =  [ () -> (0) ],
@@ -251,8 +271,8 @@ func @block_arg_type(%arg0: !linalg.view<f32>) {
 
 // -----
 
-// CHECK-LABEL: fun_result_0_element_type
-func @fun_result_0_element_type(%arg0: !linalg.view<?xf32>) {
+// CHECK-LABEL: generic_fun_result_0_element_type
+func @generic_fun_result_0_element_type(%arg0: !linalg.view<?xf32>) {
   // expected-error @+8 {{type of return operand 0 ('i1') doesn't match view element type ('f32')}}
   linalg.generic {
     indexing_maps =  [ (i) -> (i) ],
@@ -268,8 +288,8 @@ func @fun_result_0_element_type(%arg0: !linalg.view<?xf32>) {
 
 // -----
 
-// CHECK-LABEL: wrong_yield_parent
-func @fun_result_0_element_type(%arg0: !linalg.view<?xf32>) {
+// CHECK-LABEL: generic_wrong_yield_parent
+func @generic_fun_result_0_element_type(%arg0: !linalg.view<?xf32>) {
   // expected-error @+1 {{op expected 'linalg.generic' parent op}}
   linalg.yield %arg0: !linalg.view<?xf32>
 }