Repository: llvm/llvm-project
File: mlir/lib/Dialect/Tosa/Transforms/TosaValidation.cpp (C++)

Code before:
  if (!matchPattern(pad.getPadding(), m_Constant(&paddingAttr)))
    // Pad verifier will catch this
    return success();

  for (const APInt &val : paddingAttr.getValues<APInt>()) {
    if (val.getSExtValue() < 0)
      return op->emitOpError() << "padding value must all be non-negative, got "
                               << val.getSExtValue();
  }

  return success();
}

LogicalResult checkErrorIfReshape(Operation *op) {
  auto reshapeOp = dyn_cast<tosa::ReshapeOp>(op);
  if (!reshapeOp)
    return success();

  constexpr int64_t kInferableDim = -1;
  SmallVector<int64_t> shapeValues;
  if (!tosa::getConstShapeValues(reshapeOp.getShape().getDefiningOp(),
                                 shapeValues))
    return success();

  if (llvm::is_contained(shapeValues, kInferableDim))
    return op->emitOpError("shape input contains inferable dimension (-1) "
                           "which does not conform to the TOSA specification");

  return success();
}

LogicalResult checkErrorIfSlice(Operation *op) {
  auto sliceOp = dyn_cast<tosa::SliceOp>(op);
  if (!sliceOp)
    return success();

  constexpr int64_t kInferableDim = -1;
  SmallVector<int64_t> startValues;
  SmallVector<int64_t> sizeValues;
  const bool hasStartValues = tosa::getConstShapeValues(
      sliceOp.getStart().getDefiningOp(), startValues);
  const bool hasSizeValues =
      tosa::getConstShapeValues(sliceOp.getSize().getDefiningOp(), sizeValues);

  if (hasStartValues && llvm::is_contained(startValues, kInferableDim))
    return op->emitOpError("start input contains inferable dimension (-1) "
                           "which does not conform to the TOSA specification");
  if (hasSizeValues && llvm::is_contained(sizeValues, kInferableDim))
    return op->emitOpError("size input contains inferable dimension (-1) which "
                           "does not conform to the TOSA specification");


Review comment (bug):
Is this a recent change in tosa spec? I think tosa.reshape used to handle at least one dynamic dimension which is represented with `-1`. I think this will break some existing model support for us.

Code after:
  if (!matchPattern(pad.getPadding(), m_Constant(&paddingAttr)))
    // Pad verifier will catch this
    return success();

  for (const APInt &val : paddingAttr.getValues<APInt>()) {
    if (val.getSExtValue() < 0)
      return op->emitOpError() << "padding value must all be non-negative, got "
                               << val.getSExtValue();
  }

  return success();
}

LogicalResult checkErrorIfReshape(Operation *op) {
  auto reshapeOp = dyn_cast<tosa::ReshapeOp>(op);
  if (!reshapeOp)
    return success();

  SmallVector<int64_t> shapeValues;
  if (!tosa::getConstShapeValues(reshapeOp.getShape().getDefiningOp(),
                                 shapeValues))
    return success();

  if (llvm::is_contained(shapeValues, kInferableDimSize))
    return op->emitOpError("shape input contains inferable dimension (")
           << kInferableDimSize
           << ") "
              "which does not conform to the TOSA specification";

  return success();
}

LogicalResult checkErrorIfSlice(Operation *op) {
  auto sliceOp = dyn_cast<tosa::SliceOp>(op);
  if (!sliceOp)
    return success();

  SmallVector<int64_t> startValues;
  SmallVector<int64_t> sizeValues;
  const bool hasStartValues = tosa::getConstShapeValues(
      sliceOp.getStart().getDefiningOp(), startValues);
  const bool hasSizeValues =
      tosa::getConstShapeValues(sliceOp.getSize().getDefiningOp(), sizeValues);

  if (hasStartValues && llvm::is_contained(startValues, kInferableDimSize))
    return op->emitOpError("start input contains inferable dimension (")
           << kInferableDimSize
           << ") which does not conform to the TOSA specification";
  if (hasSizeValues && llvm::is_contained(sizeValues, kInferableDimSize))
    return op->emitOpError("size input contains inferable dimension (")
           << kInferableDimSize