Merge google -> main (#3488)

* 84467e66 Merge pull request #3486 from ScottTodd:main-to-google
* 66bddbfd Merge branch 'google' into main-to-google
* 6d2473bd Synchronize submodules
* a8a8242c Integrate TF at tensorflow/tensorflow@069b9b2f1079
* dabd7364 Synchronize submodules
* 3510a109 Integrate LLVM at llvm/llvm-project@50df5f24dc33
* 227e12d4 Synchronize submodules
* 14c5540c Integrate LLVM at llvm/llvm-project@196bee9648a9
* ddbead4d Synchronize submodules
* 340a030b Integrate LLVM at llvm/llvm-project@220de1f32add
* 7f12e791 Add support for building TFHub intree.
* 535f63eb Synchronize submodules
* e001092b Integrate LLVM at llvm/llvm-project@89657b3a3b57
diff --git a/SUBMODULE_VERSIONS b/SUBMODULE_VERSIONS
index 48180ae..e3aa377 100644
--- a/SUBMODULE_VERSIONS
+++ b/SUBMODULE_VERSIONS
@@ -5,7 +5,7 @@
 a5d9d0f7d368054fd1691aedf1db4116efcc233e third_party/flatbuffers
 4fb0ff7069bd88ee85902f4d0bb62794e5f6d021 third_party/flatcc
 f2fb48c3b3d79a75a88a99fba6576b25d42ec528 third_party/googletest
-9b3c2a72e4cb3b0ae27f87064c11f728452b2af9 third_party/llvm-project
+50df5f24dc333e912f6eb8500ef84e648d43af93 third_party/llvm-project
 17b12a4481daa150e2d1ea3ada086b551b856707 third_party/marl
 d2cdb70e038370b5e28f353fe98ccd70af1cbc25 third_party/mlir-emitc
 d8c7ee00a687ac369e62e2032514a93a9b413502 third_party/pybind11
@@ -14,7 +14,7 @@
 685f86471e9d26b3eb7676695a2e2cefb4551ae9 third_party/spirv_cross
 f8bf11a0253a32375c32cad92c841237b96696c0 third_party/spirv_headers
 57eb48aed36160c4876bc8310d9ca84d42ee9e2a third_party/swiftshader
-090b691fbf7b7823c41345004d12eddaa6c86118 third_party/tensorflow
+069b9b2f1079a545e4c6312dbbe2e3b55e9d3586 third_party/tensorflow
 a9a09ab0940408898fccfdcfe2bb8dc19b50f13c third_party/tracy
 9bd3f561bcee3f01d22912de10bb07ce4e23d378 third_party/vulkan_headers
 909f36b714c9239ee0b112a321220213a474ba53 third_party/vulkan_memory_allocator
diff --git a/bindings/python/build_defs.oss.bzl b/bindings/python/build_defs.oss.bzl
index 7ad76b5..e6a21d8 100644
--- a/bindings/python/build_defs.oss.bzl
+++ b/bindings/python/build_defs.oss.bzl
@@ -40,6 +40,10 @@
 # defaults to getting TensorFlow from the python environment (empty).
 INTREE_TENSORFLOW_PY_DEPS = []
 
+# Optional deps to enable intree TensorFlow Hub. This build configuration
+# defaults to getting TensorFlow from the python environment (empty).
+INTREE_TF_HUB_DEPS = []
+
 def pybind_cc_library(
         name,
         copts = [],
diff --git a/integrations/tensorflow/e2e/slim_vision_models/BUILD b/integrations/tensorflow/e2e/slim_vision_models/BUILD
index 077bf90..bbfe6a7 100644
--- a/integrations/tensorflow/e2e/slim_vision_models/BUILD
+++ b/integrations/tensorflow/e2e/slim_vision_models/BUILD
@@ -21,6 +21,7 @@
 load(
     "//bindings/python:build_defs.oss.bzl",
     "INTREE_TENSORFLOW_PY_DEPS",
+    "INTREE_TF_HUB_DEPS",
     "NUMPY_DEPS",
     "iree_py_binary",
 )
@@ -42,7 +43,7 @@
     args = ["--tf_hub_url=https://tfhub.dev/google/imagenet/"],
     main = "slim_vision_model_test.py",
     python_version = "PY3",
-    deps = INTREE_TENSORFLOW_PY_DEPS + NUMPY_DEPS + [
+    deps = INTREE_TENSORFLOW_PY_DEPS + INTREE_TF_HUB_DEPS + NUMPY_DEPS + [
         "//integrations/tensorflow/bindings/python/pyiree/tf/support",
     ],
 )
diff --git a/iree/compiler/Conversion/HLOToLinalg/FusionOfTensorOps.cpp b/iree/compiler/Conversion/HLOToLinalg/FusionOfTensorOps.cpp
index ebf96aa..8350d11 100644
--- a/iree/compiler/Conversion/HLOToLinalg/FusionOfTensorOps.cpp
+++ b/iree/compiler/Conversion/HLOToLinalg/FusionOfTensorOps.cpp
@@ -71,13 +71,17 @@
   }
 
   void runOnOperation() override {
-    OwningRewritePatternList patterns;
+    OwningRewritePatternList fusionPatterns, interfacePatterns;
     Operation *op = getOperation();
     MLIRContext *context = op->getContext();
-    populateLinalgTensorOpsFusionPatterns(context, patterns);
-    patterns.insert<FuseWithHALInterfaceLoadTensor,
-                    FuseWithHALInterfaceStoreTensor>(context);
-    applyPatternsAndFoldGreedily(op->getRegions(), patterns);
+    interfacePatterns.insert<FuseWithHALInterfaceLoadTensor,
+                             FuseWithHALInterfaceStoreTensor>(context);
+    applyPatternsAndFoldGreedily(op->getRegions(), interfacePatterns);
+
+    populateLinalgTensorOpsFusionPatterns(context, fusionPatterns);
+    applyPatternsAndFoldGreedily(op->getRegions(), fusionPatterns);
+
+    applyPatternsAndFoldGreedily(op->getRegions(), interfacePatterns);
   }
 };
 }  // namespace
diff --git a/iree/compiler/Conversion/LinalgToLLVM/ConvImg2ColMatmulConversion.cpp b/iree/compiler/Conversion/LinalgToLLVM/ConvImg2ColMatmulConversion.cpp
index c20fc34..3601d99 100644
--- a/iree/compiler/Conversion/LinalgToLLVM/ConvImg2ColMatmulConversion.cpp
+++ b/iree/compiler/Conversion/LinalgToLLVM/ConvImg2ColMatmulConversion.cpp
@@ -23,7 +23,7 @@
 namespace {
 
 // clang-format off
-// 
+//
 // Convert linalg.conv op into img2col packing operation (linalg.generic) +
 // linalg.matmul. See details below:
 // A convolution operaton can be written as a matrix-matrix multiplication by
@@ -39,13 +39,13 @@
 // The packed input data (img2col) is a matrix with |rows| = output spatial
 // size, |columns| = filter spatial size. To compute the output Y(i, j) we need
 // to calculate the dot product between filter window at input X(x, y)) and the
-// filter which will look like the following where r.h.s is the img2col matrix and 
+// filter which will look like the following where r.h.s is the img2col matrix and
 // l.h.s is the flattned filter:
-// [x(0, 0), x(0, 1), x(1, 0), x(1, 1)] 
-// [x(0, 1), x(1, 1), x(0, 2), x(1, 2)] (matmul) [w(0, 0), w(0, 1), w(1, 0), w(1, 1)] 
+// [x(0, 0), x(0, 1), x(1, 0), x(1, 1)]
+// [x(0, 1), x(1, 1), x(0, 2), x(1, 2)] (matmul) [w(0, 0), w(0, 1), w(1, 0), w(1, 1)]
 // [x(0, 1), x(1, 1), x(0, 2), x(1, 2)]
 // [   .   ,    .   ,    .   ,    .   ]
-// In general for 2D case with (N, H, W, C) input and (Kh, Kw, C, D) filter 
+// In general for 2D case with (N, H, W, C) input and (Kh, Kw, C, D) filter
 // and output (N, Ho, Wo, D) the convolutin is the following matrix-matrix multiplication
 // (Ho x Wo, Kh x Kw x C) * (Kh x Kw x C, D) for each input in the N input.
 // For the case where N > 1 its a batched matrxi-matrix multplication.
@@ -70,7 +70,8 @@
     auto loc = op.getLoc();
 
     auto inputFeatures =
-        filterShapeType.getShape()[filterShapeType.getRank() - 1];
+        inputShapeType.getShape()[op.getNumBatchDimensions() +
+                                  op.getNumSpatialDimensions()];
     auto outputFeatures = filterShapeType.getShape().back();
 
     // Col buffer shape (n, d1, d1, d2, ...dn, k1, k2, k3, ...kn, ci)
@@ -129,26 +130,31 @@
         });
 
     auto getIndicesVector = [](int start, int end) {
-      SmallVector<int64_t, 2> indices;
-      for (int i = start; i <= end; ++i) {
-        indices.push_back(i);
-      }
-      return indices;
+      return llvm::to_vector<2>(llvm::seq<int64_t>(start, end));
     };
 
-    // n, d1, d2,....dn
-    auto batchAndSpatialIndices =
-        getIndicesVector(0, op.getNumSpatialDimensions());
-    auto featureIndices = getIndicesVector(op.getNumSpatialDimensions() + 1,
-                                           op.getNumSpatialDimensions() + 3);
-
     SmallVector<linalg::ReassociationIndices, 4> lhsCollapsedDimsList = {
-        batchAndSpatialIndices, featureIndices};
+        getIndicesVector(
+            0, op.getNumBatchDimensions() + op.getNumSpatialDimensions()),
+        getIndicesVector(
+            op.getNumBatchDimensions() + op.getNumSpatialDimensions(),
+            op.getNumBatchDimensions() + op.getNumSpatialDimensions() * 2 +
+                op.getNumInputFeatureDimensions())};
     SmallVector<linalg::ReassociationIndices, 4> rhsCollapsedDimsList = {
-        batchAndSpatialIndices, {op.getNumSpatialDimensions() + 1}};
+        getIndicesVector(0, op.getNumSpatialDimensions() +
+                                op.getNumInputFeatureDimensions()),
+        getIndicesVector(
+            op.getNumSpatialDimensions() + op.getNumInputFeatureDimensions(),
+            op.getNumSpatialDimensions() + op.getNumInputFeatureDimensions() +
+                op.getNumOutputFeatureDimensions())};
 
     SmallVector<linalg::ReassociationIndices, 4> resultCollapsedDimsList = {
-        batchAndSpatialIndices, {op.getNumSpatialDimensions() + 1}};
+        getIndicesVector(
+            0, op.getNumBatchDimensions() + op.getNumSpatialDimensions()),
+        getIndicesVector(
+            op.getNumBatchDimensions() + op.getNumSpatialDimensions(),
+            op.getNumBatchDimensions() + op.getNumSpatialDimensions() +
+                op.getNumOutputFeatureDimensions())};
 
     auto reshapedColBufferType =
         MemRefType::get({spatialSize, filterSpatialSize * inputFeatures},
diff --git a/iree/compiler/Dialect/Vulkan/Utils/TargetEnvUtils.cpp b/iree/compiler/Dialect/Vulkan/Utils/TargetEnvUtils.cpp
index c3681ee..0091778 100644
--- a/iree/compiler/Dialect/Vulkan/Utils/TargetEnvUtils.cpp
+++ b/iree/compiler/Dialect/Vulkan/Utils/TargetEnvUtils.cpp
@@ -154,7 +154,7 @@
       vkCapabilities.maxComputeSharedMemorySize(),
       vkCapabilities.maxComputeWorkGroupInvocations(),
       vkCapabilities.maxComputeWorkGroupSize(), vkCapabilities.subgroupSize(),
-      context);
+      nullptr, context);
 }
 }  // anonymous namespace
 
diff --git a/third_party/llvm-project b/third_party/llvm-project
index 9b3c2a7..50df5f2 160000
--- a/third_party/llvm-project
+++ b/third_party/llvm-project
@@ -1 +1 @@
-Subproject commit 9b3c2a72e4cb3b0ae27f87064c11f728452b2af9
+Subproject commit 50df5f24dc333e912f6eb8500ef84e648d43af93
diff --git a/third_party/tensorflow b/third_party/tensorflow
index 090b691..069b9b2 160000
--- a/third_party/tensorflow
+++ b/third_party/tensorflow
@@ -1 +1 @@
-Subproject commit 090b691fbf7b7823c41345004d12eddaa6c86118
+Subproject commit 069b9b2f1079a545e4c6312dbbe2e3b55e9d3586