[mlir][tosa] Added div op, variadic concat. Removed placeholder. Spec v0.22 alignment.

Nearly complete alignment to spec v0.22
- Adds Div op
- Concat inputs now variadic
- Removes Placeholder op

Note: TF side PR https://github.com/tensorflow/tensorflow/pull/48921 deletes Concat legalizations to avoid breaking TensorFlow CI. This must be merged only after the TF PR has merged.

Reviewed By: rsuderman

Differential Revision: https://reviews.llvm.org/D101958
diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
index 43138f1..1a9198d 100644
--- a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
+++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
@@ -493,6 +493,28 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Operator: div
+//===----------------------------------------------------------------------===//
+def Tosa_DivOp : Tosa_Op<"div", [ResultsBroadcastableShape,
+                                 NoSideEffect]> {
+  let summary = "Integer divide operator";
+
+  let description = [{
+    Elementwise integer divide operator of input1 by input2. Axis of size 1
+    will be broadcast, as necessary. Rank of input tensors must match.
+  }];
+
+  let arguments = (ins
+    Tosa_Int32TensorUpto4D:$input1,
+    Tosa_Int32TensorUpto4D:$input2
+  );
+
+  let results = (outs
+    Tosa_Int32TensorUpto4D:$output
+  );
+}
+
+//===----------------------------------------------------------------------===//
 // Operator: logical_and
 //===----------------------------------------------------------------------===//
 def Tosa_LogicalAndOp : Tosa_Op<"logical_and", [ResultsBroadcastableShape,
@@ -1206,13 +1228,12 @@
   let summary = "Concatenates tensors along one dimension.";
 
   let description = [{
-    Concatenate two tensors along a given axis. No data conversion happens
-    during a concat operation.
+    Concatenate a variadic amount of tensors along a given axis. No data 
+    conversion happens during a concat operation.
   }];
 
   let arguments = (ins
-    Tosa_Tensor1Dto4D:$input1,
-    Tosa_Tensor1Dto4D:$input2,
+    Variadic<Tosa_Tensor1Dto4D>:$input1,
     I64Attr:$axis
   );
 
@@ -1586,26 +1607,6 @@
   );
 }
 
-
-//===----------------------------------------------------------------------===//
-// Operator: placeholder
-//===----------------------------------------------------------------------===//
-def Tosa_PlaceholderOp : Tosa_Op<"placeholder", [NoSideEffect]> {
-  let summary = "Placeholder op";
-
-  let description = [{
-    A node where data will be inserted into the network at runtime. Generally
-    used for inputs to the network.
-  }];
-
-  let arguments = (ins
-  );
-
-  let results = (outs
-    Tosa_Tensor1Dto4D:$output
-  );
-}
-
 //===----------------------------------------------------------------------===//
 // TOSA Spec Section 2.14
 // Operator Class: Custom Operators.
diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaTypesBase.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaTypesBase.td
index b65201e..35572de 100644
--- a/mlir/include/mlir/Dialect/Tosa/IR/TosaTypesBase.td
+++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaTypesBase.td
@@ -126,6 +126,8 @@
 def Tosa_TensorUpto4D : TensorRankOf<[Tosa_AnyNumber], [0,1,2,3,4]>;
 def Tosa_TensorUpto6D : TensorRankOf<[Tosa_AnyNumber], [0,1,2,3,4,5,6]>;
 
+def Tosa_Int32TensorUpto4D : TensorRankOf<[Tosa_Int32], [0,1,2,3,4]>;
+
 //===----------------------------------------------------------------------===//
 // Generic scalar, vector, or tensor of a particular type.
 //===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/Tosa/ops.mlir b/mlir/test/Dialect/Tosa/ops.mlir
index 2ff3971..3a23f37 100644
--- a/mlir/test/Dialect/Tosa/ops.mlir
+++ b/mlir/test/Dialect/Tosa/ops.mlir
@@ -101,7 +101,6 @@
   return %0 : tensor<13x21x3xf32>
 }
 
-
 // -----
 // CHECK-LABEL: bitwise_and
 func @test_bitwise_and(%arg0: tensor<13x21x3xi32>, %arg1: tensor<13x21x1xi32>) -> tensor<13x21x3xi32> {
@@ -124,6 +123,13 @@
 }
 
 // -----
+// CHECK-LABEL: div
+func @test_div(%arg0: tensor<13x21x1xi32>, %arg1: tensor<13x21x3xi32>) -> tensor<13x21x3xi32> {
+  %0 = "tosa.div"(%arg0, %arg1) : (tensor<13x21x1xi32>, tensor<13x21x3xi32>) -> tensor<13x21x3xi32>
+  return %0 : tensor<13x21x3xi32>
+}
+
+// -----
 // CHECK-LABEL: logical_and
 func @test_logical_and(%arg0: tensor<13x21x3xi1>, %arg1: tensor<13x21x1xi1>) -> tensor<13x21x3xi1> {
   %0 = "tosa.logical_and"(%arg0, %arg1) : (tensor<13x21x3xi1>, tensor<13x21x1xi1>) -> tensor<13x21x3xi1>
@@ -475,13 +481,6 @@
 }
 
 // -----
-// CHECK-LABEL: placeholder
-func @test_placeholder() -> tensor<1xi32> {
-  %0 = "tosa.placeholder"() : () -> tensor<1xi32>
-  return %0 : tensor<1xi32>
-}
-
-// -----
 // CHECK-LABEL: cond_if
 func @test_cond_if(%arg0: tensor<f32>, %arg1: tensor<f32>, %arg2: tensor<i1>) -> tensor<f32> {
   %0 = "tosa.cond_if"(%arg2, %arg0, %arg1) ( {