diff --git a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp --- a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp +++ b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp @@ -1215,6 +1215,14 @@ SmallVector newShape; operandsAndShape(resultType, dynamicExtents, newOperands, newShape); + for (int64_t newdim : newShape) { + // This check also occurs in the verifier, but we need it here too + // since intermediate passes may have some replaced dynamic dimensions + // by constants. + if (newdim < 0 && !ShapedType::isDynamic(newdim)) + return failure(); + } + if (newOperands.size() == tensorFromElements.getDynamicExtents().size()) return failure(); @@ -2126,7 +2134,8 @@ } OpFoldResult ExtractSliceOp::fold(FoldAdaptor adaptor) { - if (auto splat = llvm::dyn_cast_if_present(adaptor.getSource())) { + if (auto splat = + llvm::dyn_cast_if_present(adaptor.getSource())) { auto resultType = llvm::cast(getResult().getType()); if (resultType.hasStaticShape()) return splat.resizeSplat(resultType); diff --git a/mlir/test/Dialect/Tensor/invalid-canonicalize.mlir b/mlir/test/Dialect/Tensor/invalid-canonicalize.mlir new file mode 100644 --- /dev/null +++ b/mlir/test/Dialect/Tensor/invalid-canonicalize.mlir @@ -0,0 +1,15 @@ +// RUN: mlir-opt <%s -split-input-file -verify-diagnostics -canonicalize + +// ----- + +func.func @indirectly_generate_negative_size() -> tensor { + %cst = arith.constant 0 : i32 + %c0 = arith.constant 0 : index + %size = affine.max affine_map<(d0) -> (d0 mod 64 - 8)>(%c0) + // expected-error@+1 {{tensor dimensions must be non-negative}} + %tensor = tensor.generate %size { + ^bb0(%arg0: index, %arg1: index): + tensor.yield %cst : i32 + } : tensor + return %tensor : tensor +}